]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement treesit-forward-sexp correctly (bug#63487)
authorYuan Fu <casouri@gmail.com>
Fri, 19 May 2023 07:15:21 +0000 (00:15 -0700)
committerYuan Fu <casouri@gmail.com>
Fri, 19 May 2023 07:20:33 +0000 (00:20 -0700)
* lisp/treesit.el (treesit-forward-sexp): Signal scan-error when we
can't move across sexps further.

lisp/treesit.el

index 49eeba64a14d8f84a3fbcca185793fb920c18262..cc7ec97785112bf40c4fda0b1a730eb38d383aae 100644 (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.