@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
@var{node} itself), looking for a node for which @var{predicate}
returns non-@code{nil}. @var{predicate} is a regexp that is matched
down the tree.
@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
parse tree and matches each node with @var{predicate} (except for
@var{start}), where @var{predicate} can be a (case-insensitive) regexp
the buffer that satisfies some condition?''
@end defun
-@defun treesit-search-forward-goto predicate side &optional all backward
-This function moves point to the beginning or end of the next node in
-the buffer that matches @var{predicate}. Arguments @var{predicate},
-@var{all} and @var{backward} are the same as in
-@code{treesit-search-forward}. @var{side} controls on which side of
-the matched node we stop: it can be @code{start} or @code{end}.
-@c FIXME: Wouldn't it be convenient to make SIDE optional argument,
-@c and by default stop and the beginning (or end), whichever happens
-@c most frequently?
+@defun treesit-search-forward-goto predicate &optional start backward all
+This function moves point to the start or end of the next node in
+the buffer that matches @var{predicate}. If @var{start} is
+non-nil, stop at the beginning rather than the end of a node.
+
+Arguments @var{predicate}, @var{backward} and @var{all} are the same
+as in @code{treesit-search-forward}.
@end defun
@defun treesit-induce-sparse-tree root predicate &optional process-fn limit
;;; Search
(defun treesit-search-forward-goto
- (predicate side &optional all backward)
- "Search forward for a node and move to it.
+ (predicate &optional start backward all)
+ "Search forward for a node and move to its end position.
Stops at the first node after point that matches PREDICATE.
PREDICATE can be either a regexp that matches against each node's
returns nil/non-nil for match/no match.
If a node matches, move to that node and return the node,
-otherwise return nil. SIDE controls whether we move to the start
-or end of the matches node, it can be either \\='start or
-\\='end.
+otherwise return nil. If START is non-nil, stop at the
+beginning rather than the end of a node.
-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)))
- (start (point)))
+ (start-pos (point)))
;; 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
;; node as the starting point to traverse the tree. So we try to
;; use the node before point.
(when (and (not node) (eq (point) (point-max)))
(setq node (treesit-node-at (max (1- (point)) (point-min)))))
- ;; When searching forward, it is possible for (point) < start,
- ;; because `treesit-search-forward' goes to parents.
+ ;; When searching forward and stopping at beginnings, or search
+ ;; 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
- (>= (point) start)
- (<= (point) start)))
+ (>= (point) start-pos)
+ (<= (point) start-pos)))
(setq node (treesit-search-forward
- node predicate all backward))
- (if-let ((pos (pcase side
- ('start (treesit-node-start node))
- ('end (treesit-node-end node)))))
+ node predicate backward all))
+ (if-let ((pos (if start
+ (treesit-node-start node)
+ (treesit-node-end node))))
(goto-char pos)))
;; If we made reverse progress, go back to where we started.
(when (if backward
- (>= (point) start)
- (<= (point) start))
- (goto-char start))
+ (>= (point) start-pos)
+ (<= (point) start-pos))
+ (goto-char start-pos))
node))
;;; Navigation
;; Go backward.
(while (and (> arg 0)
(treesit-search-forward-goto
- treesit-defun-type-regexp 'start nil t))
+ treesit-defun-type-regexp t t))
(setq arg (1- arg)))
;; Go forward.
(while (and (< arg 0)
(treesit-search-forward-goto
- treesit-defun-type-regexp 'start))
+ treesit-defun-type-regexp t t))
(setq arg (1+ arg))))))
(defun treesit-end-of-defun ()
"Tree-sitter `end-of-defun' function."
- (treesit-search-forward-goto treesit-defun-type-regexp 'end))
+ (treesit-search-forward-goto treesit-defun-type-regexp))
;;; Imenu
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. */)
- (Lisp_Object node, Lisp_Object predicate, Lisp_Object all,
- Lisp_Object backward, Lisp_Object limit)
+ (Lisp_Object node, Lisp_Object predicate, Lisp_Object backward,
+ Lisp_Object all, Lisp_Object limit)
{
CHECK_TS_NODE (node);
CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate),
Note that this function doesn't traverse the subtree of START, and it
always traverse leaf nodes first, then upwards. */)
- (Lisp_Object start, Lisp_Object predicate, Lisp_Object all,
- Lisp_Object backward)
+ (Lisp_Object start, Lisp_Object predicate, Lisp_Object backward,
+ Lisp_Object all)
{
CHECK_TS_NODE (start);
CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate),