Emacs: Navigate Lisp Code as Tree

By Xah Lee. Date: . Last updated: .

Lisp code with its nested parenthesis syntax represents a tree structure.

(For historical reasons, lisp code are called “sexp”, short for Symbolic EXPression.)

Emacs has many commands that move cursor in lisp code as if navigating a tree structure.

backward-sexpCtrl+Alt+
Move to (beginning of) previous sibling.

Example:

  • Before: (a (b) ▮c d (e f))
  • After: (a ▮(b) c d (e f))
forward-sexpCtrl+Alt+
Move to (end of) next sibling.

Example:

  • Before: (a (b) ▮c d (e f))
  • After: (a (b) c▮ d (e f))
backward-up-listCtrl+Alt+
Move to (beginning of) parent (outer paren).

Example:

  • Before: (a (b) ▮c d (e f))
  • After: ▮(a (b) c d (e f))
down-listCtrl+Alt+
Move to (beginning of) first child (first inner paren pair).
backward-list
Move to (beginning of) previous sibling that has children.

Example:

  • Before: (a (b) c d▮ (e f))
  • After: (a ▮(b) c d (e f))
forward-list
Move to (end of) next sibling that has children.

Example:

  • Before: (a (b) ▮c d (e f))
  • After: (a (b) c d (e f)▮)

The following is lisp source code laid 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
  (f x li)
  "Applies (f x ele) recursively to the list 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 Ctrl+Alt+arrow, to the “pop” , then move it to “let”, then “funcall”.

💡 TIP: In practice, navigation by tree structure is not that useful. It's much more useful to move cursor to a bracket. See Emacs: Move Cursor to Bracket 🚀

Emacs, Work with Brackets