Skip to content

corigne/swank.nvim

Repository files navigation

swank.nvim

CI Coverage

A modern, pure-Lua Common Lisp development environment for Neovim, built on the Swank protocol.

Status: Early development. Not ready for daily use yet.


Why another CL plugin?

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.

Goals

  • Pure Lua — no Vimscript, no Python, no Fennel
  • Neovim 0.10+ only
  • vim.uv async TCP transport — no blocking
  • vim.ui.input / vim.ui.select everywhere → snacks.nvim works automatically
  • vim.diagnostic for compiler notes
  • blink.cmp as a first-class completion source
  • Self-contained — no helper plugin dependency

Features

  • 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 lazy describe-symbol documentation
  • 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 a FileType autocmd)

Prerequisites

Neovim

Neovim 0.10+ required. 0.13+ recommended (used for development and testing).

Quick start (autostart — recommended)

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:

  1. A Common Lisp implementation installed (e.g. sbcl)
  2. Quicklisp installed in the default location (~/quicklisp/)

Install SBCL:

# Debian/Ubuntu
sudo apt install sbcl

# Arch
sudo pacman -S sbcl

# macOS
brew install sbcl

Install 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)' \
     --quit

That'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.

CL implementation support

Implementation Support Notes
SBCL ✅ Primary Recommended. Best Swank support.
CCL (Clozure CL) ✅ Should work Swank is well-supported
ECL ⚠️ Partial Swank works; some features limited
ABCL ⚠️ Partial 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

ASDF is bundled with SBCL, CCL, and most modern implementations. No separate install needed. Required for the swank-asdf contrib (project-aware compilation).

Advanced: connecting to an existing server

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.


Installation

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.

Completions

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.

Default keybindings

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

LSP-compatible keymaps

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)

Documentation

See :help swank.nvim after installation.

Contributing

See CONTRIBUTING.md for coverage requirements (80% floor, 100% goal) and test instructions.

Acknowledgements

  • 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

License

MIT

About

A pure-Lua, Neovim-native Swank protocol client for Common Lisp development

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages