ABLE - A Basic Lisp Editor

ABLE is an open source Common Lisp editor for Mac, Linux and Windows. ABLE's features include a listener with command history, syntax colouring, symbol completion, jump to definition, parenthesis matching, configurable indentation, Hyperspec lookup and call-tips. ABLE is distributed under the MIT license.

ABLE was formerly hosted at another site (Internet Archive); with Phil's permission, development has moved to

Mailing lists


Version 0.20 was compatible with CCL, SBCL and CLISP. It depends on Tcl/Tk, LTK, CL-FAD and TRIVIAL-GRAY-STREAMS. ABLE can be loaded and started with:

  (asdf:oos 'asdf:load-op 'able)  ; load ABLE
  (able::start)                   ; start ABLE

The latest source release is Development sources are available from Gitweb. Binary releases will be made available as time permits and requests are made.

Getting started

ABLE comprises a single window split into two frames. The top frame is the editor and the bottom the listener (the interface to the REPL). Information messages and call-tips are displayed in the message bar along the bottom. All commands are invoked with keyboard shortcuts which are documented below. Commands which require further input, such as filenames, prompt for it in the listener.

Throughout this document, as each feature of ABLE is introduced, relevant key bindings or associated configuration settings will be described. These take the form of code snippets which can be supplied in a configuration file. The examples given show the default values. To override the default values, create a file named .able in your home directory and provide any settings you wish to change. If you're unsure of where your home directory is, evaluate the following in the listener:


Note that it's not necessary to have this file for ABLE to run nor is it necessary to override every setting if you do, just those you wish to change.

Working with files

The standard file system commands are available through the following shortcuts:

  (setf able::*key-new-file* "<Control-n>")
  (setf able::*key-open-file* "<Control-o>")
  (setf able::*key-close-file* "<Control-w>")
  (setf able::*key-save-file* "<Control-s>")
  (setf able::*key-save-as-file* "<Control-S>")

Prompts for filenames appear in the listener which supports pathname completion by pressing the TAB key. In the event of multiple possible completions, alternatives will be shown in the message bar. Completion is only provided for .lisp files and directories.

In addition to opening a file, ABLE can also load a file into both the editor and the Lisp system, reload it and compile it:

  (setf able::*key-load-file* "<Control-l>")
  (setf able::*key-reload-file* "<Control-r>")
  (setf able::*key-compile-file* "<Control-k>")

ABLE can open multiple files at once and switch between them with

  (setf able::*key-next-file* "<Control-b>")

Finally, when you want to quit ABLE you can press

  (setf able::*key-quit-able* "<Control-q>")

If there are any unsaved files you will be prompted to take action.

Working with code

ABLE can be used to edit any text file although it can't be considered a general purpose text editor, instead focussing on Common Lisp specific features. The standard editing commands are:

  (setf able::*key-cut* "<Control-x>")
  (setf able::*key-copy* "<Control-c>")
  (setf able::*key-paste* "<Control-v>")
  (setf able::*key-select-all* "<Control-a>")

As you type code, ABLE will highlight known symbols. This includes both symbols from the Hyperspec as well as those from your own code. When a file is loaded or saved, it's indexed for all defining forms. In addition, you can watch a set of directories using

  (setf able::*watch-directories* nil)

By providing a list of directory names here, all symbols found will be indexed. Because the index is updated whenever a file is saved, you can comfortably work on your own systems in these directories and know the index is up to date. As well as providing syntax colouring, this setting is used in symbol completion and jump to definition. Symbol completion allows you to type the start of a symbol name and then press

  (setf able::*key-code-complete* "<Tab>")

to cycle through all possible completions of that prefix in turn. Jump to definition, invoked with

  (setf able::*key-lookup* "<Control-d>")

