]> git.eshelyaron.com Git - emacs.git/commitdiff
Add treesit-node-top-level
authorYuan Fu <casouri@gmail.com>
Sat, 29 Oct 2022 21:11:52 +0000 (14:11 -0700)
committerYuan Fu <casouri@gmail.com>
Sat, 29 Oct 2022 21:47:05 +0000 (14:47 -0700)
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
lisp/progmodes/js.el
lisp/treesit.el

index fe51222e9bc9ef3cdfd909a976bafc14826c9998..524b81a2bbd5353cf75aa53400afbbc454927dbd 100644 (file)
@@ -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
index d6ec3199abf5630968678663e90a1658856e24dd..8d1cfbd3c0e331528d05c581cb029ed915e13eff 100644 (file)
@@ -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))
index 6176fb57ef6e42c0a823dc2fac9f69a56be508e9..027f5ecb77dd45ebc501a08243dd237608d91c18 100644 (file)
@@ -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