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.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 byte index 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.