lispyville
lispyville copied to clipboard
Evil navigation
Hello. First of all, thanks for this amazing package!
I'm personally used to a navigation in normal and visual state where backward-sexp
is analogous to evil-backward-word-begin
and forward-sexp
is analogous to evil-forward-word-end
. To elaborate, I want:
abc def
^ >
(abc def) ghi
^ >
(abc def) ghi
^ >
where ^
is the current position of the point and >
is where the point should be after the forward-sexp
operation. Similarly, I want:
abc def
< ^
ghi (abc def)
< ^
ghi (abc def)
< ^
where ^
is the current position of the point and <
is where the point should be after the backward-sexp
operation.
IIUC, none of the functionalities that lispyville provides does something like this, due to the off-by-one error from the mismatch between Emacs's point system and Vim's point system. Therefore, I wrote my own:
(defun significantp (old-point new-point)
(not (or (equal old-point new-point)
(equal (1+ old-point) new-point))))
(evil-define-motion my/lispyville-forward-sexp (count)
"This is an evil motion equivalent of `forward-sexp'."
(let ((original-point (point)))
(when (nth 3 (syntax-ppss))
(forward-char))
(condition-case nil
(forward-sexp (or count 1))
(error nil))
(unless (significantp original-point (point))
(goto-char (1+ original-point))
(condition-case nil
(forward-sexp (or count 1))
(error nil)))
(backward-char)))
(evil-define-motion my/lispyville-backward-sexp (count)
"This is an evil motion equivalent of `backward-sexp'."
(let ((original-point (point)))
(when (nth 3 (syntax-ppss (1+ (point))))
(backward-char))
(condition-case nil
(backward-sexp (or count 1))
(error nil))
(unless (significantp original-point (point))
(goto-char original-point)
(condition-case nil
(backward-sexp (or count 1))
(error nil)))))
If you think it's useful, feel free to adapt it. Any suggestion would be appreciated, too!