Note:


❖TREE_SITTER_LANGUAGE_VERSION: integer

The current language ABI version supported by the used version of tree-sitter

❖TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION: integer

The minimum language ABI version supported by the used version of tree-sitter

❖load: function(file_name: string, language_name: string): Language, string

Load a language from a given file Keep in mind that this includes the .so, .dll, or .dynlib extension On Unix this uses dlopen, on Windows this uses LoadLibrary so if a path without a path separator is given, these functions have their own path's that they will search for your file in. So if in doubt use a file path like
local my_language = ltreesitter.load("./my_parser.so", "my_language")

❖require: function(library_file_name: string, language_name?: string): Language, string

Search package.cpath for a parser with the filename library_file_name.so or parsers/library_file_name.so (or .dll on Windows) and try to load the symbol tree_sitter_'language_name' language_name is optional and will be set to library_file_name if not provided. So if you want to load a Lua parser from a file named lua.so then use ltreesitter.require("lua") But if you want to load a Lua parser from a file named parser.so then use ltreesitter.require("parser", "lua") Like the regular require, this will error if the parser is not found or the symbol couldn't be loaded. Use either pcall or ltreesitter.load to not error out on failure. Returns the language and the path it was loaded from.
local my_language, loaded_from = ltreesitter.require("my_language")
print(my_language:name(), loaded_from) -- "my_language", /home/user/.luarocks/lib/lua/5.4/parsers/my_language.so
-- etc.

❖tree_sitter_version: string

The version of the tree-sitter library ltreesitter was built with

❖version: string

The version of ltreesitter

❖Language.abi_version: function(Language): integer

Get the ABI version number for the given parser's language

❖Language.field_count: function(Language): integer

Get the number of distinct field names in the given parser's language

❖Language.field_id_for_name: function(Language, string): FieldId

Get the numeric id for the given field name

❖Language.metadata: function(Language): LanguageMetadata

Get the metadata for the given language. This information relies on the language author providing the correct data in the language's tree-sitter.json May return nil

❖Language.name: function(Language): string

Get the name of the language. May return nil.

❖Language.name_for_field_id: function(Language, FieldId): string

Get the name for a numeric field id

❖Language.next_state: function(Language, StateId, Symbol): StateId

Get the next parse state

❖Language.parser: function(Language): Parser

Create a parser of the given language

❖Language.query: function(Language, string): Query

Create a query out of the given string for this language

❖Language.state_count: function(Language): integer

Get the number of valid states in the given language

❖Language.subtypes: function(Language, supertype: Symbol): {Symbol}

Get a list of all supertype symbols for the given language

❖Language.supertypes: function(Language): {Symbol}

Get a list of all supertype symbols for the given language

❖Language.symbol_count: function(Language): integer

Get the number of distinct node types in the given language

❖Language.symbol_for_name: function(Language, string, is_named: boolean): Symbol

Get the numerical id for the given node type string

❖Language.symbol_name: function(Language, Symbol): string

Get a node type string for the given symbol id

❖Language.symbol_type: function(Language, Symbol): SymbolType

Check whether the given node type id belongs to named nodes, anonymous nodes, or hidden nodes

❖Node.child: function(Node, zero_index: integer): Node

Get the node's zero_index'th child (0-indexed)

❖Node.child_by_field_id: function(Node, FieldId): Node

Get a node's child given a field id

❖Node.child_by_field_name: function(Node, string): Node

Get a node's child given a field name

❖Node.child_count: function(Node): integer

Get the number of children a node has

❖Node.child_with_descendant: function(Node, descendant: Node): Node

Get the node that contains descendant. Can return descendant itself

❖Node.children: function(Node): function(): Node

Iterate over a node's children

❖Node.create_cursor: function(Node): TreeCursor

Create a new tree cursor at the given node

❖Node.descendant_count: function(Node): integer

Returns the number of descendants this node has

❖Node.descendant_for_byte_range: function(Node, start_byte: integer, end_byte: integer): Node

Returns the smallest descendant node that spans the given range

❖Node.descendant_for_point_range: function(Node, start_point: Point, end_point: Point): Node

Returns the smallest descendant node that spans the given range

❖Node.edit: function( Node, start_byte: integer, old_end_byte: integer, new_end_byte: integer, start_point_row: integer, start_point_col: integer, old_end_point_row: integer, old_end_point_col: integer, new_end_point_row: integer, new_end_point_col: integer )
Node.edit: function(Node, Edit)

