aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2022-10-29 14:11:52 -0700
committerYuan Fu2022-10-29 14:47:05 -0700
commitda87895df2d6b21468b187f5a4e2ca8710e35ee7 (patch)
tree7ff85558a6b0d445f15fe3620df45746d9905119
parentbaacad1771e3551ffdb1b88c41224fa1957e766c (diff)
downloademacs-da87895df2d6b21468b187f5a4e2ca8710e35ee7.tar.gz
emacs-da87895df2d6b21468b187f5a4e2ca8710e35ee7.zip
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.
-rw-r--r--doc/lispref/parsing.texi10
-rw-r--r--lisp/progmodes/js.el3
-rw-r--r--lisp/treesit.el61
3 files changed, 39 insertions, 35 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index fe51222e9bc..524b81a2bbd 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
782farthest parent that still satisfies @var{predicate}. 782farthest parent that still satisfies @var{predicate}.
783@end defun 783@end defun
784 784
785@defun treesit-node-top-level node &optional type
786This function returns the highest parent of @var{node} that has the
787same type as @var{node}. If no such parent exists, it returns
788@code{nil}. Therefore this function is also useful for testing
789whether @var{node} is top-level.
790
791If @var{type} is non-@code{nil}, this function matches each parent's
792type with @var{type} as a regexp, rather than using @var{node}'s type.
793@end defun
794
785@node Accessing Node Information 795@node Accessing Node Information
786@section Accessing Node Information 796@section Accessing Node Information
787@cindex information of node, syntax trees 797@cindex information of node, syntax trees
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index d6ec3199abf..8d1cfbd3c0e 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3670,8 +3670,9 @@ definition*\"."
3670 (cond 3670 (cond
3671 ((null ts-node) 3671 ((null ts-node)
3672 subtrees) 3672 subtrees)
3673 ;; Don't included non-top-level variable declarations.
3673 ((and (eq type 'variable) 3674 ((and (eq type 'variable)
3674 (not (treesit-node-top-level-p ts-node))) 3675 (treesit-node-top-level ts-node))
3675 nil) 3676 nil)
3676 (subtrees 3677 (subtrees
3677 (let ((parent-label (js--treesit-imenu-label type name)) 3678 (let ((parent-label (js--treesit-imenu-label type name))
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 6176fb57ef6..027f5ecb77d 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -246,21 +246,21 @@ that language in the current buffer, and use that."
246 (treesit-buffer-root-node parser-or-lang)))) 246 (treesit-buffer-root-node parser-or-lang))))
247 (treesit-node-descendant-for-range root beg (or end beg) named))) 247 (treesit-node-descendant-for-range root beg (or end beg) named)))
248 248
249(defun treesit-node-top-level-p (node &optional type) 249(defun treesit-node-top-level (node &optional type)
250 "Return non-nil if NODE is top-level, and nil otherwise. 250 "Return the top-level equivalent of NODE.
251Being top-level means there is no parent of NODE that has the 251Specifically, return the highest parent of NODE that has the same
252same type. 252type as it. If no such parent exists, return nil.
253 253
254If TYPE is non-nil, match each parent's type with TYPE as a regexp." 254If TYPE is non-nil, match each parent's type with TYPE as a
255 (when node 255regexp, rather than using NODE's type."
256 (catch 'term 256 (let ((type (or type (treesit-node-type node)))
257 (let ((plain-type (treesit-node-type node))) 257 (result nil))
258 (while (setq node (treesit-node-parent node)) 258 (cl-loop for cursor = (treesit-node-parent node)
259 (when (if type 259 then (treesit-node-parent cursor)
260 (string-match-p type (treesit-node-type node)) 260 while cursor
261 (equal (treesit-node-type node) plain-type)) 261 if (string-match-p type (treesit-node-type cursor))
262 (throw 'term nil)))) 262 do (setq result cursor))
263 t))) 263 result))
264 264
265(defun treesit-buffer-root-node (&optional language) 265(defun treesit-buffer-root-node (&optional language)
266 "Return the root node of the current buffer. 266 "Return the root node of the current buffer.
@@ -1162,17 +1162,6 @@ For example, \"(function|class)_definition\".
1162 1162
1163This is used by `treesit-beginning-of-defun' and friends.") 1163This is used by `treesit-beginning-of-defun' and friends.")
1164 1164
1165(defun treesit--find-top-level-match (node type)
1166 "Return the top-level parent of NODE matching TYPE.
1167TYPE is a regexp, this function matches TYPE with each parent's
1168type."
1169 (cl-loop for cursor = (treesit-node-parent node)
1170 then (treesit-node-parent cursor)
1171 while cursor
1172 if (string-match-p type (treesit-node-type cursor))
1173 do (setq node cursor)
1174 finally return node))
1175
1176(defun treesit-beginning-of-defun (&optional arg) 1165(defun treesit-beginning-of-defun (&optional arg)
1177 "Tree-sitter `beginning-of-defun' function. 1166 "Tree-sitter `beginning-of-defun' function.
1178ARG is the same as in `beginning-of-defun'." 1167ARG is the same as in `beginning-of-defun'."
@@ -1183,15 +1172,17 @@ ARG is the same as in `beginning-of-defun'."
1183 (while (and (> arg 0) 1172 (while (and (> arg 0)
1184 (setq node (treesit-search-forward-goto 1173 (setq node (treesit-search-forward-goto
1185 node treesit-defun-type-regexp t t))) 1174 node treesit-defun-type-regexp t t)))
1186 (setq node (treesit--find-top-level-match 1175 (setq node (or (treesit-node-top-level
1187 node treesit-defun-type-regexp)) 1176 node treesit-defun-type-regexp)
1177 node))
1188 (setq arg (1- arg))) 1178 (setq arg (1- arg)))
1189 ;; Go forward. 1179 ;; Go forward.
1190 (while (and (< arg 0) 1180 (while (and (< arg 0)
1191 (setq node (treesit-search-forward-goto 1181 (setq node (treesit-search-forward-goto
1192 node treesit-defun-type-regexp))) 1182 node treesit-defun-type-regexp)))
1193 (setq node (treesit--find-top-level-match 1183 (setq node (or (treesit-node-top-level
1194 node treesit-defun-type-regexp)) 1184 node treesit-defun-type-regexp)
1185 node))
1195 (setq arg (1+ arg)))) 1186 (setq arg (1+ arg))))
1196 (when node 1187 (when node
1197 (goto-char (treesit-node-start node)) 1188 (goto-char (treesit-node-start node))
@@ -1201,10 +1192,12 @@ ARG is the same as in `beginning-of-defun'."
1201 "Tree-sitter `end-of-defun' function." 1192 "Tree-sitter `end-of-defun' function."
1202 ;; Why not simply get the largest node at point: when point is at 1193 ;; Why not simply get the largest node at point: when point is at
1203 ;; (point-min), that gives us the root node. 1194 ;; (point-min), that gives us the root node.
1204 (let ((node (treesit--find-top-level-match 1195 (let* ((node (treesit-node-at (point)))
1205 (treesit-node-at (point)) 1196 (top (or (treesit-node-top-level
1206 treesit-defun-type-regexp))) 1197 node
1207 (goto-char (treesit-node-end node)))) 1198 treesit-defun-type-regexp)
1199 node)))
1200 (goto-char (treesit-node-end top))))
1208 1201
1209;;; Imenu 1202;;; Imenu
1210 1203