clojure-emacs / clojure-emacs/clojure-ts-mode
`beginning/end-of-defun` doesn't work if point is in docstring or regex
- Dominant language
- Emacs Lisp
- Stars
- 188
- Forks
- 21
- Avg merge
- 12m
- Merged PRs (30d)
- 1
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:
```emacs-lisp
(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.
Contributor guide
Assessment
This issue has not been assessed yet.