Function: treesit-search-subtree
treesit-search-subtree is a function defined in treesit.c.
Signature
(treesit-search-subtree NODE PREDICATE &optional BACKWARD ALL DEPTH)
Documentation
Traverse the parse tree of NODE depth-first using PREDICATE.
Traverse the subtree of NODE, and match PREDICATE with each node along the way.
PREDICATE can be a regexp string that matches against each node's
type, a predicate function, and more. See treesit-thing-settings
for the possible predicates. PREDICATE can also be a thing defined in
treesit-thing-settings. Using an undefined thing doesn't raise an
error.
By default, only traverse named nodes, but if ALL is non-nil, traverse all nodes. If BACKWARD is non-nil, traverse backwards. If DEPTH is non-nil, only traverse nodes up to that number of levels down in the tree. If DEPTH is nil, default to 1000.
Return the first matched node, or nil if none matches.
Other relevant functions are documented in the treesit group.
Probably introduced at or before Emacs version 30.1.
Shortdoc
;; treesit
(treesit-search-subtree node "function_definition")
e.g. => #<treesit-node (function_definition) in 57-146>
Source Code
// Defined in /usr/src/emacs/src/treesit.c
{
CHECK_TS_NODE (node);
CHECK_SYMBOL (all);
CHECK_SYMBOL (backward);
/* We use a default limit of 1000. See bug#59426 for the
discussion. */
ptrdiff_t the_limit = TREESIT_RECURSION_LIMIT;
if (!NILP (depth))
{
CHECK_FIXNUM (depth);
the_limit = XFIXNUM (depth);
}
treesit_initialize ();
Lisp_Object parser = XTS_NODE (node)->parser;
Lisp_Object language = XTS_PARSER (parser)->language_symbol;
Lisp_Object signal_data = Qnil;
if (!treesit_traverse_validate_predicate (predicate, language,
&signal_data, 0))
{
Lisp_Object err_symbol = XCAR (signal_data);
Lisp_Object data = XCDR (signal_data);
if (EQ (err_symbol, Qtreesit_predicate_not_found))
return Qnil;
xsignal1 (err_symbol, data);
}
Lisp_Object return_value = Qnil;
TSTreeCursor cursor;
if (!treesit_cursor_helper (&cursor, XTS_NODE (node)->node, parser))
return return_value;
specpdl_ref count = SPECPDL_INDEX ();
record_unwind_protect_ptr (treesit_traverse_cleanup_cursor, &cursor);
if (treesit_search_dfs (&cursor, predicate, parser, NILP (backward),
NILP (all), the_limit, false))
{
TSNode node = ts_tree_cursor_current_node (&cursor);
return_value = make_treesit_node (parser, node);
}
return unbind_to (count, return_value);
}