Create an edit to the given node

❖Node.edit_p: function( Node, start_byte: integer, old_end_byte: integer, new_end_byte: integer, start_point_row: integer, start_point_col: integer, old_end_point_row: integer, old_end_point_col: integer, new_end_point_row: integer, new_end_point_col: integer )

Create an edit to the given node

❖Node.edit_s: function(Node, Edit)

Create an edit to the given node

❖Node.end_byte_offset: function(Node): integer

Get the byte offset of the source string that the given node ends at (exclusive)

❖Node.end_index: function(Node): integer

Get the inclusive 1-index of the source string that the given node ends at

❖Node.end_point: function(Node): Point

Get the row and column of where the given node ends

❖Node.field_name_for_child: function(Node, child_zero_index: integer): string

Returns the field name for the child at the given zero index (if any)

❖Node.field_name_for_named_child: function(Node, child_zero_index: integer): string

Returns the field name for the named child at the given zero index (if any)

❖Node.first_child_for_byte: function(Node, byte_offset: integer): Node

Returns the first child that contains or starts after the given byte offset

❖Node.first_named_child_for_byte: function(Node, byte_offset: integer): Node

Returns the first named child that contains or starts after the given byte offset

❖Node.grammar_symbol: function(Node): Symbol

Returns the type of a given node as a numeric id as it appears in the grammar ignoring aliases This is what should be used in Parser:language_next_state() instead of Node:symbol

❖Node.grammar_type: function(Node): string

Returns the type of a given node as a string as it appears in the grammar ignoring aliases

❖Node.has_changes: function(Node): boolean

Returns true when the node has been changed by an edit

❖Node.has_error: function(Node): boolean

Returns true when the node is an error

❖Node.id: function(Node): NodeId

Returns the language used to parse the Node

❖Node.is_extra: function(Node): boolean

Get whether or not the current node is extra

❖Node.is_missing: function(Node): boolean

Get whether or not the current node is missing

❖Node.is_named: function(Node): boolean

Get whether or not the current node is named

❖Node.language: function(Node): Language

Returns the language used to parse the Node

❖Node.named_child: function(Node, zero_index: integer): Node

Get the node's zero_index'th named child

❖Node.named_child_count: function(Node): integer

Get the number of named children a node has

❖Node.named_children: function(Node): function(): Node

Iterate over a node's named children

❖Node.named_descendant_for_byte_range: function(Node): Node

Returns the smallest named descendant node that spans the given range

❖Node.named_descendant_for_point_range: function(Node): Node

Returns the smallest named descendant node that spans the given range

❖Node.next_named_sibling: function(Node): Node

Get a node's next named sibling

❖Node.next_parse_state: function(Node): StateId

Get the parse state after this node

❖Node.next_sibling: function(Node): Node

Get a node's next sibling

❖Node.parent: function(Node): Node

Returns the parent of a given node. It is recommended to use Node.child_with_descendant for iterating over ancestors

❖Node.parse_state: function(Node): StateId

Get this node's parse state

❖Node.prev_named_sibling: function(Node): Node

Get a node's previous named sibling

❖Node.prev_sibling: function(Node): Node

Get a node's previous sibling

❖Node.source: function(Node): string

Get the substring of the source that was parsed to create Node

❖Node.start_byte_offset: function(Node): integer

Get the byte offset of the source string that the given node starts at

❖Node.start_index: function(Node): integer

Get the inclusive 1-index of the source string that the given node starts at

❖Node.start_point: function(Node): Point

Get the row and column of where the given node starts

❖Node.symbol: function(Node): Symbol

Returns the type of a given node as a numeric id

❖Node.type: function(Node): string

Get the type of the given node

❖Parser.get_ranges: function(Parser): {Range}

Get the ranges of text that the parser will include when parsing

❖Parser.language: function(Parser): Language

Get the language associated with this parser

❖Parser.parse_string: function(Parser, string, ?Encoding, ?Tree): Tree

Uses the given parser to parse the string If Tree is provided then it will be used to create a new updated tree (but it is the responsibility of the programmer to make the correct Tree:edit calls)

❖Parser.parse_with: function( Parser, reader: (function(integer, Point): string), progress_callback?: (function(has_error: boolean, byte_offset: integer): boolean), encoding?: Encoding, old_tree?: Tree ): Tree

reader should be a function that takes a zero-based byte offset and a Point and returns the text at that point. The function should return either nil or an empty string to signal that there is no more text.

progress_callback should be a function that takes a boolean signalling if an error has occurred, and an integer byte offset. This function will be called intermittently while parsing and may return true to cancel parsing.

A Tree can be provided to reuse parts of it for parsing, provided that Tree:edit has been called previously

encoding defaults to "utf-8" when not provided.

May return nil if the progress callback cancelled parsing.

❖Parser.print_dot_graphs: function(Parser, ?FILE)

Set the file that the parser should dump debugging DOT graphs to during parsing.

❖Parser.reset: function(Parser)

Reset the parser, causing the next parse to start from the beginning

❖Parser.set_ranges: function(Parser, {Range}): boolean

Sets the ranges that Parser will include when parsing, so you don't have to parse an entire document, but the ranges in the tree will still match the document. The array of Ranges must satisfy the following relationship: for a positive integer i within the length of ranges: {Range}:
ranges[i].end_byte <= ranges[i + 1].start_byte
returns whether or not setting the range succeeded

❖Query.capture: function( Query, Node, predicates?: {string:Predicate}, start?: integer | Point, end_?: integer | Point ): function(): (Node, string)

Iterate over the captures of a given query in Node, name pairs.
start and end are optional.
They must be passed together with the same type, describing either two bytes or two points.
If passed, the query will be executed within the range denoted.
If not passed, the default behaviour is to execute the query through the entire range of the node.
local q = parser:query[[ (comment) @my_match ]]
for capture, name in q:capture(node) do
   print(capture, name) -- => (comment), "my_match"
end

❖Query.capture_count: function(Query): integer

Returns the number of captures this query has

❖Query.cursor: function(Query, Node): QueryCursor

Create a query cursor from the given query, executing over the given node.

❖Query.disable_capture: function(Query, name: string)

Disable a certain capture within a query, preventing it from being returned in matches. Currently there is no way to undo this.

❖Query.disable_pattern: function(Query, pattern_zero_index: integer)

Disable a certain pattern within a query, preventing it from being returned in matches. Currently there is no way to undo this.

❖Query.end_byte_for_pattern: function(Query, pattern_zero_index: integer): integer

Returns the byte offset where the given pattern ends in the query's source

❖Query.exec: function( Query, Node, predicates?: {string:Predicate}, start?: integer | Point, end_?: integer | Point )

Runs a query. That's it. Nothing more, nothing less.

This is intended to be used with predicates that have side effects, i.e. for when you would use Query.match or Query.capture, but do nothing in the for loop.

start and end are optional.
They must be passed together with the same type, describing either two bytes or two points.
If passed, the query will be executed within the range denoted.
If not passed, the default behaviour is to execute the query through the entire range of the node.
local parser = ltreesitter.require("teal"):parser()

-- grab a node to query against
local root_node = parser:parse_string[[
   local x: string = "foo"
   local y: string = "bar"
]]:root()

