Description
Expected behavior
Executing C-M-e
(end-of-defun
) or C-M-a
(beginning-of-defun
) from any place inside of a defun navigates to a proper position.
Actual behavior
Point is not moved or moved to some random place inside of a docstring or a regex.
Steps to reproduce the problem
The issue is reproducible only if any of the embedded parsers is enabled (either markdown-inline
or regex
). When end-of-defun
is called Emacs delegates its execution to treesit-end-of-defun
, which tries to operate on "things", but if parser at point is not clojure
it tries to navigate to the end of defun of embedded parser.
It also affects CIDER: currently it's not possible to evaluate form if point is in a docstring, because CIDER uses end-of-defun
internally.
Possible solutions
We can either defun custom clojure-ts-[beginning|end]-of-defun
functions and remap treesit-*
versions or we can add advice before treesit-*
functions to jump out of an embedded node before using an actual navigation command:
(defun clojure-ts--ensure-not-embedded (&rest args)
(when (and (derived-mode-p 'clojure-ts-mode)
(not (equal (treesit-language-at (point)) 'clojure)))
(backward-up-list 1 t)))
(advice-add 'treesit-end-of-defun :before #'clojure-ts--ensure-not-embedded)
(advice-add 'treesit-beginning-of-defun :before #'clojure--ts-ensure-not-embedded)
I tested both options locally, both work fine and solve the issue.