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 is a regexp string that matches against each node's type.
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.
PREDICATE can also be a function that takes a node and returns nil/non-nil, but it is slower and more memory consuming than using a regexp.
Other relevant functions are documented in the treesit group.
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);
CHECK_TYPE (STRINGP (predicate) || FUNCTIONP (predicate),
list3 (Qor, Qstringp, Qfunctionp), predicate);
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 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;
}