Change function signiture of treesit search functions

Justification: We want to make the SIDE argument in
treesit-search-forward-goto optional, so I changed it to START.
It makes more sense for BACKWARD to follow START so two common
case, search for end forward and beginning backwards are

(treesit-search-forward-goto node pred)
(treesit-search-forward-goto node pred t t)

Then since we swapped BACKWARD and ALL for
treesit-search-forward-goto, it's best to swap them for
treesit-search-forward and treesit-search-subtree, too.  And BACKWARD
will probably be used more frequently than ALL anyway.

* doc/lispref/parsing.texi (Retrieving Node): Resolve FIXME and update
function signitures.
* lisp/treesit.el (treesit-search-forward-goto): Change SIDE to
START, swap BACKWARD and ALL.
(treesit-beginning-of-defun)
(treesit-end-of-defun): Update use of treesit-search-forward-goto
* src/treesit.c (Ftreesit_search_subtree)
(Ftreesit_search_forward): Swap BACKWARD and ALL.
This commit is contained in:
Yuan Fu 2022-10-23 14:56:17 -07:00
parent 6a2399c55e
commit fa9bede36c
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
3 changed files with 39 additions and 36 deletions

View file

@ -633,7 +633,7 @@ is non-@code{nil}, it looks for smallest named child.
@heading Searching for node @heading Searching for node
@defun treesit-search-subtree node predicate &optional all backward limit @defun treesit-search-subtree node predicate &optional backward all limit
This function traverses the subtree of @var{node} (including This function traverses the subtree of @var{node} (including
@var{node} itself), looking for a node for which @var{predicate} @var{node} itself), looking for a node for which @var{predicate}
returns non-@code{nil}. @var{predicate} is a regexp that is matched returns non-@code{nil}. @var{predicate} is a regexp that is matched
@ -650,7 +650,7 @@ must be a number that limits the tree traversal to that many levels
down the tree. down the tree.
@end defun @end defun
@defun treesit-search-forward start predicate &optional all backward @defun treesit-search-forward start predicate &optional backward all
Like @code{treesit-search-subtree}, this function also traverses the Like @code{treesit-search-subtree}, this function also traverses the
parse tree and matches each node with @var{predicate} (except for parse tree and matches each node with @var{predicate} (except for
@var{start}), where @var{predicate} can be a (case-insensitive) regexp @var{start}), where @var{predicate} can be a (case-insensitive) regexp
@ -691,15 +691,13 @@ answering questions like ``what is the first node after @var{start} in
the buffer that satisfies some condition?'' the buffer that satisfies some condition?''
@end defun @end defun
@defun treesit-search-forward-goto predicate side &optional all backward @defun treesit-search-forward-goto predicate &optional start backward all
This function moves point to the beginning or end of the next node in This function moves point to the start or end of the next node in
the buffer that matches @var{predicate}. Arguments @var{predicate}, the buffer that matches @var{predicate}. If @var{start} is
@var{all} and @var{backward} are the same as in non-nil, stop at the beginning rather than the end of a node.
@code{treesit-search-forward}. @var{side} controls on which side of
the matched node we stop: it can be @code{start} or @code{end}. Arguments @var{predicate}, @var{backward} and @var{all} are the same
@c FIXME: Wouldn't it be convenient to make SIDE optional argument, as in @code{treesit-search-forward}.
@c and by default stop and the beginning (or end), whichever happens
@c most frequently?
@end defun @end defun
@defun treesit-induce-sparse-tree root predicate &optional process-fn limit @defun treesit-induce-sparse-tree root predicate &optional process-fn limit

View file