parser
   :query[[(
      (var_declaration
         (var) @var-name
         (string) @value)
      (#set! @var-name @value)
   )]]
   :exec(root_node, {["set!"] = function(a, b) _G[a] = b:sub(2, -2) end})

print(x) -- => foo
print(y) -- => bar
If you'd like to interact with the matches/captures of a query, see the Query.match and Query.capture iterators

❖Query.is_pattern_guaranteed_at_step: function(Query, pattern_zero_index: integer): boolean

Returns whether the pattern at the given index is guaranteed to match when it is reached

❖Query.is_pattern_non_local: function(Query, pattern_zero_index: integer): boolean

Returns whether the pattern at the given index is non-local

❖Query.is_pattern_rooted: function(Query, pattern_zero_index: integer): boolean

Returns whether the pattern at the given index is rooted

❖Query.match: function( Query, Node, predicates?: {string:Predicate}, start?: integer | Point, end_?: integer | Point ): function(): Match

Iterate over the matches of a given query. start and end are optional. They must be passed together with the same type, describing either two bytes or two points. If passed, the query will be executed within the range denoted. If not passed, the default behaviour is to execute the query through the entire range of the node.
The match object is a record populated with all the information given by treesitter
interface Match
   id: integer
   pattern_index: integer
   capture_count: integer
   captures: {string:Node|{Node}}
end
If a capture can only contain at most one node (as is the case with regular (node) @capture-name patterns and (node)? @capture-name patterns), it will either be nil or that Node. If a capture can contain multiple nodes (as is the case with (node)* @capture-name and (node)+ @capture-name patterns) it will either be nil or an array of Node Example:
local q = parser:query[[ (comment) @my_match ]]
for match in q:match(node) do
   print(match.captures.my_match)
end
predicates is a map of functions to determine whether a query matches and/or execute side effects Predicates that end in a '?' character will be seen as conditions that must be met for the pattern to be matched. Predicates that don't will be seen just as functions to be executed given the matches provided. Additionally, you will not have access to the return values of these functions, if you'd like to keep the results of a computation, make your functions have side-effects to write somewhere you can access.

By default the following predicates are provided.

Predicate evaluation order:

Since predicates that end with a ? affect whether a node matches, these are run first, in the order they appear in the query's source. Once all ? queries are run, all the non-? queries are run in the order they appear in the query's source.

Example:
The following snippet will match lua functions that have a single LDoc/EmmyLua style comment above them
local parser = ltreesitter.require("lua"):parser()

-- grab a node to query against
local root_node = parser:parse_string[[
   ---@Doc this does stuff
   local function stuff_doer()
      do_stuff()
   end
]]:root()

for match in parser
   :query[[(
      (comment) @the-comment
      .
      (function_definition
         (function_name) @the-function-name)
      (#is-doc-comment? @the-comment)
   )]]
   :match(root_node, {
      ["is-doc-comment?"] = function(str)
         return str:source():sub(1, 4) == "---@"
      end
   })
do
   print("Function: " .. match.captures["the-function-name"] .. " has documentation")
   print("   " .. match.captures["the-comment"])
end

❖Query.pattern_count: function(Query): integer

Returns the number of patterns this query has

❖Query.predicates_for_pattern: function(Query, pattern_index: integer): {{string | Capture}}

Given a pattern index, return an array representing each predicate Each predicate is an array of either strings, representing literal strings in the predicate, or a table with a capture_name field, representing a @capture in the predicate. e.g. Given a (c) query like with source:
local q = c:query [[
  ((_ declarator: (identifier) @name)
   (#match? @name "[a-z]+")
   (#set! @name true))
]]
q:predicates_for_pattern(0) would return:
{
   { "match?", { capture_name = "name" }, "[a-z]+" },
   { "set!", { capture_name = "name" }, "true" },
}

❖Query.start_byte_for_pattern: function(Query, pattern_zero_index: integer): integer

Returns the byte offset where the given pattern starts in the query's source

❖Query.string_count: function(Query): integer

Returns the number of strings this query has

❖QueryCursor.did_exceed_match_limit: function(QueryCursor): boolean

Returns true if the given cursor exceeded its match limit. See set_match_limit and match_limit

❖QueryCursor.match_limit: function(QueryCursor): integer

Get the match limit of the given cursor. See set_match_limit and did_exceed_match_limit

❖QueryCursor.next_capture_without_executing_predicates: function(QueryCursor): Node, string

Find the next capture of the given cursor. As implied by the name, this does NOT execute any predicates. See Query.predicates_for_pattern or Query.capture for executing predicates.

❖QueryCursor.next_match_without_executing_predicates: function(QueryCursor): Match

Find the next match of the given cursor. As implied by the name, this does NOT execute any predicates. See Query.predicates_for_pattern or Query.match for executing predicates.

❖QueryCursor.remove_match: function(QueryCursor, match_id: integer)

Prevent the given query cursor from matching the given match id

❖QueryCursor.set_byte_range: function(QueryCursor, start_byte: integer, end_byte: integer): boolean

returns true when the given range was non-empty

❖QueryCursor.set_containing_byte_range: function( QueryCursor, start_byte: integer, end_byte: integer ): boolean

Set the byte range within which all matches must be fully contained.

❖QueryCursor.set_containing_point_range: function( QueryCursor, start_point: Point, end_point: Point ): boolean

Set the byte range within which all matches must be fully contained.

❖QueryCursor.set_match_limit: function(QueryCursor, integer)

Set the maximum number of in-progress matches allowed by this query cursor. Set to nil to set to the maximum limit (2^32-1)

❖QueryCursor.set_max_start_depth: function(QueryCursor, integer)

Set the maximum start depth of the given cursor. Set to nil to set the maximum. This prevents cursors from exploring children nodes at a certain depth.

❖QueryCursor.set_point_range: function(QueryCursor, start: Point, end_: Point): boolean

returns true when the given range was non-empty

❖Tree.copy: function(Tree): Tree

Creates a copy of the tree. Tree-sitter recommends to create copies if you are going to use multithreading since tree accesses are not thread-safe, but copying them is cheap and quick

❖Tree.edit: function( Tree, start_byte: integer, old_end_byte: integer, new_end_byte: integer, start_point_row: integer, start_point_col: integer, old_end_point_row: integer, old_end_point_col: integer, new_end_point_row: integer, new_end_point_col: integer )
Tree.edit: function(Tree, Edit)

Create an edit to the given tree

❖Tree.edit_p: function( Tree, start_byte: integer, old_end_byte: integer, new_end_byte: integer, start_point_row: integer, start_point_col: integer, old_end_point_row: integer, old_end_point_col: integer, new_end_point_row: integer, new_end_point_col: integer )

Create an edit to the given tree

❖Tree.edit_s: function(Tree, Edit)

Create an edit to the given tree

❖Tree.get_changed_ranges: function(old: Tree, new: Tree): {Range}

Compare an old syntax tree to a new syntax tree. This would usually be called right after a set of calls to Tree.edit(_s) and Parser.parse_{string,with}

❖Tree.included_ranges: function(Tree): {Range}

Returns the array of ranges used to parse the syntax tree

❖Tree.language: function(Tree): Language

Returns the language used to parse the tree

❖Tree.print_dot_graph: function(Tree, ?FILE)

Write a DOT graph to the given file. Defaults to standard error.

❖Tree.root: function(Tree): Node

Returns the root node of the given parse tree

❖Tree.root_with_offset: function(Tree, offset_bytes: integer, offset_extent: Point): Node

Returns the root node of the given parse tree, but with its position shifted forward

❖TreeCursor.copy: function(TreeCursor): TreeCursor

Create a copy of the given cursor

❖TreeCursor.current_depth: function(TreeCursor): integer

Get the depth of the cursor's current node relative to the node the cursor was constructed with

❖TreeCursor.current_descendant_index: function(TreeCursor): integer

Get the cursor's current node index

❖TreeCursor.current_field_id: function(TreeCursor): FieldId

Get the field id of the given cursor's current node
May return nil

❖TreeCursor.current_field_name: function(TreeCursor): string

Get the field name of the current node under the cursor

❖TreeCursor.current_node: function(TreeCursor): Node

Get the current node under the cursor

❖TreeCursor.goto_descendant: function(TreeCursor, offset: integer)

Move the cursor to the nth descendant of the original node this cursor was constructed with. Zero represents the original node itself.

❖TreeCursor.goto_first_child: function(TreeCursor): boolean

Position the cursor at the first child of the current node Returns true if the cursor was able to move

❖TreeCursor.goto_first_child_for_byte: function(TreeCursor, integer): integer

Move the given cursor to the first child of its current node that contains or starts after the given offset Returns the index of the child node or nil if no such child was found

❖TreeCursor.goto_first_child_for_point: function(TreeCursor, Point): integer

Move the given cursor to the first child of its current node that contains or starts after the given point Returns the index of the child node or nil if no such child was found

❖TreeCursor.goto_last_child: function(TreeCursor): boolean

Position the cursor at the first child of the current node Returns true if the cursor was able to move

❖TreeCursor.goto_next_sibling: function(TreeCursor): boolean

Position the cursor at the next sibling of the current node Returns true if there was a sibling to move to

❖TreeCursor.goto_parent: function(TreeCursor): boolean

Position the cursor at the parent of the current node

❖TreeCursor.goto_previous_sibling: function(TreeCursor): boolean

Position the cursor at the sibling of the current node Returns true if there was a sibling to move to

❖TreeCursor.reset: function(TreeCursor, Node)

Position the cursor at the given node

❖TreeCursor.reset_to: function(TreeCursor, TreeCursor)

Re-initialize a tree cursor to the same position as another cursor.