Paredit and Evil: Improving Navigation

2025-11-30

If...

  • ...you are an Emacs user

  • who also uses evil

  • and is having a hard time getting paredit navigation to work,

  • this post is for you.

The Most Important Setting

First make sure evil-move-beyond-eol is true.

;; Many paredit navigation commands won't work without this!
(setq evil-move-beyond-eol t)

Unfortunately, it is a departure from traditional vi/vim behavior that some of you may not like. To limit this behavior to only when you're using paredit-mode, you could do something like this.

(defun enable-evil-move-beyond-eol ()
  "Enable `evil-move-beyond-eol' in a buffer-local way."
  (setq-local evil-move-beyond-eol t))
  
;; My preference is to used named functions in hooks,
;; because it makes removal easier.
(add-hook 'paredit-mode-hook #'enable-evil-move-beyond-eol)

I personally don't mind and do it the first way, but you have options.

Improving Navigation Keybindings

Paredit provides the following navigation commands.

commandkeykeycommand
paredit-forwardC-M-fC-M-bparedit-backward
paredit-forward-upC-M-nC-M-pparedit-backward-down
paredit-forward-downC-M-dC-M-uparedit-backward-up

There are two dimensions of movement here:

  • forward and backward and

  • up and down.

For the commands that move in two dimensions, the mnemonics used by the existing keybindings struggle to capture both dimensions at once. However, vi-style editing has a long tradtion of using ([{}]) for forward and backward movement, so forward and backward directionality is already solved. The only thing left to solve is encoding up and down.

  • [] will be used for downard movement, because I think it's more common to move down into a sexp.

  • {} will be used for upward movement. This requires the SHIFT key.

commandkeykeycommand
paredit-forward()paredit-backward
paredit-forward-up[]paredit-backward-down
paredit-forward-down{}paredit-backward-up
Meow users could try something similar and gain similar benefits.
;; Integrate paredit navigation commands in a vi style.
(evil-define-key '(normal visual) paredit-mode-map
  ;;  paredit function                    overriden evil function
  ;;  ----------------                    -----------------------
  ")" #'paredit-forward                 ; evil-forward-sentence-begin
  "(" #'paredit-backward                ; evil-backward-sentence-begin
  "]" #'paredit-forward-down            ; evil-forward-section-begin
  "[" #'paredit-backward-down           ; evil-backward-section-begin
  "}" #'paredit-forward-up              ; evil-forward-paragraph
  "{" #'paredit-backward-up             ; evil-backward-paragraph
  )

The trade-off is that some traditional evil movement commands had to be unbound, but I think it's a sacrifice worth making in a Lisp editing context. After all, you're working with (sexps) not sentences and paragraphs.

I would like evil users to try this out, and see how it feels. I think you'll find it very intuitive and compatible with vi-style movement. It should make lisp programming a little more enjoyable too.

Happy Lisp Hacking

CC BY-SA 4.0 @g-gundam. Last modified: November 30, 2025. Website built with Franklin.jl and the Julia programming language.