ICL is an enhanced REPL for Common Lisp. It provides a modern, terminal-based interactive experience with readline-style editing, persistent history, tab completion, and an extensible command system.
- Syntax highlighting - Colorized input with distinct colors for keywords, strings, comments, numbers, and symbols
- Parenthesis matching - Real-time highlighting of matching parentheses as you type
- Paredit mode - Structural editing with auto-close parens, safe deletion, and sexp navigation
- Multi-line input - Automatically detects incomplete expressions with smart indentation
- Persistent history - Command history saved across sessions
- Tab completion - Complete symbols, package-qualified names, and keywords
- Command system - Built-in commands prefixed with comma (e.g.,
,help) - Multiple Lisp support - Works with SBCL, CCL, ECL, CLISP, ABCL, and Clasp
- Error backtraces - Automatic backtrace capture with
,btcommand to view stack traces - Thread inspection - List and inspect threads in the inferior Lisp
- Documentation lookup - Quick access to function docs and apropos search
- Interactive object inspector - TUI for exploring objects with keyboard navigation
- Tracing - Enable/disable function tracing
- Source location - Find where functions are defined
- Terminal-aware colors - Automatically detects light/dark terminal background
- AI integration - Use
,explainto get AI-powered explanations of code, errors, and results
Download from GitHub Releases:
| Platform | Formats |
|---|---|
| Linux | RPM, DEB |
| Windows | ZIP, EXE installer, MSI installer |
Roswell users can also install with ros install atgreen/icl.
git clone https://github.com/atgreen/icl.git
cd icl
ocicl install
makeRequires SBCL, ocicl, and libfixposix-devel.
Start ICL (auto-detects available Lisp):
Specify a Lisp implementation:
icl --lisp ccl
icl --lisp eclEvaluate an expression and exit:
Load a file before starting the REPL:
Connect to an existing Slynk server:
icl --connect localhost:4005Skip loading ~/.iclrc:
Commands are prefixed with a comma. Type ,help for a full list.
| Command | Description |
|---|---|
,cd <package> |
Change current package |
,pwd |
Show current package |
,ls [filter] |
List symbols (filters: functions, macros, variables, classes) |
| Command | Description |
|---|---|
,doc <symbol> |
Show documentation |
,describe <symbol> |
Full description of symbol |
,apropos <pattern> |
Search for matching symbols |
,arglist <function> |
Show function arguments |
,source <symbol> |
Show source location |
| Command | Description |
|---|---|
,inspect <expr> |
Interactive object inspector (alias: ,i) |
,i |
Inspect last result (*) |
,inspect-static <expr> |
Non-interactive inspection output |
,slots <expr> |
Show slots of a class instance |
The interactive inspector (,i or ,inspect) provides a TUI for exploring objects:
| Key | Action |
|---|---|
↑/↓ or j/k |
Navigate entries |
Enter |
Drill into selected entry |
b or Backspace |
Go back to parent object |
q or Escape |
Quit inspector |
| Command | Description |
|---|---|
,macroexpand <form> |
Expand macro once |
,macroexpand-all <form> |
Fully expand all macros |
| Command | Description |
|---|---|
,load-system <name> |
Load system via ocicl/Quicklisp/ASDF (alias: ,ql) |
,libyear |
Show dependency freshness metric (requires ocicl) |
,changes [system] |
Show LLM-generated changelogs (requires ocicl) |
,time <form> |
Time expression evaluation |
,load <file> |
Load a Lisp file |
,compile-file <file> |
Compile a file |
,disassemble <fn> |
Disassemble a function |
| Command | Description |
|---|---|
,bt |
Show backtrace from last error |
,step <form> |
Show traced function calls during evaluation |
,threads |
List all threads in inferior Lisp |
,trace <function> |
Enable tracing |
,untrace <function> |
Disable tracing |
,untrace-all |
Disable all tracing |
| Command | Description |
|---|---|
,profile <form> |
Profile a form with the statistical profiler |
,profile-start |
Start ongoing profiling |
,profile-stop |
Stop profiling and show results |
,profile-reset |
Reset profiler data |
| Command | Description |
|---|---|
,show-config |
Show config file location and customization options |
,reload-config |
Reload ~/.iclrc |
,paredit [on/off] |
Toggle paredit structural editing mode |
| Command | Description |
|---|---|
,help |
Show all commands |
,info |
Show session information |
,history |
Show value history variables |
,lisp [name] |
Show or switch Lisp backend |
,clear |
Clear terminal |
,quit |
Exit ICL |
| Command | Description |
|---|---|
,explain |
Explain last result or error using AI |
,explain <code> |
Explain specific code |
,ai-cli [name] |
Show or set AI backend (gemini, claude, codex) |
The ,explain command uses an AI CLI (auto-detected from PATH) to provide explanations of Lisp code, errors, and results. When using Gemini CLI, ICL provides an MCP server that gives the AI read-only access to the live Lisp environment - it can query documentation, describe symbols, and search for functions, but cannot execute any code.
Requires one of: Gemini CLI, Claude CLI, or Codex CLI
ICL maintains history of recent values and inputs:
| Variable | Description |
|---|---|
icl:_ / icl:icl-* |
Last result |
icl:__ / icl:icl-** |
Second-to-last result |
icl:___ / icl:icl-*** |
Third-to-last result |
icl:icl-+ |
Last input form |
icl:icl-/ |
Last returned values (all values) |
ICL loads ~/.iclrc on startup (unless --no-config is specified). This file can contain any Common Lisp code.
| Variable | Description |
|---|---|
*default-lisp* |
Lisp implementation to use (:sbcl, :ccl, :ecl, :clisp, :abcl, :clasp) |
*prompt-string* |
Prompt format string (default: "~A> ") |
*result-prefix* |
Prefix for results (default: "=> ") |
*colors-enabled* |
Enable syntax coloring (default: t) |
*history-size* |
Maximum history entries (default: 1000) |
*paredit-mode* |
Enable structural editing (default: nil) |
*ai-cli* |
AI CLI for ,explain (:gemini, :claude, :codex, or :auto) |
Use configure-lisp to customize how ICL invokes a Lisp implementation:
(icl:configure-lisp impl &key program args eval-arg):program- Path to the executable:args- List of command-line arguments:eval-arg- The eval flag (e.g.,"--eval")
;; Use CCL instead of SBCL
(setf icl:*default-lisp* :ccl)
;; Custom SBCL with more memory
(icl:configure-lisp :sbcl
:program "/opt/sbcl/bin/sbcl"
:args '("--dynamic-space-size" "8192"))
;; Enable paredit mode
(setf icl:*paredit-mode* t)
;; Custom prompt
(setf icl:*prompt-string* "λ ~A> ")
;; Load commonly used systems
(asdf:load-system :alexandria)
;; Define custom utilities
(defun reload ()
(asdf:load-system :my-project :force t))| Key | Description |
|---|---|
Enter |
Submit form if complete, otherwise insert newline |
Alt+Enter |
Always insert newline (works in most terminals) |
Shift+Enter |
Always insert newline (requires kitty keyboard protocol) |
Tab |
Complete symbol or show completion menu |
Ctrl+A / Home |
Move to beginning of line |
Ctrl+E / End |
Move to end of line |
Ctrl+K |
Kill to end of line |
Ctrl+U |
Clear entire line |
Ctrl+L |
Clear screen |
Ctrl+D |
EOF (exit if line empty) |
Ctrl+C |
Cancel current input |
Ctrl+R |
Reverse history search |
Ctrl+G |
Cancel search |
Up/Down |
Navigate history (on first/last line) or move cursor |
Alt+Q |
Reindent current form |
Alt+F |
Forward sexp (paredit mode only) |
Alt+B |
Backward sexp (paredit mode only) |
Notes:
- In paredit mode, Enter only submits when the cursor is at the end of the buffer (allowing multi-line editing of balanced forms)
- Use Alt+Enter in gnome-terminal and most other terminals. Shift+Enter only works in terminals with kitty keyboard protocol support (kitty, WezTerm, Alacritty, etc.).
| Variable | Description |
|---|---|
ICL_SLYNK_PATH |
Override path to Slynk directory |
ICL_ASDF_PATH |
Override path to bundled ASDF (for backends without ASDF) |
ICL_BACKGROUND |
Override terminal background detection (dark or light) |
NO_COLOR |
When set to any non-empty value, disables colored output (see no-color.org) |
ICL aims to support multiple Common Lisp implementations. SBCL is the primary development and testing platform.
| Implementation | Status |
|---|---|
| SBCL | Tested |
| CCL | Tested |
| ECL | Tested |
| ABCL | Tested |
| Clasp | Untested |
| CLISP | Experimental |
ICL operates as a frontend that communicates with a backend Lisp process via the Slynk protocol (from SLY). This architecture allows ICL to:
- Work with any Common Lisp implementation
- Provide consistent features regardless of backend
- Connect to remote Lisp processes
MIT License. See LICENSE file for details.
Anthony Green [email protected]
