Next: , Previous: , Up: Parsing Program Source   [Contents][Index]


37.3 Retrieving Node

Before we continue, lets go over some conventions of tree-sitter functions.

We talk about a node being “smaller” or “larger”, and “lower” or “higher”. A smaller and lower node is lower in the syntax tree and therefore spans a smaller piece of text; a larger and higher node is higher up in the syntax tree, containing many smaller nodes as its children, and therefore spans a larger piece of text.

When a function cannot find a node, it returns nil. And for the convenience for function chaining, all the functions that take a node as argument and returns a node accept the node to be nil; in that case, the function just returns nil.

Nodes are not automatically updated when the associated buffer is modified. And there is no way to update a node once it is retrieved. Using an outdated node throws treesit-node-outdated error.

Retrieving node from syntax tree

Function: treesit-node-at beg end &optional parser-or-lang named

This function returns the smallest node that starts at or after the point. In other words, the start of the node is equal or greater than point.

When parser-or-lang is nil, this function uses the first parser in (treesit-parser-list) in the current buffer. If parser-or-lang is a parser object, it use that parser; if parser-or-lang is a language, it finds the first parser using that language in (treesit-parser-list) and use that.

If named is non-nil, this function looks for a named node only (see named node).

Example:

;; Find the node at point in a C parser's syntax tree.
(treesit-node-at (point) 'c)
    
Function: treesit-node-on beg end &optional parser-or-lang named

This function returns the smallest node that covers the span from beg to end. In other words, the start of the node is less or equal to beg, and the end of the node is greater or equal to end.

Beware that calling this function on an empty line that is not inside any top-level construct (function definition, etc) most probably will give you the root node, because the root node is the smallest node that covers that empty line. Most of the time, you want to use treesit-node-at.

When parser-or-lang is nil, this function uses the first parser in (treesit-parser-list) in the current buffer. If parser-or-lang is a parser object, it use that parser; if parser-or-lang is a language, it finds the first parser using that language in (treesit-parser-list) and use that.

If named is non-nil, this function looks for a named node only (see named node).

Function: treesit-parser-root-node parser

This function returns the root node of the syntax tree generated by parser.

Function: treesit-buffer-root-node &optional language

This function finds the first parser that uses language in (treesit-parser-list) in the current buffer, and returns the root node of that buffer. If it cannot find an appropriate parser, nil is returned.

Once we have a node, we can retrieve other nodes from it, or query for information about this node.

Retrieving node from other nodes

By kinship

Function: treesit-node-parent node

This function returns the immediate parent of node.

Function: treesit-node-child node n &optional named

This function returns the n’th child of node. If named is non-nil, then it only counts named nodes (see named node). For example, in a node that represents a string: "text", there are three children nodes: the opening quote ", the string content text, and the enclosing quote ". Among these nodes, the first child is the opening quote ", the first named child is the string content text.

Function: treesit-node-children node &optional named

This function returns all of node’s children in a list. If named is non-nil, then it only retrieves named nodes.

Function: treesit-next-sibling node &optional named

This function finds the next sibling of node. If named is non-nil, it finds the next named sibling.

Function: treesit-prev-sibling node &optional named

This function finds the previous sibling of node. If named is non-nil, it finds the previous named sibling.

By field name

To make the syntax tree easier to analyze, many language definitions assign field names to child nodes (see field name). For example, a function_definition node could have a declarator and a body.

Function: treesit-child-by-field-name node field-name

This function finds the child of node that has field-name as its field name.

;; Get the child that has "body" as its field name.
(treesit-child-by-field-name node "body")
    

By position

Function: treesit-first-child-for-pos node pos &optional named

This function finds the first child of node that extends beyond pos. “Extend beyond” means the end of the child node >= pos. This function only looks for immediate children of node, and doesn’t look in its grand children. If named is non-nil, it only looks for named child (see named node).

Function: treesit-node-descendant-for-range node beg end &optional named

This function finds the smallest child/grandchild... of node that spans the range from beg to end. It is similar to treesit-node-at. If named is non-nil, it only looks for named child.

Searching for node

Function: treesit-search-subtree node predicate &optional all backward limit

This function traverses the subtree of node (including node), and match predicate with each node along the way. And predicate is a regexp that matches (case-insensitively) against each node’s type, or a function that takes a node and returns nil/non-nil. If a node matches, that node is returned, if no node ever matches, nil is returned.

By default, this function only traverses named nodes, if all is non-nil, it traverses all nodes. If backward is non-nil, it traverses backwards. If limit is non-nil, it only traverses that number of levels down in the tree.

Function: treesit-search-forward start predicate &optional all backward up

This function is somewhat similar to treesit-search-subtree. It also traverse the parse tree and match each node with predicate (except for start), where predicate can be a (case-insensitive) regexp or a function. For a tree like the below where start is marked 1, this function traverses as numbered:

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

Same as in treesit-search-subtree, this function only searches for named nodes by default. But if all is non-nil, it searches for all nodes. If backward is non-nil, it searches backwards.

If up is non-nil, this function will only traverse to siblings and parents. In that case, only 1 3 4 8 would be traversed.

Function: treesit-search-forward-goto predicate side &optional all backward up

This function jumps to the start or end of the next node in buffer that matches predicate. Parameters predicate, all, backward, and up are the same as in treesit-search-forward. And side controls which side of the matched no do we stop at, it can be start or end.

Function: treesit-induce-sparse-tree root predicate &optional process-fn limit

This function creates a sparse tree from root’s subtree.

Basically, it takes the subtree under root, and combs it so only the nodes that match predicate are left, like picking out grapes on the vine. Like previous functions, predicate can be a regexp string that matches against each node’s type case-insensitively, or a function that takes a node and return nil/non-nil.

For example, for a subtree on the left that consist of both numbers and letters, if predicate is “letter only”, 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, instead of returning the matched nodes, this function passes each node to process-fn and uses the returned value instead. If non-nil, limit is the number of levels to go down from root.

Each node in the returned tree looks like (tree-sitter node . (child ...)). The tree-sitter node of the root of this tree will be nil if ROOT doesn’t match pred. If no node matches predicate, return nil.

More convenient functions

Function: treesit-filter-child node pred &optional named

This function finds immediate children of node that satisfies pred.

Function pred takes the child node as the argument and should return non-nil to indicated keeping the child. If named non-nil, this function only searches for named nodes.

Function: treesit-parent-until node pred

This function repeatedly finds the parent of node, and returns the parent if it satisfies pred (which takes the parent as the argument). If no parent satisfies pred, this function returns nil.

Function: treesit-parent-while

This function repeatedly finds the parent of node, and keeps doing so as long as the parent satisfies pred (which takes the parent as the single argument). I.e., this function returns the farthest parent that still satisfies pred.


Next: Accessing Node Information, Previous: Using Tree-sitter Parser, Up: Parsing Program Source   [Contents][Index]