| Title: | Bindings to the 'Tree-Sitter' Parsing Library |
|---|---|
| Description: | A runtime for the 'Tree-sitter' parsing library <https://tree-sitter.github.io/tree-sitter/> that mirrors the API of the 'treesitter' package, so it can serve as a drop-in replacement. Parses source code into concrete syntax trees and updates them incrementally as the source changes. Grammars are supplied by separate packages such as 'treesitter.r', so the runtime itself depends on nothing beyond base R. |
| Authors: | Troy Hernandez [aut, cre] (ORCID: <https://orcid.org/0009-0005-4248-604X>), cornball.ai [cph], Max Brunsfeld [ctb, cph] (tree-sitter C library, bundled under src/tree-sitter), International Business Machines Corporation [cph] (ICU UTF-8 and UTF-16 headers, src/tree-sitter/lib/src/unicode), Unicode, Inc. [cph] (ICU license, src/tree-sitter/lib/src/unicode/LICENSE), Mathias Panzenböck [ctb] (src/tree-sitter/lib/src/portable/endian.h, public domain) |
| Maintainer: | Troy Hernandez <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.2 |
| Built: | 2026-09-17 13:45:16 UTC |
| Source: | https://github.com/cran/bonsaisitter |
Convert a node's descendants to a data frame
## S3 method for class 'tree_sitter_node' as.data.frame(x, row.names = NULL, optional = FALSE, ...)## S3 method for class 'tree_sitter_node' as.data.frame(x, row.names = NULL, optional = FALSE, ...)
x |
A |
row.names |
Ignored. |
optional |
Ignored. |
... |
Ignored. |
A base data frame with columns: type, named, text, start_row, start_col, end_row, end_col, start_byte, end_byte.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- f(1)", treesitter.r::language())) as.data.frame(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- f(1)", treesitter.r::language())) as.data.frame(node) }
Compares a reference scope (e.g. the original Python or torch code) with its port, reporting numeric literals present in one but not the other. Parity tests prove the paths they exercise; this catches the drift they do not – wrong constants, dropped operations, unported branches. Call names are returned too for eyeballing with a noise filter.
audit_translation(reference, port, lang = "r", normalize = TRUE)audit_translation(reference, port, lang = "r", normalize = TRUE)
reference |
Character scalar of reference source. |
port |
Character scalar of the port's source. |
lang |
Language of both ( |
normalize |
Logical; strip |
Numeric literals are normalized by default so 4.0, 4L, and
4 compare equal.
A list: literals_missing (in reference, not port),
literals_extra (in port, not reference), and the full
reference / port extractions.
if (requireNamespace("treesitter.r", quietly = TRUE)) { audit_translation("clamp(x, 1e-10); y * 8", "pmax(x, 1e-10); y * 8") }if (requireNamespace("treesitter.r", quietly = TRUE)) { audit_translation("clamp(x, 1e-10); y * 8", "pmax(x, 1e-10); y * 8") }
x a language?Is x a language?
is_language(x)is_language(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { is_language(treesitter.r::language()) }if (requireNamespace("treesitter.r", quietly = TRUE)) { is_language(treesitter.r::language()) }
x a node?Is x a node?
is_node(x)is_node(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x + 1", treesitter.r::language())) c(is_node(node), is_node("x + 1")) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x + 1", treesitter.r::language())) c(is_node(node), is_node("x + 1")) }
x a parser?Is x a parser?
is_parser(x)is_parser(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { is_parser(parser(treesitter.r::language())) }if (requireNamespace("treesitter.r", quietly = TRUE)) { is_parser(parser(treesitter.r::language())) }
x a query?Is x a query?
is_query(x)is_query(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { is_query(query(treesitter.r::language(), "(identifier) @id")) }if (requireNamespace("treesitter.r", quietly = TRUE)) { is_query(query(treesitter.r::language(), "(identifier) @id")) }
x a tree?Is x a tree?
is_tree(x)is_tree(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { is_tree(text_parse("x <- 1", treesitter.r::language())) }if (requireNamespace("treesitter.r", quietly = TRUE)) { is_tree(text_parse("x <- 1", treesitter.r::language())) }
x a tree cursor?Is x a tree cursor?
is_tree_cursor(x)is_tree_cursor(x)
x |
An object. |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { is_tree_cursor(tree_walk(text_parse("x <- 1", treesitter.r::language()))) }if (requireNamespace("treesitter.r", quietly = TRUE)) { is_tree_cursor(tree_walk(text_parse("x <- 1", treesitter.r::language()))) }
The name of a language
language_name(x)language_name(x)
x |
A |
A single string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { language_name(treesitter.r::language()) }if (requireNamespace("treesitter.r", quietly = TRUE)) { language_name(treesitter.r::language()) }
- language_field_count() is the number of distinct fields.
- language_field_name_for_id() maps a field id to its name.
- language_field_id_for_name() maps a field name to its id.
language_field_count(x) language_field_name_for_id(x, id) language_field_id_for_name(x, name)language_field_count(x) language_field_name_for_id(x, id) language_field_id_for_name(x, name)
x |
A |
id |
A field id. |
name |
A field name. |
Counts and ids as a double; names as a string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_field_count(lang) language_field_name_for_id(lang, language_field_id_for_name(lang, "lhs")) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_field_count(lang) language_field_name_for_id(lang, language_field_id_for_name(lang, "lhs")) }
Language parse states
language_state_count(x) language_next_state(x, state, symbol)language_state_count(x) language_next_state(x, state, symbol)
x |
A |
state |
A parse state id. |
symbol |
A symbol id. |
A single double.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_state_count(lang) node <- tree_root_node(text_parse("x <- 1", lang)) language_next_state(lang, node_parse_state(node), node_grammar_symbol(node)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_state_count(lang) node <- tree_root_node(text_parse("x <- 1", lang)) language_next_state(lang, node_parse_state(node), node_grammar_symbol(node)) }
- language_symbol_count() is the number of distinct node types.
- language_symbol_name() maps a symbol id to its name.
- language_symbol_for_name() maps a name to its symbol id.
language_symbol_count(x) language_symbol_name(x, symbol) language_symbol_for_name(x, name, named = TRUE)language_symbol_count(x) language_symbol_name(x, symbol) language_symbol_for_name(x, name, named = TRUE)
x |
A |
symbol |
A symbol id. |
name |
A node type name. |
named |
Whether to look up the named or anonymous variant. |
Counts and ids as a double; names as a string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_symbol_count(lang) language_symbol_name(lang, language_symbol_for_name(lang, "identifier")) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() language_symbol_count(lang) language_symbol_name(lang, language_symbol_for_name(lang, "identifier")) }
Parses code with tree-sitter and walks the AST collecting every
numeric literal (integer / float) and the callee name of every call. The
building block for audit_translation. Requires the grammar
package for lang (treesitter.r, treesitter.python,
treesitter.cpp, treesitter.go, treesitter.rust, or
treesitter.javascript) to be installed.
literals_and_calls( code, lang = c("r", "python", "cpp", "go", "rust", "javascript") )literals_and_calls( code, lang = c("r", "python", "cpp", "go", "rust", "javascript") )
code |
Character scalar of source code. |
lang |
Language: |
A list with literals and calls (character vectors,
in source order).
if (requireNamespace("treesitter.r", quietly = TRUE)) { literals_and_calls("f(1L, 2.5) + g(3)") }if (requireNamespace("treesitter.r", quietly = TRUE)) { literals_and_calls("f(1L, 2.5) + g(3)") }
A child by field id
node_child_by_field_id(x, id)node_child_by_field_id(x, id)
x |
A |
id |
A field id (see |
A tree_sitter_node, or NULL.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() expr <- node_child(tree_root_node(text_parse("x <- 1", lang)), 1) id <- language_field_id_for_name(lang, "lhs") node_text(node_child_by_field_id(expr, id)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() expr <- node_child(tree_root_node(text_parse("x <- 1", lang)), 1) id <- language_field_id_for_name(lang, "lhs") node_text(node_child_by_field_id(expr, id)) }
A child by field name
node_child_by_field_name(x, name)node_child_by_field_name(x, name)
x |
A |
name |
A field name. |
A tree_sitter_node, or NULL.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) node_text(node_child_by_field_name(expr, "lhs")) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) node_text(node_child_by_field_name(expr, "lhs")) }
The number of descendants of a node
node_descendant_count(x)node_descendant_count(x)
x |
A |
A single double, including the node itself.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_descendant_count(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_descendant_count(node) }
Like node_type, but returns the type as written in the grammar, ignoring
aliases.
node_grammar_type(x)node_grammar_type(x)
x |
A |
A single string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_grammar_type(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_grammar_type(node) }
Is a node named?
node_is_named(x)node_is_named(x)
x |
A |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) vapply(node_children(expr), node_is_named, logical(1)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) vapply(node_children(expr), node_is_named, logical(1)) }
The language of a node
node_language(x)node_language(x)
x |
A |
A tree_sitter_language.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) language_name(node_language(node)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) language_name(node_language(node)) }
A node's range
node_range(x)node_range(x)
x |
A |
A tree_sitter_range.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_range(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_range(node) }
The raw s-expression of a node
node_raw_s_expression(x)node_raw_s_expression(x)
x |
A |
A single string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_raw_s_expression(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_raw_s_expression(node) }
Show a node's s-expression
node_show_s_expression(x)node_show_s_expression(x)
x |
A |
x, invisibly, called for its side effect of printing.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_show_s_expression(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_show_s_expression(node) }
The text underlying a node
node_text(x)node_text(x)
x |
A |
A single string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- f(1)", treesitter.r::language())) node_text(node_child(node, 1)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- f(1)", treesitter.r::language())) node_text(node_child(node, 1)) }
The type of a node
node_type(x)node_type(x)
x |
A |
A single string.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x + 1", treesitter.r::language())) node_type(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x + 1", treesitter.r::language())) node_type(node) }
A node's start / end byte
node_start_byte(x) node_end_byte(x)node_start_byte(x) node_end_byte(x)
x |
A |
A single double (0-indexed).
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) c(node_start_byte(node), node_end_byte(node)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) c(node_start_byte(node), node_end_byte(node)) }
Access a child by index (1-indexed)
node_child(x, i) node_named_child(x, i)node_child(x, i) node_named_child(x, i)
x |
A |
i |
A 1-indexed child position. |
A tree_sitter_node, or NULL.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_type(node_child(expr, 2)), node_type(node_named_child(expr, 2))) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_type(node_child(expr, 2)), node_type(node_named_child(expr, 2))) }
Child counts
node_child_count(x) node_named_child_count(x)node_child_count(x) node_named_child_count(x)
x |
A |
A single double.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_child_count(expr), node_named_child_count(expr)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_child_count(expr), node_named_child_count(expr)) }
All children of a node
node_children(x) node_named_children(x)node_children(x) node_named_children(x)
x |
A |
A list of tree_sitter_nodes.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) vapply(node_children(expr), node_type, character(1)) vapply(node_named_children(expr), node_type, character(1)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) vapply(node_children(expr), node_type, character(1)) vapply(node_named_children(expr), node_type, character(1)) }
Field name for a child (1-indexed)
node_field_name_for_child(x, i) node_field_name_for_named_child(x, i)node_field_name_for_child(x, i) node_field_name_for_named_child(x, i)
x |
A |
i |
A 1-indexed child position. |
A single string, or NA if the child has no field.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_field_name_for_child(expr, 1), node_field_name_for_named_child(expr, 2)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) expr <- node_child(tree_root_node(tree), 1) c(node_field_name_for_child(expr, 1), node_field_name_for_named_child(expr, 2)) }
Locate nodes by byte or point
node_first_child_for_byte(x, byte) node_first_named_child_for_byte(x, byte) node_descendant_for_byte_range(x, start, end) node_named_descendant_for_byte_range(x, start, end) node_descendant_for_point_range(x, start_point, end_point) node_named_descendant_for_point_range(x, start_point, end_point)node_first_child_for_byte(x, byte) node_first_named_child_for_byte(x, byte) node_descendant_for_byte_range(x, start, end) node_named_descendant_for_byte_range(x, start, end) node_descendant_for_point_range(x, start_point, end_point) node_named_descendant_for_point_range(x, start_point, end_point)
x |
A |
byte, start, end
|
0-indexed byte offsets. |
start_point, end_point
|
|
A tree_sitter_node, or NULL.
if (requireNamespace("treesitter.r", quietly = TRUE)) { root <- tree_root_node(text_parse("x <- 1\ny <- 2", treesitter.r::language())) node_text(node_first_named_child_for_byte(root, 7)) node_text(node_descendant_for_byte_range(root, 7, 7)) node_text(node_descendant_for_point_range(root, point(1, 0), point(1, 0))) }if (requireNamespace("treesitter.r", quietly = TRUE)) { root <- tree_root_node(text_parse("x <- 1\ny <- 2", treesitter.r::language())) node_text(node_first_named_child_for_byte(root, 7)) node_text(node_descendant_for_byte_range(root, 7, 7)) node_text(node_descendant_for_point_range(root, point(1, 0), point(1, 0))) }
A node's start / end point
node_start_point(x) node_end_point(x)node_start_point(x) node_end_point(x)
x |
A |
A tree_sitter_point.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1\ny <- 2", treesitter.r::language())) node_start_point(node) node_end_point(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1\ny <- 2", treesitter.r::language())) node_start_point(node) node_end_point(node) }
- node_has_error() is TRUE if the node or any descendant is an error or
is missing.
- node_is_error() is TRUE if the node itself is a syntax error.
- node_is_missing() is TRUE if the node is inserted by the parser to
recover from an error.
- node_is_extra() is TRUE if the node is "extra" (e.g. a comment).
node_has_error(x) node_is_error(x) node_is_missing(x) node_is_extra(x)node_has_error(x) node_is_error(x) node_is_missing(x) node_is_extra(x)
x |
A |
TRUE or FALSE.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() ok <- tree_root_node(text_parse("x <- 1", lang)) broken <- tree_root_node(text_parse("x <- ", lang)) c(node_has_error(ok), node_has_error(broken)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() ok <- tree_root_node(text_parse("x <- 1", lang)) broken <- tree_root_node(text_parse("x <- ", lang)) c(node_has_error(ok), node_has_error(broken)) }
Node symbols and parse states
node_symbol(x) node_grammar_symbol(x) node_parse_state(x) node_next_parse_state(x)node_symbol(x) node_grammar_symbol(x) node_parse_state(x) node_next_parse_state(x)
x |
A |
A single double.
if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_symbol(node) language_symbol_name(node_language(node), node_symbol(node)) node_parse_state(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { node <- tree_root_node(text_parse("x <- 1", treesitter.r::language())) node_symbol(node) language_symbol_name(node_language(node), node_symbol(node)) node_parse_state(node) }
parser() constructs a parser from a tree_sitter_language. Use
parser_parse to parse text with it.
parser(language)parser(language)
language |
A |
A tree_sitter_parser.
if (requireNamespace("treesitter.r", quietly = TRUE)) { p <- parser(treesitter.r::language()) tree <- parser_parse(p, "x <- f(1, 2)") node_type(tree_root_node(tree)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { p <- parser(treesitter.r::language()) tree <- parser_parse(p, "x <- f(1, 2)") node_type(tree_root_node(tree)) }
Each returns a new parser with one setting changed.
- parser_set_language() sets the language.
- parser_set_timeout() sets a parse timeout in microseconds (0 clears it).
- parser_set_included_ranges() restricts parsing to a list of ranges
(an empty list clears the restriction).
parser_set_language(x, language) parser_set_timeout(x, timeout) parser_set_included_ranges(x, included_ranges)parser_set_language(x, language) parser_set_timeout(x, timeout) parser_set_included_ranges(x, included_ranges)
x |
A |
language |
A |
timeout |
A single whole number of microseconds. |
included_ranges |
A list of |
A new tree_sitter_parser.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() p <- parser_set_timeout(parser(lang), 1e6) p <- parser_set_language(p, lang) first_line <- range(0, point(0, 0), 6, point(0, 6)) p <- parser_set_included_ranges(p, list(first_line)) node_text(tree_root_node(parser_parse(p, "x <- 1\ny <- 2"))) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() p <- parser_set_timeout(parser(lang), 1e6) p <- parser_set_language(p, lang) first_line <- range(0, point(0, 0), 6, point(0, 6)) p <- parser_set_included_ranges(p, list(first_line)) node_text(tree_root_node(parser_parse(p, "x <- 1\ny <- 2"))) }
- parser_parse() parses text and returns a tree_sitter_tree.
- parser_reparse() performs an incremental reparse of a slightly edited
text, reusing the old tree. All bytes and points are 0-indexed.
parser_parse(x, text, ...) parser_reparse( x, text, tree, start_byte, start_point, old_end_byte, old_end_point, new_end_byte, new_end_point )parser_parse(x, text, ...) parser_reparse( x, text, tree, start_byte, start_point, old_end_byte, old_end_point, new_end_byte, new_end_point )
x |
A |
text |
A single string to parse. |
... |
Unused. |
tree |
The original |
start_byte, old_end_byte, new_end_byte
|
Edit byte offsets. |
start_point, old_end_point, new_end_point
|
Edit |
A tree_sitter_tree.
if (requireNamespace("treesitter.r", quietly = TRUE)) { p <- parser(treesitter.r::language()) tree <- parser_parse(p, "x <- 1") # Replace the "1" at byte 5 with "42", then reparse incrementally. tree2 <- parser_reparse(p, "x <- 42", tree, 5, point(0, 5), 6, point(0, 6), 7, point(0, 7)) node_text(tree_root_node(tree2)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { p <- parser(treesitter.r::language()) tree <- parser_parse(p, "x <- 1") # Replace the "1" at byte 5 with "42", then reparse incrementally. tree2 <- parser_reparse(p, "x <- 42", tree, 5, point(0, 5), 6, point(0, 6), 7, point(0, 7)) node_text(tree_root_node(tree2)) }
- point() creates a tree-sitter point. Points are 0-indexed.
- point_row() and point_column() access the row and column.
- is_point() tests for a point.
point(row, column) point_row(x) point_column(x) is_point(x)point(row, column) point_row(x) point_column(x) is_point(x)
x |
A |
row, column
|
A 0-indexed row / column (single whole number). |
point() a point; the accessors a double; is_point() a logical.
p <- point(2, 4) p point_row(p) point_column(p) is_point(p)p <- point(2, 4) p point_row(p) point_column(p) is_point(p)
Compile a tree-sitter query
query(language, source)query(language, source)
language |
A |
source |
A single string of query source (tree-sitter S-expression pattern syntax). |
A tree_sitter_query.
if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call function: (identifier) @fn)") query_capture_count(q) }if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call function: (identifier) @fn)") query_capture_count(q) }
Run a query and collect its captures
query_captures(x, node)query_captures(x, node)
x |
A |
node |
A |
A list with name (character vector of capture names) and node
(list of tree_sitter_nodes), one entry per capture in traversal order.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() node <- tree_root_node(text_parse("f(1); g(2)", lang)) q <- query(lang, "(call function: (identifier) @fn)") vapply(query_captures(q, node)$node, node_text, character(1)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() node <- tree_root_node(text_parse("f(1); g(2)", lang)) q <- query(lang, "(call function: (identifier) @fn)") vapply(query_captures(q, node)$node, node_text, character(1)) }
Unlike treesitter, which nests matches by pattern, this returns a flat list
of matches. Each match is list(pattern, name, node): the 0-indexed pattern,
the capture names, and the captured tree_sitter_nodes.
query_matches(x, node)query_matches(x, node)
x |
A |
node |
A |
A list of matches.
if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() node <- tree_root_node(text_parse("f(1); g(2)", lang)) q <- query(lang, "(call function: (identifier) @fn)") matches <- query_matches(q, node) vapply(matches, function(m) node_text(m$node[[1]]), character(1)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { lang <- treesitter.r::language() node <- tree_root_node(text_parse("f(1); g(2)", lang)) q <- query(lang, "(call function: (identifier) @fn)") matches <- query_matches(q, node) vapply(matches, function(m) node_text(m$node[[1]]), character(1)) }
Query byte ranges per pattern (1-indexed pattern)
query_start_byte_for_pattern(x, i) query_end_byte_for_pattern(x, i)query_start_byte_for_pattern(x, i) query_end_byte_for_pattern(x, i)
x |
A |
i |
A 1-indexed pattern position. |
A single double (0-indexed byte).
if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call) @call (identifier) @id") c(query_start_byte_for_pattern(q, 2), query_end_byte_for_pattern(q, 2)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call) @call (identifier) @id") c(query_start_byte_for_pattern(q, 2), query_end_byte_for_pattern(q, 2)) }
Query counts
query_pattern_count(x) query_capture_count(x) query_string_count(x)query_pattern_count(x) query_capture_count(x) query_string_count(x)
x |
A |
A single double.
if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call function: (identifier) @fn)") c(query_pattern_count(q), query_capture_count(q), query_string_count(q)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { q <- query(treesitter.r::language(), "(call function: (identifier) @fn)") c(query_pattern_count(q), query_capture_count(q), query_string_count(q)) }
- range() creates a tree-sitter range from a start/end byte and point.
- range_start_byte(), range_start_point(), range_end_byte(), and
range_end_point() access the components.
- is_range() tests for a range.
All bytes and points are 0-indexed.
range(start_byte, start_point, end_byte, end_point) range_start_byte(x) range_start_point(x) range_end_byte(x) range_end_point(x) is_range(x)range(start_byte, start_point, end_byte, end_point) range_start_byte(x) range_start_point(x) range_end_byte(x) range_end_point(x) is_range(x)
x |
A |
start_byte, end_byte
|
Single whole numbers. |
start_point, end_point
|
|
range() a range; accessors their component; is_range() a logical.
r <- range(0, point(0, 0), 6, point(0, 6)) r range_end_byte(r) range_end_point(r) is_range(r)r <- range(0, point(0, 0), 6, point(0, 6)) r range_end_byte(r) range_end_point(r) is_range(r)
text_parse() is a convenience wrapper that builds a parser for language
and parses x with it, returning the tree directly.
text_parse(x, language)text_parse(x, language)
x |
A single string to parse. |
language |
A |
A tree_sitter_tree.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("f <- function(x) x + 1", treesitter.r::language()) node_type(tree_root_node(tree)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("f <- function(x) x + 1", treesitter.r::language()) node_type(tree_root_node(tree)) }
The tree's included ranges
tree_included_ranges(x)tree_included_ranges(x)
x |
A |
A list of tree_sitter_range objects.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) tree_included_ranges(tree) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) tree_included_ranges(tree) }
Retrieve the root node of a tree
tree_root_node(x)tree_root_node(x)
x |
A |
A tree_sitter_node.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) node_type(tree_root_node(tree)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) node_type(tree_root_node(tree)) }
Returns the root node shifted forward by byte and point, so positions
read in the coordinate space of a larger document.
tree_root_node_with_offset(x, byte, point)tree_root_node_with_offset(x, byte, point)
x |
A |
byte |
A 0-indexed byte offset. |
point |
A |
A tree_sitter_node.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) node <- tree_root_node_with_offset(tree, 10, point(2, 0)) node_start_point(node) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) node <- tree_root_node_with_offset(tree, 10, point(2, 0)) node_start_point(node) }
- tree_text() returns the text the tree was parsed with.
- tree_language() returns the tree's tree_sitter_language.
tree_text(x) tree_language(x)tree_text(x) tree_language(x)
x |
A |
tree_text() a string; tree_language() a language.
if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) tree_text(tree) language_name(tree_language(tree)) }if (requireNamespace("treesitter.r", quietly = TRUE)) { tree <- text_parse("x <- 1", treesitter.r::language()) tree_text(tree) language_name(tree_language(tree)) }
tree_walk() and node_walk() create a tree_sitter_tree_cursor, a mutable
cursor for efficient traversal. Navigate with its methods:
cursor$goto_first_child(), cursor$goto_next_sibling(),
cursor$goto_parent() (each returns TRUE/FALSE), and read state with
cursor$node(), cursor$field_name(), and cursor$depth().
tree_walk(x) node_walk(node)tree_walk(x) node_walk(node)
x |
A |
node |
A |
A tree_sitter_tree_cursor.
if (requireNamespace("treesitter.r", quietly = TRUE)) { cursor <- tree_walk(text_parse("x <- 1", treesitter.r::language())) cursor$goto_first_child() node_type(cursor$node()) }if (requireNamespace("treesitter.r", quietly = TRUE)) { cursor <- tree_walk(text_parse("x <- 1", treesitter.r::language())) cursor$goto_first_child() node_type(cursor$node()) }