6

When writing Emacs Lisp code, I use forward-sexp (C-M-right) and backward-sexp (C-M-left) to navigate the buffer. However, in some cases these functions stops with error like:

forward-sexp: Scan error: "Containing expression ends prematurely"

Here is an example:

(defun my-test1()
  (message "ok1"))

(defun my-test2()
  (message "ok2"))

If cursor is on the first (, pressing C-M-right twice works fine. However, if cursor is on the first d (in defun), pressing C-M-right five times results in the error. Instead of the error, I would like to move further down the buffer to the next defun that is to the start of the line (defun my-test2()..

Håkon Hægland
  • 3,608
  • 1
  • 20
  • 51
  • 1
    That's the behavior of `lispy-forward` and `lispy-backward` from https://github.com/abo-abo/lispy – abo-abo Feb 04 '15 at 08:21

2 Answers2

4

You can hit C-M-e twice then C-M-a once to move to the beginning of the next defun, from anywhere in the current defun (those key bindings navigate across whole defuns).

Other than that, you probably want to get into Paredit (or SmartParens), for editing s-expressions. (The C-M-f of Paredit does not behave exactly the way you describe, but will skip the closing paren.) Read a short into and try to get the hang of Paredit; it will be immensely beneficial in the long run.

TaylanKammer
  • 626
  • 5
  • 5
  • 1
    If you do this a lot you could wrap it as a command: `(defun next-defun () (interactive) (end-of-defun 2) (beginning-of-defun))` – glucas Feb 04 '15 at 15:17
2

You can use C-M-u (backward-up-list) to move up a level of parentheses.

In your example, with point on the first d, you could use:

C-M-u C-M-f C-M-f

Or, if your instincts have you always hitting C-M-f first, you can go forward until you get the scan error; then go up, then go forward again.

glucas
  • 20,175
  • 1
  • 51
  • 83
  • Thanks @glucas. I tried `C-h m` when in `elisp-mode` but it only showed keys defined in `lisp-mode.el`. Typing `C-h k RET C-M-u` showed that `C-M-u` was defined in `lisp.el` (not `lisp-mode.el`).. so that was the reason I could not find the shortcuts myself.. How to get the other keyboard shortcuts (defined in `lisp.el`) ? – Håkon Hægland Feb 04 '15 at 17:23
  • 1
    Hmm, you're right. With `C-h m` you get the list of keys in the current major mode map; but `C-M-u` is actually in the global map. You can use `C-h b` to see all the keys that are currently bound, although that can be a big list to search through... – glucas Feb 04 '15 at 18:27
  • 1
    By the way, you should take a look at the Emacs Manual section [Commands for Editing with Parentheses](https://www.gnu.org/software/emacs/manual/html_node/emacs/Parentheses.html) which covers this set of commands. – glucas Feb 04 '15 at 18:38