emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/tree-sitter ef6e18a6b9 13/15: Improve treesit-search-forward-got


From: Yuan Fu
Subject: feature/tree-sitter ef6e18a6b9 13/15: Improve treesit-search-forward-goto
Date: Sun, 25 Sep 2022 00:12:00 -0400 (EDT)

branch: feature/tree-sitter
commit ef6e18a6b9ab103f3f076b35100d09cff1687396
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Improve treesit-search-forward-goto
    
    * doc/lispref/parsing.texi (Retrieving Node): Update manual.
    * lisp/treesit.el (treesit-search-forward-goto): Instead of taking a
    node, use the node at point, and make sure we make progress.
---
 doc/lispref/parsing.texi | 29 ++++-------------------------
 lisp/treesit.el          | 35 ++++++++++++++++++++++++-----------
 2 files changed, 28 insertions(+), 36 deletions(-)

diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index 868b9bc074..32fc6a69a5 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -623,33 +623,12 @@ If @var{up} is non-nil, this function will only traverse 
to siblings
 and parents.  In that case, only 1 3 4 8 would be traversed.
 @end defun
 
-@defun treesit-search-forward-goto start predicate side &optional all backward 
up
-For those who want to not only search for a node but also move to it,
-this is the function to use.  Parameter @var{start}, @var{predicate},
-@var{all}, @var{backward}, and @var{up} are the same as in
+@defun treesit-search-forward-goto predicate side &optional all backward up
+This function jumps to the start or end of the next node in buffer
+that matches @var{predicate}.  Parameters @var{predicate}, @var{all},
+@var{backward}, and @var{up} are the same as in
 @code{treesit-search-forward}.  And @var{side} controls which side of
 the matched no do we stop at, it can be @code{'start} or @code{'end}.
-
-Beware of this common pitfall:
-
-@example
-@group
-;; This will not move point forward.
-(while (treesit-search-forward-goto
-        (treesit-node-at (point))
-        "xxx"
-        'start)
-  ...)
-
-;; This is will move point forward.
-(let ((node (treesit-node-at (point))))
-  (while (setq node (treesit-search-forward-goto
-                     node "xxx" 'start))
-    ...))
-@end group
-@end example
-
-The exact reason why is left as an exercise for the reader.
 @end defun
 
 @defun treesit-induce-sparse-tree root predicate &optional process-fn limit
diff --git a/lisp/treesit.el b/lisp/treesit.el
index def2e6259e..001404d88d 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -723,13 +723,13 @@ indentation (target) is in green, current indentation is 
in red."
 ;;; Search
 
 (defun treesit-search-forward-goto
-    (start predicate side &optional all backward up)
-  "Search for node in the parse tree and move point to it.
+    (predicate side &optional all backward up)
+  "Search forward for a node and move to it.
 
-Start traversing the tree from node START, and match PREDICATE with
-each node along the way (except START).  PREDICATE can be either a
-regexp that matches against each node's type, or a function that takes
-a node and returns nil/non-nil for match/no match.
+Stops at the first node after point that matches PREDICATE.
+PREDICATE can be either a regexp that matches against each node's
+type, or a function that takes a node and returns nil/non-nil for
+match/no match.
 
 If a node matches, move to that node and return the node,
 otherwise return nil.  SIDE controls whether we move to the start
@@ -737,11 +737,24 @@ or end of the matches node, it can be either \\='start or
 \\='end.
 
 ALL, BACKWARD, and UP are the same as in `treesit-search-forward'."
-  (when-let ((node (treesit-search-forward
-                    start predicate all backward up)))
-    (pcase side
-      ('start (goto-char (treesit-node-start node)))
-      ('end (goto-char (treesit-node-end node))))
+  (let ((node (treesit-node-at (point)))
+        (start (point)))
+    ;; When searching forward, it is possible for (point) < start,
+    ;; because `treesit-search-forward' goes to parents.
+    (while (and node (if backward
+                         (>= (point) start)
+                       (<= (point) start)))
+      (setq node (treesit-search-forward
+                  node predicate all backward up))
+      (if-let ((pos (pcase side
+                      ('start (treesit-node-start node))
+                      ('end (treesit-node-end node)))))
+          (goto-char pos)))
+    ;; If we made reverse progress, go back to where we started.
+    (when (if backward
+              (>= (point) start)
+            (<= (point) start))
+      (goto-char start))
     node))
 
 ;;; Debugging



reply via email to

[Prev in Thread] Current Thread [Next in Thread]