GitHub - etyurkin/zed-cl: Common Lisp extension for Zed editor

5 min read Original article β†—

Common Lisp Extension for Zed

Common Lisp language support for the Zed editor with integrated LSP server and Jupyter kernel support.

Features

🎯 Smart Type-Aware Code Completion

Intelligent completions that detect type declarations and provide contextual example values:

;; After defining and evaluating:
(defun greet (name)
  (declare (type string name))
  (format t "Hello, ~a!~%" name))

;; Typing (gree shows:
(greet name)  ← Parameter name placeholder

Smart parameter completion:

  • Shows parameter names from function signatures
  • Includes type information when available
  • Works with both built-in and user-defined functions

πŸ”§ LSP Features

  • Syntax highlighting with tree-sitter grammar
  • Autocomplete with parameter snippets and type-aware placeholders
  • Multi-package support with package-qualified completion (my-utils::internal-helper)
  • Package labels showing which package each symbol comes from
  • User package prioritization - your symbols appear first in completions
  • Hover documentation showing signatures and docstrings
  • Package hover - hover over package names to see symbols in that package
  • Symbol information from both built-in Common Lisp and user definitions
  • Document sync for real-time updates
  • Master REPL integration for querying user-defined symbols

πŸ”„ Jupyter REPL Integration

  • Shared Master REPL: All Jupyter kernels and the LSP server share a single REPL environment
  • Live sync: Definitions from Jupyter automatically available in Zed LSP
  • Bidirectional: Code evaluated in Zed available in Jupyter
  • Multi-kernel support: Run multiple Jupyter kernels with shared state
  • Auto-reconnect: Handles REPL restarts gracefully

πŸ“ Language Support

  • Syntax highlighting for all Common Lisp constructs
  • Rainbow brackets support
  • Multi-line s-expression evaluation
  • ASDF system definition support

Installation

From Zed Extensions

  1. Open Zed
  2. Open the command palette (Cmd+Shift+P)
  3. Search for "zed: extensions"
  4. Search for "Common Lisp"
  5. Click "Install"

Development Installation

git clone https://github.com/etyurkin/zed-cl
cd zed-cl

In Zed:

  1. Go to Extensions (Cmd+Shift+P β†’ "zed: extensions")
  2. Click "Install Dev Extension"
  3. Select the cloned directory

Quick Start

Prerequisites

  • SBCL: Install via brew install sbcl (macOS) or your package manager
  • Quicklisp: Install from quicklisp.org
  • Jupyter (optional): Install via pip install jupyter jupyterlab
  • ZeroMQ (for Jupyter): Install via brew install zeromq (macOS)

Basic LSP Usage

Once installed, the LSP server starts automatically when you open a .lisp file:

  1. Open or create a .lisp file
  2. Start typing - you'll see:
    • Autocomplete for Common Lisp built-ins
    • Hover documentation
    • Symbol information

Using with Jupyter

For the full experience with REPL evaluation and shared state:

# Install Jupyter kernel
make install

# Verify installation
make verify

# Start Jupyter
jupyter lab

Usage Examples

In Zed Editor

;; Define a function
(defun factorial (n)
  "Calculate factorial of n"
  (declare (type integer n))
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))

;; Select the function with Cmd+Shift+Up
;; Press Ctrl+Shift+Enter to evaluate it in the REPL

;; Now type (fact and you'll see completion with package info:
factorial [common-lisp-user]  ← Your definition appears first!
factorial [alexandria]        ← Library symbols appear after

;; Hover over 'factorial' to see the documentation

Multi-Package Support

;; Define functions in custom packages
(defpackage :my-utils
  (:use :cl)
  (:export #:add-numbers #:multiply-numbers))

(in-package :my-utils)

(defun add-numbers (a b)
  "Add two numbers"
  (+ a b))

;; Select the above code
;; Press Ctrl+Shift+Enter to evaluate in the REPL

;; In another file, use package-qualified completion:
;; Type (my-utils:: to see all symbols in the package
;; Type (my-utils::add to complete to add-numbers

;; Hover over 'my-utils' to see all package symbols
;; Package tooltip shows:
;;   Package: my-utils
;;   User-defined package
;;   Symbols (2):
;;   - add-numbers (function)
;;   - multiply-numbers (function)

Shared State Magic

In one file:

(defvar *config*
  '(:database "mydb" :port 5432))

In another file:

(getf *config* :port)  ; => 5432
;; Hover over *config* shows the value!
;; Autocomplete suggests *config*

All files share the same REPL environment via the master REPL architecture.

Supported File Extensions

  • .lisp - Common Lisp source files
  • .lsp - Lisp source files
  • .l - Lisp files
  • .cl - Common Lisp files
  • .asd - ASDF system definitions
  • .ros - Roswell scripts

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Master REPL Process        β”‚
β”‚  (Shared Lisp Environment)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚              β”‚              β”‚
β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”    β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”    β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
β”‚Jupyter β”‚    β”‚Jupyter β”‚    β”‚  Zed   β”‚
β”‚Kernel 1β”‚    β”‚Kernel 2β”‚    β”‚  LSP   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

All components connect to a single master REPL for true state sharing.

Tree-sitter Grammar

This extension uses tree-sitter-commonlisp, automatically downloaded and compiled by Zed.

Management Commands

# Jupyter Kernel
make install        # Install Jupyter kernel
make verify         # Verify installation and dependencies
make uninstall      # Uninstall kernel
make test-jupyter   # Test kernel manually

# Master REPL
make start-repl     # Start master REPL server
make stop-repl      # Stop master REPL (resets environment)
make repl-status    # Check master REPL and kernel status

# Maintenance
make clean          # Clean temporary files
make help           # Show all available commands

Troubleshooting

LSP not starting

  • Check Zed's language server logs
  • Ensure SBCL is installed: which sbcl
  • Check Zed's extension installation succeeded

Completions not working

  • Check master REPL is running: ls /tmp/cl-master-repl.sock
  • Verify LSP server is connected (check Zed's language server logs)
  • Try restarting Zed to reconnect to master REPL

Jupyter kernel won't start

  • Run make verify to check dependencies
  • Ensure Jupyter is installed: pip install jupyter jupyterlab
  • Ensure ZeroMQ is installed: brew install zeromq (macOS)

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Development Setup

  1. Clone the repository
  2. Install dev extension in Zed
  3. Make changes
  4. Test with a .lisp file

License

MIT

Links