emacs-diffs
[Top][All Lists]
Advanced

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

feature/tree-sitter da87895df2 2/4: Add treesit-node-top-level


From: Yuan Fu
Subject: feature/tree-sitter da87895df2 2/4: Add treesit-node-top-level
Date: Sat, 29 Oct 2022 17:52:17 -0400 (EDT)

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

    Add treesit-node-top-level
    
    Merge treesit-node-top-level-p and treesit--find-top-level-match into
    treesit-node-top-level.
    
    * doc/lispref/parsing.texi (Retrieving Node): Add manual entry for it.
    * lisp/progmodes/js.el (js--treesit-imenu-1): Replace
    treesit-node-top-level-p with treesit-node-top-level.
    * lisp/treesit.el (treesit-node-top-level-p)
    (treesit--find-top-level-match): Remove functions.
    (treesit-node-top-level): New function.
    * lisp/treesit.el (treesit-beginning-of-defun)
    (treesit-end-of-defun): Replace treesit--find-top-level-match with
    treesit-node-top-level.
---
 doc/lispref/parsing.texi | 10 ++++++++
 lisp/progmodes/js.el     |  3 ++-
 lisp/treesit.el          | 61 +++++++++++++++++++++---------------------------
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index fe51222e9b..524b81a2bb 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -782,6 +782,16 @@ takes a node as the argument.  That is, this function 
returns the
 farthest parent that still satisfies @var{predicate}.
 @end defun
 
+@defun treesit-node-top-level node &optional type
+This function returns the highest parent of @var{node} that has the
+same type as @var{node}.  If no such parent exists, it returns
+@code{nil}.  Therefore this function is also useful for testing
+whether @var{node} is top-level.
+
+If @var{type} is non-@code{nil}, this function matches each parent's
+type with @var{type} as a regexp, rather than using @var{node}'s type.
+@end defun
+
 @node Accessing Node Information
 @section Accessing Node Information
 @cindex information of node, syntax trees
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index d6ec3199ab..8d1cfbd3c0 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3670,8 +3670,9 @@ definition*\"."
     (cond
      ((null ts-node)
       subtrees)
+     ;; Don't included non-top-level variable declarations.
      ((and (eq type 'variable)
-           (not (treesit-node-top-level-p ts-node)))
+           (treesit-node-top-level ts-node))
       nil)
      (subtrees
       (let ((parent-label (js--treesit-imenu-label type name))
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 6176fb57ef..027f5ecb77 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -246,21 +246,21 @@ that language in the current buffer, and use that."
                 (treesit-buffer-root-node parser-or-lang))))
     (treesit-node-descendant-for-range root beg (or end beg) named)))
 
-(defun treesit-node-top-level-p (node &optional type)
-  "Return non-nil if NODE is top-level, and nil otherwise.
-Being top-level means there is no parent of NODE that has the
-same type.
-
-If TYPE is non-nil, match each parent's type with TYPE as a regexp."
-  (when node
-    (catch 'term
-      (let ((plain-type (treesit-node-type node)))
-        (while (setq node (treesit-node-parent node))
-          (when (if type
-                    (string-match-p type (treesit-node-type node))
-                  (equal (treesit-node-type node) plain-type))
-            (throw 'term nil))))
-      t)))
+(defun treesit-node-top-level (node &optional type)
+  "Return the top-level equivalent of NODE.
+Specifically, return the highest parent of NODE that has the same
+type as it.  If no such parent exists, return nil.
+
+If TYPE is non-nil, match each parent's type with TYPE as a
+regexp, rather than using NODE's type."
+  (let ((type (or type (treesit-node-type node)))
+        (result nil))
+    (cl-loop for cursor = (treesit-node-parent node)
+             then (treesit-node-parent cursor)
+             while cursor
+             if (string-match-p type (treesit-node-type cursor))
+             do (setq result cursor))
+    result))
 
 (defun treesit-buffer-root-node (&optional language)
   "Return the root node of the current buffer.
@@ -1162,17 +1162,6 @@ For example, \"(function|class)_definition\".
 
 This is used by `treesit-beginning-of-defun' and friends.")
 
-(defun treesit--find-top-level-match (node type)
-  "Return the top-level parent of NODE matching TYPE.
-TYPE is a regexp, this function matches TYPE with each parent's
-type."
-  (cl-loop for cursor = (treesit-node-parent node)
-           then (treesit-node-parent cursor)
-           while cursor
-           if (string-match-p type (treesit-node-type cursor))
-           do (setq node cursor)
-           finally return node))
-
 (defun treesit-beginning-of-defun (&optional arg)
   "Tree-sitter `beginning-of-defun' function.
 ARG is the same as in `beginning-of-defun'."
@@ -1183,15 +1172,17 @@ ARG is the same as in `beginning-of-defun'."
         (while (and (> arg 0)
                     (setq node (treesit-search-forward-goto
                                 node treesit-defun-type-regexp t t)))
-          (setq node (treesit--find-top-level-match
-                      node treesit-defun-type-regexp))
+          (setq node (or (treesit-node-top-level
+                          node treesit-defun-type-regexp)
+                         node))
           (setq arg (1- arg)))
       ;; Go forward.
       (while (and (< arg 0)
                   (setq node (treesit-search-forward-goto
                               node treesit-defun-type-regexp)))
-        (setq node (treesit--find-top-level-match
-                    node treesit-defun-type-regexp))
+        (setq node (or (treesit-node-top-level
+                        node treesit-defun-type-regexp)
+                       node))
         (setq arg (1+ arg))))
     (when node
       (goto-char (treesit-node-start node))
@@ -1201,10 +1192,12 @@ ARG is the same as in `beginning-of-defun'."
   "Tree-sitter `end-of-defun' function."
   ;; Why not simply get the largest node at point: when point is at
   ;; (point-min), that gives us the root node.
-  (let ((node (treesit--find-top-level-match
-               (treesit-node-at (point))
-               treesit-defun-type-regexp)))
-    (goto-char (treesit-node-end node))))
+  (let* ((node (treesit-node-at (point)))
+         (top (or (treesit-node-top-level
+                   node
+                   treesit-defun-type-regexp)
+                  node)))
+    (goto-char (treesit-node-end top))))
 
 ;;; Imenu
 



reply via email to

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