@ -809,8 +809,8 @@ indentation (target) is in green, current indentation is in red."
;;; Search ;;; Search
(defun treesit-search-forward-goto (defun treesit-search-forward-goto
(predicate side &optional all backward) (predicate &optional start backward all)
"Search forward for a node and move to it. "Search forward for a node and move to its end position.
Stops at the first node after point that matches PREDICATE. Stops at the first node after point that matches PREDICATE.
PREDICATE can be either a regexp that matches against each node's PREDICATE can be either a regexp that matches against each node's
@ -818,35 +818,40 @@ type case-insensitively, or a function that takes a node and
returns nil/non-nil for match/no match. returns nil/non-nil for match/no match.
If a node matches, move to that node and return the node, If a node matches, move to that node and return the node,
otherwise return nil. SIDE controls whether we move to the start otherwise return nil. If START is non-nil, stop at the
or end of the matches node, it can be either \\='start or beginning rather than the end of a node.
\\='end.
ALL and BACKWARD are the same as in `treesit-search-forward'." BACKWARD and ALL are the same as in `treesit-search-forward'."
(let ((node (treesit-node-at (point))) (let ((node (treesit-node-at (point)))
(start (point))) (start-pos (point)))
;; Often the EOF (point-max) is a newline, and `treesit-node-at' ;; Often the EOF (point-max) is a newline, and `treesit-node-at'
;; will return nil at that point (which is fair). But we need a ;; will return nil at that point (which is fair). But we need a
;; node as the starting point to traverse the tree. So we try to ;; node as the starting point to traverse the tree. So we try to
;; use the node before point. ;; use the node before point.
(when (and (not node) (eq (point) (point-max))) (when (and (not node) (eq (point) (point-max)))
(setq node (treesit-node-at (max (1- (point)) (point-min))))) (setq node (treesit-node-at (max (1- (point)) (point-min)))))
;; When searching forward, it is possible for (point) < start, ;; When searching forward and stopping at beginnings, or search
;; because `treesit-search-forward' goes to parents. ;; backward stopping at ends, it is possible to "roll back" in
;; position. Take three nodes N1, N2, N3 as an example, if we
;; start at N3, search for forward for beginning, and N1 matches,
;; we would stop at beg of N1, which is backwards! So we skip N1.
;;
;; |<--------N1------->|
;; |<--N2-->| |<--N3-->|
(while (and node (if backward (while (and node (if backward
(>= (point) start) (>= (point) start-pos)
(<= (point) start))) (<= (point) start-pos)))
(setq node (treesit-search-forward (setq node (treesit-search-forward
node predicate all backward)) node predicate backward all))
(if-let ((pos (pcase side (if-let ((pos (if start
('start (treesit-node-start node)) (treesit-node-start node)
('end (treesit-node-end node))))) (treesit-node-end node))))
(goto-char pos))) (goto-char pos)))
;; If we made reverse progress, go back to where we started. ;; If we made reverse progress, go back to where we started.
(when (if backward (when (if backward
(>= (point) start) (>= (point) start-pos)
(<= (point) start)) (<= (point) start-pos))
(goto-char start)) (goto-char start-pos))
node)) node))
;;; Navigation ;;; Navigation
@ -867,17 +872,17 @@ ARG is the same as in `beginning-of-defun."
;; Go backward. ;; Go backward.
(while (and (> arg 0) (while (and (> arg 0)
(treesit-search-forward-goto (treesit-search-forward-goto
treesit-defun-type-regexp 'start nil t)) treesit-defun-type-regexp t t))
(setq arg (1- arg))) (setq arg (1- arg)))
;; Go forward. ;; Go forward.
(while (and (< arg 0) (while (and (< arg 0)
(treesit-search-forward-goto (treesit-search-forward-goto
treesit-defun-type-regexp 'start)) treesit-defun-type-regexp t t))
(setq arg (1+ arg)))))) (setq arg (1+ arg))))))
(defun treesit-end-of-defun () (defun treesit-end-of-defun ()
"Tree-sitter `end-of-defun' function." "Tree-sitter `end-of-defun' function."
(treesit-search-forward-goto treesit-defun-type-regexp 'end)) (treesit-search-forward-goto treesit-defun-type-regexp))
;;; Imenu ;;; Imenu

View file

@ -2503,8 +2503,8 @@ all nodes. If BACKWARD is non-nil, traverse backwards. If LIMIT is
non-nil, only traverse nodes up to that number of levels down in the tree. non-nil, only traverse nodes up to that number of levels down in the tree.
Return the first matched node, or nil if none matches. */) Return the first matched node, or nil if none matches. */)
(Lisp_Object node, Lisp_Object predicate, Lisp_Object all, (Lisp_Object node, Lisp_Object predicate, Lisp_Object backward,
Lisp_Object backward, Lisp_Object limit) Lisp_Object all, Lisp_Object limit)
{ {
CHECK_TS_NODE (node); CHECK_TS_NODE (node);
CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate), CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate),
@ -2563,8 +2563,8 @@ numbered from 1 to 12:
Note that this function doesn't traverse the subtree of START, and it Note that this function doesn't traverse the subtree of START, and it
always traverse leaf nodes first, then upwards. */) always traverse leaf nodes first, then upwards. */)
(Lisp_Object start, Lisp_Object predicate, Lisp_Object all, (Lisp_Object start, Lisp_Object predicate, Lisp_Object backward,
Lisp_Object backward) Lisp_Object all)
{ {
CHECK_TS_NODE (start); CHECK_TS_NODE (start);
CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate), CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate),