emacs-diffs
[Top][All Lists]
Advanced

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

feature/tree-sitter b2b57eda04 5/5: Extract out treesit-search-forward


From: Yuan Fu
Subject: feature/tree-sitter b2b57eda04 5/5: Extract out treesit-search-forward
Date: Sat, 14 May 2022 01:12:02 -0400 (EDT)

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

    Extract out treesit-search-forward
    
    * lisp/treesit.el (treesit-search-forward, treesit-search-beginning,
    treesit-search-end): New functions.
    (treesit-traverse-defun): Remove function.
    (treesit-beginning-of-defun, treesit-end-of-defun): Replace
    'treesit-traverse-defun' with 'treesit-search-forward' and fiends.
    * test/src/treesit-tests.el: Add reminder for tests.
---
 lisp/treesit.el           | 123 ++++++++++++++++++++++++++++++++--------------
 test/src/treesit-tests.el |   4 +-
 2 files changed, 90 insertions(+), 37 deletions(-)

diff --git a/lisp/treesit.el b/lisp/treesit.el
index 60f375e9d9..1cfdab95ca 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -832,48 +832,95 @@ indentation (target) is in green, current indentation is 
in red."
       (indent-region (point-min) (point-max))
       (diff-buffers source-buf (current-buffer)))))
 
-;;; Navigation
+;;; Search
 
-(defvar-local treesit-defun-query nil
-  "A tree-sitter query that matches function/class definitions.
-Capture names don't matter.  This variable is used by navigation
-functions like `treesit-beginning-of-defun'.")
+(defun treesit-search-forward (pos-fn arg query &optional lang)
+  "Search forward for nodes that matches QUERY.
 
-(defun treesit-traverse-defun (pos-fn arg)
-  "Move forward/backward to the beginning/end of a defun.
+This is a more primitive function, you might want to use
+`treesit-search-beginning' or `treesit-search-end' instead.
 
-Defun is defined according to `treesit-defun-pattern'.  Move
-forward/backward ARG time, positive ARG means go forward,
+QUERY has to capture the node to match.  LANG specifies the
+language in which we search for nodes.  If LANG is nil, use the
+first parser in `treesit-parser-list'.
+
+Move forward/backward ARG times, positive ARG means go forward,
 negative ARG means go backward.
 
-POS-FN can be either `treesit-node-start' or `treesit-node-end'."
-  (unless treesit-defun-query
-    (error "Variable `treesit-defun-query' is unset"))
+POS-FN can be either `treesit-node-start' or `treesit-node-end',
+or any function that takes a node and returns a position.
+
+If search succeeds, stop at the position returned by POS-FN and
+return the matched node.  Return nil if search failed."
   (cl-loop for idx from 1 to (abs arg)
-           for positions =
-           (remove
-            nil
-            (mapcar (lambda (parser)
-                      (if-let ((starting-point (point))
-                               (node (treesit-node-at
-                                      (point) parser t)))
-                          (funcall
-                           pos-fn
-                           (treesit-traverse-forward-depth-first
-                            node
-                            (lambda (node)
-                              (and (not (eq (funcall pos-fn node)
-                                            starting-point))
-                                   (treesit-query-capture
-                                    node treesit-defun-query)))
-                            arg))))
-                    treesit-parser-list))
-           ;; If we can find a defun start, jump to it.
-           if positions do (goto-char (apply #'max positions))
+           for parser = (if lang
+                            (treesit-get-parser-create lang)
+                          (car treesit-parser-list))
+           for node =
+           (if-let ((starting-point (point))
+                    (node (treesit-node-at (point) parser t)))
+               (treesit-traverse-forward-depth-first
+                node
+                (lambda (node)
+                  (and (not (eq (funcall pos-fn node)
+                                starting-point))
+                       (if (> arg 0)
+                           ;; Make sure we move forward.
+                           (> (funcall pos-fn node) starting-point)
+                         ;; Make sure we move backward.
+                         (< (funcall pos-fn node) starting-point))
+                       (cl-loop for cap-node in
+                                (mapcar
+                                 #'cdr
+                                 (treesit-query-capture node query))
+                                if (treesit-node-eq cap-node node)
+                                return t)))
+                arg))
+           for pos = (funcall pos-fn node)
+           ;; If we can find a match, jump to it.
+           if pos do (goto-char pos)
            else return nil
-           if (eq (point) (point-min)) return nil
            ;; Return t to indicate that search is successful.
-           finally return t))
+           finally return node))
+
+(defun treesit-search-beginning (query arg &optional lang)
+  "Search forward for nodes that matches QUERY.
+
+Stops at the beginning of matched node.
+
+QUERY has to capture the node to match.  LANG specifies the
+language in which we search for nodes.  If LANG is nil, use the
+first parser in `treesit-parser-list'.
+
+Move forward/backward ARG times, positive ARG means go forward,
+negative ARG means go backward.
+
+If search succeeds, return the matched node.  Return nil if
+search failed."
+  (treesit-search-forward #'treesit-node-start arg query lang))
+
+(defun treesit-search-end (query arg &optional lang)
+  "Search forward for nodes that matches QUERY.
+
+Stops at the end of matched node.
+
+QUERY has to capture the node to match.  LANG specifies the
+language in which we search for nodes.  If LANG is nil, use the
+first parser in `treesit-parser-list'.
+
+Move forward/backward ARG times, positive ARG means go forward,
+negative ARG means go backward.
+
+If search succeeds, return the matched node.  Return nil if
+search failed."
+  (treesit-search-forward #'treesit-node-end arg query lang))
+
+;;; Navigation
+
+(defvar-local treesit-defun-query nil
+  "A tree-sitter query that matches function/class definitions.
+Capture names don't matter.  This variable is used by navigation
+functions like `treesit-beginning-of-defun'.")
 
 (defun treesit-beginning-of-defun (&optional arg)
   "Move backward to the beginning of a defun.
@@ -881,7 +928,9 @@ POS-FN can be either `treesit-node-start' or 
`treesit-node-end'."
 With ARG, do it that many times.  Negative ARG means move forward
 to the ARGth following beginning of defun.  Defun is defined
 according to `treesit-defun-pattern'."
-  (treesit-traverse-defun #'treesit-node-start (- arg)))
+  (unless treesit-defun-query
+    (error "Variable `treesit-defun-query' is unset"))
+  (treesit-search-beginning treesit-defun-query (- arg)))
 
 (defun treesit-end-of-defun (&optional arg)
   "Move forward to the end of a defun.
@@ -889,7 +938,9 @@ according to `treesit-defun-pattern'."
 With ARG, do it that many times.  Negative ARG means move back to
 ARGth preceding end of defun.  Defun is defined according to
 `treesit-defun-pattern'."
-  (treesit-traverse-defun #'treesit-node-end arg))
+  (unless treesit-defun-query
+    (error "Variable `treesit-defun-query' is unset"))
+  (treesit-search-end treesit-defun-query arg))
 
 ;;; Debugging
 
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index 65b871693d..1b20b86bc9 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -369,7 +369,9 @@
 ;; TODO
 ;; - Functions in treesit.el
 ;; - treesit-load-name-override-list
-;; - treesit-traverse-defun
+;; - treesit-search-forward
+;; - treesit-search-beginning
+;; - treesit-search-end
 ;; - treesit-beginning-of-defun
 ;; - treesit-end-of-defun
 



reply via email to

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