Evil 有効下で paredit-forward/backward をちゃんと動くようにする


背景

Emacs でS式を書く時には ParEdit がとても便利ですが、Evil と併用すると paredit-forwardparedit-backward が上手く動いてくれません。カッコとカーソルとの相対的な位置関係が素の Emacs と Evil で異なるためですが、これを気にしながら Lisp を書くのは無駄に疲れるので挙動を修正します。

既に evil-paredit.el は存在していますが、paredit-forwardparedit-backward に関しては考慮されていないようです(たぶん)。

コード

;; Evil compatibility fix
(defun evil-end-of-line-p ()
  (let ((offset (if (evil-emacs-state-p)
                    0
                  1)))
    (eq (- (line-end-position) offset) (point))))

(defun evil-paredit-forward (origfun arg)
  (funcall origfun)
  (unless (evil-emacs-state-p)
    (backward-char)))

(defun evil-paredit-backward (origfun arg)
  (if (evil-end-of-line-p)
      (forward-line)
    (forward-char))
  (funcall origfun))

(advice-add 'paredit-forward :around #'evil-paredit-forward)
(advice-add 'paredit-backward :around #'evil-paredit-backward)

やっていること

基本的にはparedit-forwardした後に1文字戻り、paredit-backwardする前に1文字進むようにするだけです。ただし、Evil の Normal State でカーソルが行末にある時に1文字進もうとするとエラーが出てしまうので、行末かどうかを判定してから、行末であれば次行の先頭に、そうでなければ次の文字にカーソルを移動させるようにしています。