Thanks to visit codestin.com
Credit goes to github.com

Skip to content

etyurkin/zed-cl

Repository files navigation

Common Lisp Extension for Zed

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

Features

  • LSP Features: Syntax highlighting, autocomplete, hover documentation, goto-definition
  • Smart Completion: Type-aware parameter snippets, package-qualified completions
  • Multi-Package Support: Package labels, user symbols prioritized
  • Interactive REPL: Built-in REPL with Ctrl+Shift+Enter, shared state across files
  • Rich Output: Display markdown, tables, images, and JSON inline
  • Jupyter Compatible: Optional Jupyter Lab/Notebook support
  • Cross-Platform: Works on macOS and Linux (not tested)

Prerequisites

Required for all features:

  1. Common Lisp Implementation (one of):

    • SBCL (recommended - full feature support):

      • macOS: brew install sbcl
      • Linux: apt install sbcl / dnf install sbcl / pacman -S sbcl
    • ECL (alternative - ~90% feature parity):

      • macOS: brew install ecl
      • Linux: apt install ecl / dnf install ecl / pacman -S ecl

    Configure your preferred implementation via ~/.zed-cl/config.json (see Configuration section below).

Note: Quicklisp and required dependencies will be installed automatically during the build process (make build or make setup-quicklisp).

Development Installation

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

In Zed:

  1. Open command palette (Cmd+Shift+P)
  2. Run "zed: install dev extension"
  3. Select the cloned directory

Configuration

All configuration is stored in ~/.zed-cl/config.json using profiles:

{
  "active_profile": "sbcl",
  "profiles": {
    "sbcl": {
      "lisp_impl": "sbcl",
      "system_index": "system-index.db",
      "completion_package_whitelist": [
        "CORE-KEYWORDS",
        "COMMON-LISP",
        "COMMON-LISP-USER"
      ]
    }
  }
}

Profile Settings

Each profile can configure:

  • lisp_impl - Common Lisp implementation ("sbcl" or "ecl")
  • system_index - System index database filename (in ~/.zed-cl/)
  • completion_package_whitelist - Packages to show in completions

Multiple Profiles

Create different profiles for different workflows:

{
  "active_profile": "sbcl-full",
  "profiles": {
    "sbcl-full": {
      "lisp_impl": "sbcl",
      "system_index": "sbcl-complete.db",
      "completion_package_whitelist": ["CORE-KEYWORDS", "COMMON-LISP", "COMMON-LISP-USER"]
    },
    "ecl-dev": {
      "lisp_impl": "ecl",
      "system_index": "ecl-packages.db",
      "completion_package_whitelist": ["COMMON-LISP", "COMMON-LISP-USER"]
    },
    "minimal": {
      "lisp_impl": "sbcl",
      "system_index": "system-index.db",
      "completion_package_whitelist": ["COMMON-LISP"]
    }
  }
}

Switch profiles by changing active_profile and restarting Zed.

Completion Package Whitelist

Control which packages appear in completions. By default (when not set), shows all user-defined packages plus COMMON-LISP and KEYWORD.

Special values:

  • "CORE-KEYWORDS" - Only core keywords (excludes system keywords)
  • "ALL-KEYWORDS" - All keywords including system ones

Using the Extension

LSP Features

Open any .lisp file and get:

  • Autocomplete for Common Lisp built-ins and your code
  • Hover documentation
  • Goto-definition
  • Package-aware completions

Interactive REPL

Inline evaluation:

  1. Open a .lisp file
  2. Select code or position cursor in a form
  3. Press Ctrl+Shift+Enter to evaluate
  4. See results inline

Terminal REPL (for development):

  1. Open command palette (Cmd+Shift+P)
  2. Type "Tasks: Spawn"
  3. Select "Common Lisp REPL"
  4. Get an interactive REPL in a terminal tab

All evaluations share a single REPL environment - definitions are automatically available in autocomplete.

Direct Terminal Connection (Advanced):

For debugging or advanced use, connect directly to the master REPL socket:

./scripts/connect-repl.sh

This connects via Unix domain socket to the shared REPL using the configured Lisp implementation.

Building a System Index (Optional)

Goto-definition works out-of-the-box for your workspace code. To enable goto-definition for external libraries (Quicklisp packages, SBCL built-ins, etc.), build a system index.

Quick Start

The extension bundles an indexer tool at ~/.zed/extensions/installed/zed-cl/<version>/bin/zed-cl-index.

For SBCL users - index SBCL sources:

# Using Makefile (indexes SBCL built-ins)
make build-system-index

# Or manually
~/.zed/extensions/installed/zed-cl/<version>/bin/zed-cl-index \
  --source-dir /path/to/sbcl/src/code \
  --output ~/.zed-cl/system-index.db \
  --default-package COMMON-LISP

For all users - index Quicklisp packages:

# Example: Index Alexandria
zed-cl-index \
  --source-dir ~/quicklisp/dists/quicklisp/software/alexandria-<version> \
  --output ~/.zed-cl/system-index.db \
  --default-package ALEXANDRIA

Finding SBCL Source

macOS (Homebrew):

$(brew --prefix sbcl)/share/sbcl/src
# Usually: /opt/homebrew/share/sbcl/src or /usr/local/share/sbcl/src

Linux:

/usr/share/sbcl/src           # Debian/Ubuntu
/usr/share/sbcl-source/src    # Some distributions

Indexer Commands

Build an index:

zed-cl-index \
  --source-dir <PATH>           # Directory containing .lisp files (searches recursively)
  --output <DB_FILE>            # Output database file (appends if exists)
  --default-package <PACKAGE>   # Default package for symbols without (in-package ...)

Query an index:

