Function: treesit-induce-sparse-tree
treesit-induce-sparse-tree is a function defined in treesit.c.
Signature
(treesit-induce-sparse-tree ROOT PREDICATE &optional PROCESS-FN DEPTH)
Documentation
Create a sparse tree of ROOT's subtree.
This takes the subtree under ROOT, and combs it so only the nodes that match PREDICATE are left, like picking out grapes on the vine.
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.
For a subtree on the left that consist of both numbers and letters, if PREDICATE is "is letter", the returned tree is the one on the right.
a a a
| | |
+---+---+ +---+---+ +---+---+
| | | | | | | | |
b 1 2 b | | b c d
| | => | | => |
c +--+ c + e
| | | | |
+--+ d 4 +--+ d
| | |
e 5 e
If PROCESS-FN is non-nil, it should be a function of one argument. In that case, instead of returning the matched nodes, pass each node to PROCESS-FN, and use its return value instead.
If non-nil, DEPTH is the number of levels to go down the tree from ROOT. If DEPTH is nil or omitted, it defaults to 1000.
Each node in the returned tree looks like (NODE . (CHILD ...)). The root of this tree might be nil, if ROOT doesn't match PREDICATE.
If no node matches PREDICATE, return nil.
Other relevant functions are documented in the treesit group.
Probably introduced at or before Emacs version 30.1.
Shortdoc
;; treesit
(treesit-induce-sparse-tree node "function_definition")
e.g. => (nil (#<treesit-node (function_definition) in 57-146>) (#<treesit-node (function_definition) in 259-296>) (#<treesit-node (function_definition) in 303-659>))
Source Code
// Defined in /usr/src/emacs/src/treesit.c
{
CHECK_TS_NODE (root);
if (!NILP (process_fn))
CHECK_TYPE (FUNCTIONP (process_fn), Qfunctionp, process_fn);
/* 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 (root)->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 parent = Fcons (Qnil, Qnil);
/* In this function we never traverse above NODE, so we don't need
to use treesit_cursor_helper. */
TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (root)->node);
specpdl_ref count = SPECPDL_INDEX ();
record_unwind_protect_ptr (treesit_traverse_cleanup_cursor, &cursor);
treesit_build_sparse_tree (&cursor, parent, predicate, process_fn,
the_limit, parser);
unbind_to (count, Qnil);
Fsetcdr (parent, Fnreverse (Fcdr (parent)));
if (NILP (Fcdr (parent)))
return Qnil;
else
return parent;
}