Setting up a Common Lisp environment
See the relevant section of my dotfiles for the configuration files.
1. SBCL
2. Quicklisp
Quicklisp is a library manager for Common Lisp.
Download the install script.
wget https://beta.quicklisp.org/quicklisp.lisp
Load it.
sbcl --load quicklisp.lisp
Install Quicklisp. I prefer to install it in
~/.quicklisp.(quicklisp-quickstart:install :path ".quicklisp/")
Notify SBCL about Quicklisp. Add this to your
.sbclrcfile:#-quicklisp (let ((quicklisp-init (merge-pathnames ".quicklisp/setup.lisp" (user-homedir-pathname)))) (when (probe-file quicklisp-init) (load quicklisp-init)))
2.1. Optional
Run sbcl again to check everything is right by trying to download a
package.
(ql:quickload "vecto")
Output:
To load "vecto":
Load 1 ASDF system:
asdf
Install 5 Quicklisp releases:
cl-vectors salza2 vecto zpb-ttf zpng
; Fetching #<URL "http://beta.quicklisp.org/archive/salza2/2013-07-20/salza2-2.0.9.tgz">
; 15.16KB
==================================================
15,525 bytes in 0.02 seconds (631.71KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/zpng/2015-04-07/zpng-1.2.2.tgz">
; 39.20KB
==================================================
40,141 bytes in 0.08 seconds (490.00KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/zpb-ttf/2013-07-20/zpb-ttf-1.0.3.tgz">
; 43.82KB
==================================================
44,869 bytes in 0.08 seconds (554.65KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/cl-vectors/2018-02-28/cl-vectors-20180228-git.tgz">
; 30.68KB
==================================================
31,415 bytes in 0.04 seconds (697.24KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/vecto/2017-12-27/vecto-1.5.tgz">
; 69.10KB
==================================================
70,758 bytes in 0.11 seconds (628.18KB/sec)
; Loading "vecto"
[package net.tuxee.aa]............................
[package net.tuxee.aa-bin]........................
[package net.tuxee.paths].........................
[package net.tuxee.vectors].......................
[package salza2]..................................
[package zpng]....................................
[package zpb-ttf].................................
[package vecto]........
("vecto")
3. ASDF
Another System Definition Facility. The following instructions are documented here, as of .
Create the following directory:
~/.config/common-lisp/source-registry.conf.d/Create a
.conffile - I usemy-asdf.conf. In this file, add a line like this one:(:tree "/home/alc/src/")
You should find this file here.
Since I keep my programming projects in
/home/alc/src/, this will tell ASDF to recursively scan this directory looking for.asdfiles. Of course choose your own dir :)I wouldn't keep the
.quicklispdirectory in there. I didn't test it, but that might have a few funky effects.
3.1. Optional
Let's test things out by cloning a Lisp project managed with ASDF. I will use one of my projects for this test:
git clone https://github.com/alecigne/freecomm src/freecomm sbcl
Then:
(ql:quickload :freecomm)
At this step the project dependencies should be downloaded:
* (ql:quickload "freecomm")
To load "freecomm":
Load 1 ASDF system:
freecomm
; Loading "freecomm"
..................................................
[package iterate].................................
[package cl-unicode]..............................
[package cl-unicode-names]........................
[package editor-hints.named-readtables]...........
[package editor-hints.named-readtables]...........
[package cl-interpol].............................
[package cl-csv]..................................
[package freecomm].
("freecomm")
(in-package :freecomm)
You should enter the freecomm package:
* (in-package :freecomm) #<PACKAGE "FREECOMM">
4. SLIME
SLIME is the Superior Lisp Interaction Mode for Emacs.
- Install it.
Using
use-package(use-package slime :config (when (eq system-type 'gnu/linux) (setq slime-contribs '(slime-fancy) slime-protocol-version 'ignore) (setq inferior-lisp-program "sbcl")))Using the package manager directly
Run
M-x package-install RET slime RET. Don't forget to set your default Lisp by evaluating this expression:(setq inferior-lisp-program "sbcl")
- Launch it with
M-x slimeand start exploring.
5. Creating a Lisp project
Quickproject is pretty neat for creating a Common Lisp project from scratch.
Create a project.
(ql:quickload :quickproject) (quickproject:make-project #p"~/src/my-quickproject-test/")
Load the project:
(ql:quickload :my-quickproject-test)
We will now create a small Common Lisp project that will be useful in the next section.
In
my-quickproject-test.lisp, add thismainfunction:(defun main (argv) (declare (ignore argv)) (write-line "Hello, world"))
That's it!
6. Compilation
Buildapp is pretty cool.
Install it.
(ql:quickload :buildapp)
Build
buildappitself.(buildapp:build-buildapp)
The binary will be created in the current directory.
We'll now build
my-quickproject-test:) Change thebuildappdirectory to match yours; I use~/bin/buildapp.~/bin/buildapp --output my-quickproject-test \ --load-system my-quickproject-test \ --entry my-quickproject-test:mainRun the program:
./my-quickproject-test. You should see:❯ ./my-quickproject-test Hello, world
7. StumpWM
Clone the StumpWM repository:
git clone https://github.com/stumpwm/stumpwm
Install the dependencies:
(ql:quickload '("clx" "cl-ppcre" "alexandria" "swank"))Compile it:
./autogen.sh ./configure make
I prefer to link to the executable:
ln -s ~/src/stumpwm/stumpwm ~/bin/stumpwm
Create
~/.xinitrcand add this line (point to your own executable or link):exec /home/alc/bin/stumpwm
- Run
startx: it should work!
7.1. Optional
You can connect to the Lisp process that StumpWM uses from SLIME.
Add this to your StumpWM
init.lisp:(in-package :stumpwm) (require :swank) (swank-loader:init) (defcommand swank () () (setf *top-level-error-action* :break) (swank:create-server :port 4005 :style swank:*communication-style* :dont-close t)) (swank)If you encounter an error when running StumpWM with
startx, try settingSBCL_HOME. See this comment.Add this config to Emacs:
(defun yourname-swank-listening-p () (ignore-errors (let ((p (open-network-stream "SLIME Lisp Connection Test" nil "localhost" 4005))) (when p (delete-process p) t)))) (defun yourname-swank-autoconnect (&rest args) (if (and (not (slime-connected-p)) (yourname-swank-listening-p)) (ignore-errors (slime-connect "localhost" 4005)))) (yourname-swank-autoconnect))When you launch Emacs, if SLIME isn't already running and if a Swank connection is available, SLIME will connect to it. Then in the REPL, you can do this:
(in-package :stumpwm) (message "hello world")
The message should appear on the screen.

