A modern, pure-Lua Common Lisp development environment for Neovim, built on the Swank protocol.
Status: Early development. Not ready for daily use yet.
| Plugin | Status | Notes |
|---|---|---|
| vlime | Active | Vimscript, clunky UI |
| nvlime | Archived | Maintainer quit Lisp |
| conjure | Active | Multi-lang, eval-only for CL |
swank.nvim is a ground-up Lua rewrite targeting full SLIME feature parity, built with modern Neovim APIs throughout.
- Pure Lua — no Vimscript, no Python, no Fennel
- Neovim 0.10+ only
vim.uvasync TCP transport — no blockingvim.ui.input/vim.ui.selecteverywhere → snacks.nvim works automaticallyvim.diagnosticfor compiler notes- blink.cmp as a first-class completion source
- Self-contained — no helper plugin dependency
- REPL with floating output buffer
- Eval: top-level form, region, interactive
- Completion via
swank:completions/swank:fuzzy-completions— native blink.cmp and nvim-cmp sources with lazydescribe-symboldocumentation - Arglist autodoc (
CursorHoldI→ echo area) - SLDB debugger — floating window, restart/frame/eval-in-frame
- Object inspector — navigable parts, back/reinspect
- Cross-reference (xref) → picker or quickfix / direct jump for single result
- Compiler notes →
vim.diagnostic - Trace dialog (SWANK-TRACE-DIALOG)
- which-key integration
- Autostart: spawn a CL implementation + Quicklisp when
require("swank").attach()is called (typically from aFileTypeautocmd)
Neovim 0.10+ required. 0.13+ recommended (used for development and testing).
The default configuration automatically launches your CL implementation and
connects to Swank when you open a .lisp file. You don't need to write any
startup scripts or start a server manually.
All you need is:
- A Common Lisp implementation installed (e.g.
sbcl) - Quicklisp installed in the default location (
~/quicklisp/)
Install SBCL:
# Debian/Ubuntu
sudo apt install sbcl
# Arch
sudo pacman -S sbcl
# macOS
brew install sbclInstall Quicklisp (one-time setup, any implementation):
curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp \
--eval '(quicklisp-quickstart:install)' \
--eval '(ql:add-to-init-file)' \
--quitThat's it. Open a .lisp file in Neovim and swank.nvim handles the rest.
No Quicklisp? SBCL bundles Swank via ASDF. swank.nvim will automatically fall back to
(require :swank)if Quicklisp is not found.
| Implementation | Support | Notes |
|---|---|---|
| SBCL | ✅ Primary | Recommended. Best Swank support. |
| CCL (Clozure CL) | ✅ Should work | Swank is well-supported |
| ECL | Swank works; some features limited | |
| ABCL | Runs on JVM; Swank can be quirky | |
| CLISP | ❌ Not recommended | Swank support is minimal |
| Allegro CL | 🔲 Untested | Swank support exists in theory |
To use a different implementation, set autostart.implementation in your config:
require("swank").setup({
autostart = { implementation = "ccl" }, -- or "ecl", "abcl", "/usr/local/bin/sbcl", etc.
})ASDF is bundled with SBCL, CCL, and most modern implementations. No separate
install needed. Required for the swank-asdf contrib (project-aware compilation).
If you want to manage the Swank server yourself (remote machines, custom setups,
autostart.enabled = false), start it from your CL image:
(ql:quickload "swank" :silent t)
(swank:create-server :port 4005 :dont-close t)Then connect from Neovim with <Leader>lc.
lazy.nvim:
{
"corigne/swank.nvim",
ft = { "lisp", "commonlisp" },
opts = {
-- leader prefix for all swank keybindings (default: "<Leader>")
leader = "<Leader>",
server = {
host = "127.0.0.1",
port = 4005,
},
autostart = {
enabled = true, -- spawn SBCL automatically on first attach
implementation = "sbcl", -- path or name of the Lisp binary
},
ui = {
repl = {
-- "auto"|"right"|"left"|"top"|"bottom"|"float"
-- "auto" tries vertical split first (if REPL would get ≥80 cols),
-- then horizontal split, then float as a last resort
position = "auto",
size = 0.45, -- fraction (0–1) or fixed columns/rows
},
},
},
-- Wire up M.attach() so keymaps and autostart fire on FileType
config = function(_, opts)
require("swank").setup(opts)
end,
}Then add an autocmd to attach on Lisp buffers (or put this inside your config function):
vim.api.nvim_create_autocmd("FileType", {
pattern = { "lisp", "commonlisp" },
callback = function(args)
require("swank").attach(args.buf)
end,
})Requires: Neovim 0.10+. See Prerequisites above.
swank.nvim ships native sources for blink.cmp and nvim-cmp. Both support
lazy documentation previews via swank:describe-symbol when you dwell on
a completion item.
See Completions wiki page for full setup instructions, source module paths, and engine-specific options.
All <Leader> bindings are buffer-local and prefixed with the configured leader (default <Leader>).
| Key | Mode | Action |
|---|---|---|
<Leader>lc |
n | Connect to Swank server |
<Leader>rr |
n | Start configured CL implementation and connect |
<Leader>ld |
n | Disconnect |
<Leader>lp |
n | Set current package |
<Leader>ee |
n | Eval top-level form |
<Leader>ee |
v | Eval region |
<Leader>ei |
n | Eval (prompt) |
<Leader>rw |
n | Toggle REPL window |
<Leader>id |
n/v | Describe symbol (floating popup) |
<Leader>ia |
n/v | Apropos (prompt / selection) |
<Leader>iA |
n | Apropos symbol at cursor |
<Leader>ii |
n | Inspect value at cursor |
<Leader>xd |
n | Find definition |
<Leader>xc |
n | Who calls symbol |
<Leader>xr |
n | Who references symbol |
<Leader>fl |
n | Load file |
<Leader>fc |
n | Compile file |
<Leader>fs |
n | Compile form at cursor |
<Leader>tt |
n | Open trace dialog |
<Leader>td |
n | Toggle trace on symbol |
<Leader>tD |
n | Untrace all |
<Leader>tc / <Leader>tg |
n | Clear / refresh trace entries |
These standard Neovim keymaps are set as buffer-local overrides for Lisp buffers, so the familiar muscle memory works without a Language Server:
| Key | Action |
|---|---|
gd |
Go to definition (Swank xref) |
K |
Describe / hover (floating popup) |
gr |
Find references → picker or quickfix |
gR |
Find callers → picker or quickfix |
<C-k> |
Arglist / signature help (normal + insert) |
See :help swank.nvim after installation.
See CONTRIBUTING.md for coverage requirements (80% floor, 100% goal) and test instructions.
- SLIME — the original Swank protocol and the Emacs CL environment this is modelled after
- Swank — the server-side protocol implementation from the SLIME project, typically installed via SLIME/Quicklisp/ASDF or system packages
- vlime and nvlime — prior Neovim/Vim Swank clients that proved the concept
- Conjure — inspiration for a clean Neovim-native Lisp workflow
- plenary.nvim — test harness (busted runner) used throughout the test suite
- blink.cmp — completion framework with a clean source API
MIT