will locate the definition of the symbol under the cursor. If the definition is in another file then it will be opened (or switched to if already open). If lookup is pressed on a symbol defined by Common Lisp itself then the relevant section of the Hyperspec is loaded. The location of the Hyperspec can be configured with

  (setf able::*hyperspec-root*

By default, ABLE uses the version on the LispWorks server but this can be replaced with a local URL. The browser used to open the Hyperspec can be specified in

  (setf able::*web-browser*
    #+:able-windows "C:/Progra~1/Intern~1/iexplore.exe"
    #+:able-linux "/usr/bin/firefox"
    #+:able-macosx "open")

As you write code, ABLE will show call-tips for known symbols in the message bar. This includes the name of the function and its lambda list. Note that the call-tips are mined from the Lisp system itself and not all symbols are covered in all implementations.

ABLE indents code as you type based on idiomatic Lisp coding standards. Because these are not enforced, either by the compiler or the community, it's possible to extend the rules to suit your preferences using

  (setf able::*indentation-rules*
    '(("if" . 4)
      ("cond" . 6)
      ("and" . 5)
      ("or" . 4)
      ("eq" . 4)
      ("loop" . 6)))

The default indentation rule specifies a 2 space indent for each open SEXP and a 1 space indent for an open double parenthesis such as a let block's binding list. Anything provided in the above setting overrides the default on a per symbol basis. Configuration comprises a list of cells in which each entry is the name of the symbol and the number of spaces to indent it. To reformat a block of code, place the cursor inside it and press

  (setf able::*key-reformat* "<Control-j>")

To copy code to the listener, place the cursor at the closing parenthesis of an SEXP and press

  (setf able::*key-copy-to-repl* "<Control-e>")

Once at the listener, pressing ENTER will evaluate the form. The listener has a history buffer which can be navigated with the up and down arrow keys. To clear the current command in the listener press ESCAPE. Repeatedly pressing ESCAPE will toggle the cursor between the editor and the listener.

Standard find and goto line facilities are available with

  (setf able::*key-find* "<Control-f>")
  (setf able::*key-find-again* "<Control-g>")
  (setf able::*key-goto-line* "<Control-i>")

These prompt for input at the listener and can be cancelled with ESCAPE.

Placing the cursor on a closing parenthesis and pressing

  (setf able::*key-macro-expand* "<Control-m>")

will macroexpand the code, outputting the results in the listener.

Other Settings

Although ABLE has a deliberately spartan, keyboard focussed UI, a few settings can be configured. Various colours can be overridden using either HEX values or colour names

  (setf able::*highlight-text* "#2D1E27")
  (setf able::*highlight-background* "#FFFFFF")
  (setf able::*highlight-primary* "#1900D5")
  (setf able::*highlight-secondary* "#991C1C")
  (setf able::*highlight-comments* "#00732A")
  (setf able::*highlight-paren-match* "#F3752F")
  (setf able::*highlight-error* "#FF4343")

The font used throughout ABLE can be set (Courier is a safe default which Tk guarantees to be present on all operating systems but I recommend Monaco on OS X, Consolas on Windows and Monospace on Ubuntu).

  (setf able::*buffer-font* "Courier 12 normal roman")

The initial window placement and size can be specified to suit your display:

  (setf able::*window-width* 640)
  (setf able::*window-height* 480)
  (setf able::*window-x* 30)
  (setf able::*window-y* 30)

Finally, the number of lines to display in the listener can be set:

  (setf able::*listener-lines* 10)


As with many FAQs, this one's a mixture of real questions that often come up and feeble justifications for why things are implemented the way they are!

Why do you no longer supply the binaries?
Unfortunately, whatever I supplied, people wanted something different! Be it a newer version of CLISP, an older version of CLISP, SBCL on Windows or 32-bit CCL on OSX. Unfortunately I just don't have the time to make everyone happy so now I provide only the source code. As ABLE is just a Common Lisp library, anyone who's managed to set up a Lisp compiler and ASDF can be up and running quite quickly.

Which Lisp compilers are supported?
ABLE is compatible with CCL, SBCL and CLISP.

Why do I need to install Tcl/Tk?
ABLE uses LTK which is a Common Lisp interface to the Tk GUI. Other GUI toolkits do exist for CL but LTK is the only one which meets my requirements: open source, cross compiler, cross platform and builds without errors. If you own a Mac then you already have Tcl/Tk installed. If you're on Windows or Linux then you can get Tcl/Tk from here or here or here.

Why doesn't ABLE load on my Windows box?
Ensure you're running a supported Lisp compiler and that ASDF can find ABLE and its dependencies. First start up your lisp and try to load ABLE (but don't start it). If everything loads then the problem is with Tcl/Tk. Ensure that Tcl/Tk's wish.exe program is visible on your system path by running it from the command line. If it is but the GUI window doesn't load, the problem is most likely a clash with some resident Windows programs, especially those loaded in the system tray area. Try experimenting to see if closing any helps.

Why is there no menu?
ABLE provides a purely keyboard driven user interface. For example when opening a file, a text prompt is provided in the listener so it wouldn't make sense to lift your hand off the keyboard, pick up the mouse to select a menu option and then return your hand to the keyboard to enter the pathname.

When I select paste, why does the program stop responding?
Using Paste when the Tk clipboard is empty causes LTK or Tcl/Tk to silently hang. Unfortunately this seems to happen before ABLE can intercept the event. A bug report has been filed with the LTK developers although I'm not sure if there's anything they can do about it.

Why is there no debugger?
A debugger is the most important of the missing features in ABLE. Adding one is likely to be a big task but is something I plan to work on in the future.

Why does the syntax colouring think that strings contain code?
This is a limitation of the current algorithm which favors speed over accuracy, especially in the case of multi-line constructs which are basically ignored.


Thanks to Phil Armitage, Myroslav Vus, Michael Ben-Yosef, Sean Ross, Jussi Salmela, and Masayuki Onjo.

Valid XHTML 1.0 Strict