zed-cl-index \
  --query \
  --database <DB_FILE>          # Database to query
  --symbol <SYMBOL>             # Symbol name (e.g., MAPCAR, FORMAT) [required]
  --package <PACKAGE>           # Package name (e.g., SB-IMPL) [optional - searches all packages if omitted]

Examples

Index SBCL standard library:

# Core runtime (list functions, sequences, etc.)
zed-cl-index \
  --source-dir /opt/homebrew/share/sbcl/src/code \
  --output ~/.zed-cl/system-index.db \
  --default-package COMMON-LISP

# CLOS/MOP (classes, methods, generic functions)
zed-cl-index \
  --source-dir /opt/homebrew/share/sbcl/src/pcl \
  --output ~/.zed-cl/system-index.db \
  --default-package COMMON-LISP

# Interpreter
zed-cl-index \
  --source-dir /opt/homebrew/share/sbcl/src/interpreter \
  --output ~/.zed-cl/system-index.db \
  --default-package COMMON-LISP

Index Quicklisp libraries:

# Alexandria
zed-cl-index \
  --source-dir ~/quicklisp/dists/quicklisp/software/alexandria-20241012-git \
  --output ~/.zed-cl/system-index.db \
  --default-package ALEXANDRIA

# Iterate
zed-cl-index \
  --source-dir ~/quicklisp/dists/quicklisp/software/iterate-1.5.3 \
  --output ~/.zed-cl/system-index.db \
  --default-package ITERATE

Query the index:

# Find MAPCAR in a specific package
zed-cl-index --query \
  --database ~/.zed-cl/system-index.db \
  --package SB-IMPL \
  --symbol MAPCAR

# Output:
# Looking up: SB-IMPL::MAPCAR
#
# Found 1 definition(s):
#
#   [1] function in SB-IMPL
#       File: /opt/homebrew/share/sbcl/src/code/list.lisp
#       Position: line 1388, char 19

# Find MAPCAR in all packages (omit --package)
zed-cl-index --query \
  --database ~/.zed-cl/system-index.db \
  --symbol MAPCAR

# Output:
# Looking up: MAPCAR (in all packages)
#
# Found 1 definition(s) across packages:
#
#   [1] function in SB-IMPL
#       File: /opt/homebrew/share/sbcl/src/code/list.lisp
#       Position: line 1388, char 19

Multiple System Indexes (Advanced)

Create different indexes for different projects:

# Minimal: Just SBCL core
zed-cl-index \
  --source-dir /path/to/sbcl/src/code \
  --output ~/.zed-cl/system-sbcl-only.db \
  --default-package COMMON-LISP

# Full: SBCL + all your Quicklisp libraries
zed-cl-index \
  --source-dir /path/to/sbcl/src/code \
  --output ~/.zed-cl/system-full.db \
  --default-package COMMON-LISP
# ... add more libraries

Switch between indexes by changing the system_index field in your active profile in ~/.zed-cl/config.json and restarting the extension.

How It Works

  • User code: Automatically indexed when you open/save .lisp files → ~/.zed-cl/user-index.db
  • System libraries: Manually indexed using zed-cl-index~/.zed-cl/system-index.db (or custom name)
  • Goto-definition search order:
    1. User index (your workspace code)
    2. System index (SBCL + libraries you indexed)

Development Commands

# Build
make build          # Build Rust binaries and extension
make dev            # Development mode
make check          # Type check only
make test           # Run tests

# Jupyter
make install-jupyter  # Register kernel for Jupyter
make verify          # Verify SBCL installation

# Maintenance
make clean          # Clean build artifacts
make help           # Show all commands

Process Management

List running processes:

# Count each process type
ps aux | grep -c '[z]ed-cl-kernel'      # Count kernels
ps aux | grep -c '[z]ed-cl-lsp'        # Count LSP servers
ps aux | grep -c 'master-repl'         # Count master REPLs

# Show detailed process list
ps aux | grep -E 'zed-cl-kernel|zed-cl-lsp|master-repl' | grep -v grep

Kill processes:

# Kill all zed-cl processes
pkill -f 'zed-cl-kernel' && pkill -f 'zed-cl-lsp' && pkill -f 'master-repl'

# Kill individual components
pkill -f 'zed-cl-kernel'        # Kill only kernels
pkill -f 'zed-cl-lsp'          # Kill only LSP
pkill -f 'master-repl'         # Kill only master REPL

# Force kill if needed
pkill -9 -f 'zed-cl-kernel' && pkill -9 -f 'zed-cl-lsp' && pkill -9 -f 'master-repl'

Log Locations

LSP Server:

  • /tmp/cl-zed-lsp.log - LSP debug logs
  • /tmp/master-repl.log - Master REPL logs

Zed Application:

  • ~/Library/Logs/Zed/Zed.log (macOS)
  • ~/.local/share/zed/logs/Zed.log (Linux)

Database Indexes:

  • ~/.zed-cl/system-index.db - System libraries (SBCL + manually indexed packages)
  • ~/.zed-cl/user-index.db - User workspace code (auto-indexed)

Architecture

      ┌───────────────────────┐
      │  Master REPL Process  │
      │ (Unix domain sockets) │
      └──────────┬────────────┘
                 │
       ┌─────────┼──────────┐
       │         │          │
   ┌───▼───┐  ┌──▼───┐  ┌───▼───┐
   │Console│  │ Zed  │  │ Zed   │
   │ REPL  │  │ REPL │  │ LSP   │
   └───────┘  └──────┘  └───────┘

All components connect to a single master REPL via Unix domain sockets for true state sharing. Code evaluated in any component is immediately available in all others.

License

MIT

Links

About

Common Lisp extension for Zed editor

Resources

License

Stars

12 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors