Augustana University College

COMPUTING SCIENCE 370
Programming Languages


Running Lisp under Emacs


A convenient way to write, test, and edit a Lisp program on a Unix system is to use Emacs' capability of running a program--in this case, the Lisp interpreter--in a window. You can divide the Emacs editing window into two windows, one above the other, and edit your Lisp program file in one window, sending individual S-expressions to the Lisp interpreter in the other window for execution. If your function doesn't work as you had expected, you can edit the function and send it for execution again.

After starting Emacs, create a new Lisp file by typing:

C-x C-f test.lisp

Note that C-x means to hold the Ctrl key while pressing x; similarly, C-f means to hold Ctrl while pressing f. The key combination C-x C-f invokes the Emacs function which creates a new file or opens an existing file. Emacs should recognize 'test.lisp' as a Lisp file (or you may have to edit your Emacs initialization file '.emacs' in your home directory to enable this), as shown by the '(Lisp)' in the status bar near the bottom of the screen.

Now split the window into two:

C-x 2

Start running the Lisp interpreter in the upper window:

M-x run-lisp

The M-x stands for "meta-x", and can be entered either by pressing Esc followed by x or by holding one of the Alt keys while pressing x. (In some setups, only the left Alt key is defined as meta.) Emacs calls this an Inferior-Lisp window.

Hint: When you enter a control-key command which requires a parameter (such as C-x 2) or start an extended command with M-x, the focus (your cursor) moves to the minibuffer -- the one-line command entry area at the bottom of the Emacs window. Sometimes it seems as if one is trapped in the minibuffer, perhaps due to typing the wrong thing at the wrong time, but there is a quick way out: C-g. Sometimes it takes two C-g's to get out of a nested command, so I often type three of them in a row just to make sure (and because it feels so good to escape the minibuffer mire).

Try entering some Lisp S-expressions for the interpreter to execute:

(car '(a b c d))

The interpreter should respond:

A

Now switch windows:

C-x o

Note: That's the letter 'o', not the numeral '0'.

Type an S-expression:

(car '(a b c d))

Automagically send it to the Lisp interpreter for execution (without changing windows):

C-M-x

Either hold both Ctrl and Alt while pressing x, or press Esc, then hold Ctrl and press x.

Try defining a function in the test.lisp window:

   (defun trythis ()
      (car '(a b c d))) C-M-x

Hint: Be sure your cursor is after the closing parenthesis of the function definition. The key combination C-e (for "end") will take you to the end of the current line. (In a blatant inconsistency, C-a takes you to the front of the line, presumably because 'a' is at the front of the alphabet.)

The interpreter should indicate that it has stored the definition of this function by printing its name:

TRYTHIS

Note that the interpreter is case-insensitive.

Now test your new function:

(trythis) C-M-x

Hint: You can type C-M-x on the same line or the next.

Let's try one that takes an argument:

   (defun tryarg (l)
      (car l)) C-M-x

You could test this in the test.lisp window, but let's use the interpreter window instead. First, tell Emacs to switch to the other visible window:

C-x o

Then tell Lisp to execute the function:

(tryarg '(a b c d))

The interpreter should respond:

A

If your S-expression needs to read input from the standard input, you must enter it in the Lisp interpreter window. Switch to the test.lisp window and define a function:

C-x o

   (defun readList ()
      (read)) C-M-x

Now try to execute it:

(readList)

Note that Lisp is waiting for you to type input. Switch to the "inferior Lisp" window

C-x o

and type some input:

(0 1 2 3)

The interpreter will return the value you entered as the result of the readList function:

(0 1 2 3)

If an error occurs (e.g., you misspell a function name), the interpreter will enter debug mode, signalled by a double >> prompt. To exit debug mode (return to "top-level"), type:

:r

Exiting Emacs

Be sure to save your file before exiting:

C-x o

C-x C-s

Note: C-x C-s saves the current buffer. C-x s saves all unsaved buffers, but prompts you for confirmation.

To exit Emacs:

C-x C-c

Actually, you can enter C-x C-c without saving modified buffers, because Emacs will offer to save all modified buffers before it exits.

Since the Lisp interpreter is still running, Emacs will prompt you to confirm that you actually want to kill the process. You must type "yes" in response (not just "y"). If you wish to avoid this minor nuisance, you could halt the Lisp interpreter yourself prior to exiting Emacs: at the Lisp '>' prompt, type (bye) or, more simply, enter C-d. Note that, in Emacs, C-d means "delete", but to the Lisp interpreter, as with most Unix programs, C-d means "end-of-file", which will usually halt input loops such as that used by the Lisp interpreter.

Loading an Existing Program

To load a Lisp program into the interpreter (all at once, not one S-expression at a time), start Emacs, start the Lisp interpreter with the command

M-x run-lisp

then tell Emacs to read a file and redirect it to the Lisp interpreter:

C-c C-l

You will be prompted to enter a filename in the minibuffer. The TAB key is useful for autocompletion of the filename in the minibuffer, so you don't have to type the whole filename.

Alternatively, you can tell the Lisp interpreter directly to load (and interpret) a file: with your cursor positioned after Lisp's '>' prompt, type

(load "test.lisp")
(substituting the actual filename for "test.lisp", of course). The disadvantage of this method is that you can't use autocompletion, so you have to know the exact name of the file and type it correctly.

Note that either of the previous methods loads a previously written Lisp program into the Lisp interpreter, but does not load it into an editing window for you to make changes in the program. If you also want to edit the program, you can open it in a new window with

C-x C-f

If you revise a particular function in your program, be sure to send the new definition to the Lisp interpreter with

C-M-x

Alternatively, you could load the program when you start Emacs, then split the screen, start the Lisp interpreter, and load the program into the interpreter with the command sequence:

emacs test.lisp

C-x 2

M-x run-lisp

C-c C-l

Yet another alternative is to replace the last line above with

M-x eval-current-buffer

but that probably takes more typing than re-entering the filename.

Using Regions in Emacs

Emacs supports the concept of a region: a section of text which is marked for special editing by subsequent commands.

To mark a region, place your cursor at the start of the region and set a mark at that spot by entering C-space (i.e., hold the Ctrl key and press the space bar). Now move the cursor to the end of the region you wish to define and enter a command which operates on a region.

For example, C-w cuts the region, copying it to the Emacs equivalent of the clipboard; it can be pasted at another spot in the document with a subsequent C-y. Alternatively, you could copy the text in a region to the clipboard with M-w, then paste it with C-y.

You can also send the contents of the region to the Lisp interpreter with

M-x eval-region

This might be useful if you have changed several functions and want to send the new definitions to the Lisp interpreter all at once.

This also suggests another way to have the Lisp interpreter evaluate an entire file at once. After starting Emacs and loading and editing your Lisp program, start the Lisp interpreter with M-x run-lisp, then mark the entire buffer as a region (press C-space at the top of the file, then move to the bottom of the file with M->), and sent the region to the Lisp interpreter with M-x eval-region.

Copyright © 2001 Jonathan Mohr