From 156973639cc57dec47705f76f63c2ef3dc00a61d Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Fri, 19 May 2023 00:15:21 -0700 Subject: [PATCH] Implement treesit-forward-sexp correctly (bug#63487) * lisp/treesit.el (treesit-forward-sexp): Signal scan-error when we can't move across sexps further. --- lisp/treesit.el | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lisp/treesit.el b/lisp/treesit.el index 49eeba64a14..cc7ec977851 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -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. -- 2.39.2