Paredit and Evil: Improving Navigation

2025-11-30

Who Is This For?

  • 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.

I will show you how evil and paredit can work well together with no extra packages needed.

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 minor 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-backwardC-M-bC-M-fparedit-forward
paredit-backward-downC-M-pC-M-dparedit-forward-down
paredit-backward-upC-M-uC-M-nparedit-forward-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 slightly more common to move down into a sexp.

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

commandkeykeycommand
paredit-backward()paredit-forward
paredit-backword-down[]paredit-forward-down
paredit-backward-up{}paredit-forward-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

See Also

  1. r/emacs - Lisp editing packages - opinions?