HomeMathComputingArtsWordsLiteratureMusictwitter facebook webfeed

How to Edit Lisp Code with Emacs

Advertise Here For Profit

Xah Lee, 2007-12, 2009-11-05, 2010-08-13

This page gives you some tips about editing emacs lisp code in emacs. Most tips will also apply to editing Scheme, Clojure, newLISP, or code with many nested matching pairs.

Convenient Highlighting Setup

Put the following code in your “.emacs”:

; highlight text selection (active region) (on by default in emacs 23)
(transient-mark-mode 1)

; make typing overwrite text selection
(setq delete-selection-mode 1) ; this turns on transient-mark-mode automatically

For modes, by convention, argument of 1 is to turn on, 0 is off. Do NOT use “nil”. (For detail, see: Emacs: How to Turn a Minor Mode on/off/toggle?)

To see your emacs version, type 【Alt+x version】.

Show Paren Mode

You also want to turn on Paren Match Highlighting.

; turn on highlight matching parens when cursor is on one
(show-paren-mode 1)

show-paren-mode has 2 styles of highlighting parens.

emacs show-paren-mode 1

Highligh just the parens.

emacs show-paren-mode 2

Highligh the whole expression.

By default, emacs highlight just the parens. You can change it with the following code:

(setq show-paren-style 'parenthesis) ; highlight just parens
(setq show-paren-style 'expression) ; highlight entire expression

Also, you can change the default background color for highlighting the paren. You can do so by typing 【Alt+x customize-face Enter show-paren-match Enter】. Then, move your cursor to the “Attributes” section, “Background” item, in the value section type “azure2” replacing the default “turquoise”. Then, click the button “Save for Future Sessions” at the top. This will save the lisp code in your emacs init file. For example, the following shows in my emacs init file:

;'(show-paren-match ((((class color) (background light)) (:background "azure2"))))
;

To see a list of available colors and their names, type 【Alt+x list-colors-display】.

Navigating Nested Code

Lisp code with its nested parenthesis syntax represents a tree structure. Emacs has several commands that are very helpful in moving around nested syntax, analogous to navigating a tree. The following is a table showing their shortcuts, names, and purpose. (For historical reasons, lisp code units are sometimes called “sexp”, short for Symbolic EXPression.)

Shortcut Command name Purpose
Ctrl+Alt+ backward-sexp Move to previous sibling
(move to the (beginning of) previous sexp unit)
Ctrl+Alt+ forward-sexp Move to next sibling
(move to the (end of) next sexp unit)
Ctrl+Alt+ backward-up-list Move to parent
(move to the (beginning of) outer paren pair)
Ctrl+Alt+ down-list Move to first child
(move into the (beginning of) first inner paren pair)

The following is a lisp code layed out in a way to show its tree structure. You should try the above commands on it. It is very helpful to understand how sexp corresponds to a tree, and how the commands move the cursor exactly.

( defun
  fold
  "Applies (f x ele) recursively to the list li …"
  (f x li)
  ( let
    (
      (li2 li)
      (ele)
      (x2 x)
    )
    (while
      (setq ele (pop li2))
      (setq x2 (funcall f x2 ele))
    )
    x2
  )
)

Place your cursor at the beginning of the left bracket. Now, try to move your cursor, by using only the tree-walking commands, to the “pop”, then move it to “let”, then “funcall”.

Moving To Previous/Next Sibling That Has Children

The commands “backward-sexp” and “forward-sexp” moves to the previous or next sibling of the sexp the current cursor is on. For example, if you have “(a (b) c d (e f))” and your cursor is on end paren of “(b)”, then, “forward-sexp” will move it to “c”, and do it again will move it to “d”, then end paren of “(e f)”. Occationally, you want to move to the next sibling that has a branch. For example, if you are at the end of “(b)” and you want to move it to next paren pair the “(e f)”, you can then use “backward-list” and “forward-list”.

Selecting A Sexp Unit

You can use the command “mark-sexp” 【Ctrl+Alt+Space】 to select a complete sexp. However, your cursor should be at the beginning of the unit. To select a complete sexp, type 【Ctrl+Alt+】 then 【Ctrl+Alt+Space】.

Typing Parenthesis By Pairs

The matching pairs “(){}[]” are typed by the weak 4th and 5th fingers. It is convenient to move them under the home row, and also to type them always in pairs. Here's the code:

(global-set-key (kbd "H-s") (lambda () (interactive) (insert "[]") (backward-char 1)))
(global-set-key (kbd "H-d") (lambda () (interactive) (insert "()") (backward-char 1)))
(global-set-key (kbd "H-f") (lambda () (interactive) (insert "{}") (backward-char 1)))

The “H” in the above code means the Hyper key. You can make your PC's Menu key as Hyper, or your Mac's Option key as Hyper. See: Emacs: How to define Super & Hyper Keys.

blog comments powered by Disqus