Implement treesit-forward-sexp correctly (bug#63487)

* lisp/treesit.el (treesit-forward-sexp): Signal scan-error when we
can't move across sexps further.
This commit is contained in:
Yuan Fu 2023-05-19 00:15:21 -07:00
parent 7ef20e0c81
commit 156973639c
No known key found for this signature in database
GPG key ID: 56E19BC57664A442

View file

@ -1791,12 +1791,28 @@ however, smaller in scope than sentences. This is used by
(defun treesit-forward-sexp (&optional arg)
"Tree-sitter implementation for `forward-sexp-function'.
ARG is described in the docstring of `forward-sexp-function'."
ARG is described in the docstring of `forward-sexp-function'. If
there are no further sexps to move across, signal `scan-error'
like `forward-sexp' does. If point is already at top-level,
return nil without moving point."
(interactive "^p")
(or arg (setq arg 1))
(funcall
(if (> arg 0) #'treesit-end-of-thing #'treesit-beginning-of-thing)
treesit-sexp-type-regexp (abs arg) 'restricted))
(let ((arg (or arg 1))
(pred treesit-sexp-type-regexp))
(or (if (> arg 0)
(treesit-end-of-thing pred (abs arg) 'restricted)
(treesit-beginning-of-thing pred (abs arg) 'restricted))
;; If we couldn't move, we should signal an error and report
;; the obstacle, like `forward-sexp' does. If we couldn't
;; find a parent, we simply return nil without moving point,
;; then functions like `up-list' will signal "at top level".
(when-let* ((parent (nth 2 (treesit--things-around (point) pred)))
(boundary (if (> arg 0)
(treesit-node-child parent -1)
(treesit-node-child parent 0))))
(signal 'scan-error (list "No more sexp to move across"
(treesit-node-start boundary)
(treesit-node-end boundary)))))))
(defun treesit-transpose-sexps (&optional arg)
"Tree-sitter `transpose-sexps' function.