Function: treesit-search-forward

treesit-search-forward is a function defined in treesit.c.

Signature

(treesit-search-forward START PREDICATE &optional BACKWARD ALL)

Documentation

Search for node matching PREDICATE in the parse tree of START.

Start traversing the tree from node START, and match PREDICATE with each node (except START itself) 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 search for named nodes, but if ALL is non-nil, search for all nodes. If BACKWARD is non-nil, search backwards.

Return the first matched node, or nil if none matches.

For a tree like below, where START is marked by S, traverse as numbered from 1 to 12:

                12
                |
       S--------3----------11
       | | |
  o--o-+--o 1--+--2 6--+-----10
  | | | |
  o o +-+-+ +--+--+
                      | | | | |
                      4 5 7 8 9

Note that this function doesn't traverse the subtree of START, and it always traverse leaf nodes first, then upwards.

Other relevant functions are documented in the treesit group.

View in manual

Probably introduced at or before Emacs version 30.1.

Shortdoc

;; treesit
(treesit-search-forward 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 (start);
  CHECK_SYMBOL (all);
  CHECK_SYMBOL (backward);

  treesit_initialize ();

  Lisp_Object parser = XTS_NODE (start)->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 (start)->node, parser))
    return return_value;

  specpdl_ref count = SPECPDL_INDEX ();
  record_unwind_protect_ptr (treesit_traverse_cleanup_cursor, &cursor);

  if (treesit_search_forward (&cursor, predicate, parser,
			      NILP (backward), NILP (all)))
    {
      TSNode node = ts_tree_cursor_current_node (&cursor);
      return_value = make_treesit_node (parser, node);
    }

  return unbind_to (count, return_value);
}