load: function(file_name: string, language_name: string): Language, stringLoad 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, stringSearch 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.
Cursor.copy: function(Cursor): CursorCreate a copy of the given cursor
Cursor.current_depth: function(Cursor): integerGet the depth of the cursor's current node relative to the node the cursor
was constructed with
Cursor.current_descendant_index: function(Cursor): integerGet the cursor's current node index
Cursor.current_field_id: function(Cursor): FieldIdGet the field id of the given cursor's current node
May return nil
Cursor.current_field_name: function(Cursor): stringGet the field name of the current node under the cursor
Cursor.current_node: function(Cursor): NodeGet the current node under the cursor
Cursor.goto_descendant: function(Cursor, integer)Move the cursor to the nth descendant of the original node this cursor was
constructed with. Zero represents the original node itself.
Cursor.goto_first_child: function(Cursor): booleanPosition the cursor at the first child of the current node
Cursor.goto_first_child_for_byte: function(Cursor, integer): integerMove 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
Cursor.goto_first_child_for_point: function(Cursor, Point): integerMove 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
Cursor.goto_next_sibling: function(Cursor): booleanPosition the cursor at the sibling of the current node
Cursor.goto_parent: function(Cursor): booleanPosition the cursor at the parent of the current node
Cursor.reset: function(Cursor, Node)Position the cursor at the given node
Cursor.reset_to: function(Cursor, Cursor)Re-initialize a tree cursor to the same position as another cursor.
Language.abi_version: function(Language): integerGet the ABI version number for the given parser's language
Language.field_count: function(Language): integerGet the number of distinct field names in the given parser's language
Language.field_id_for_name: function(Language, string): FieldIdGet the numeric id for the given field name
Language.metadata: function(Language): LanguageMetadataGet 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): stringGet the name of the language. May return nil.
Language.name_for_field_id: function(Language, FieldId): stringGet the name for a numeric field id
Language.next_state: function(Language, StateId, Symbol): StateIdGet the next parse state
Language.parser: function(Language): ParserCreate a parser of the given language
Language.query: function(Language, string): QueryCreate a query out of the given string for this language
Language.state_count: function(Language): integerGet 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): integerGet the number of distinct node types in the given language
Language.symbol_for_name: function(Language, string, is_named: boolean): SymbolGet the numerical id for the given node type string
Language.symbol_name: function(Language, Symbol): stringGet a node type string for the given symbol id
Language.symbol_type: function(Language, Symbol): SymbolTypeCheck whether the given node type id belongs to named nodes, anonymous nodes,
or hidden nodes
Node.child: function(Node, idx: integer): NodeGet the node's idx'th child (0-indexed)
Node.child_by_field_id: function(Node, FieldId): NodeGet a node's child given a field id
Node.child_by_field_name: function(Node, string): NodeGet a node's child given a field name
Node.child_count: function(Node): integerGet the number of children a node has
Node.children: function(Node): function(): NodeIterate over a node's children
Node.create_cursor: function(Node): CursorCreate a new cursor at the given node
Node.end_byte_offset: function(Node): integerGet the byte offset of the source string that the given node ends at (exclusive)
Node.end_index: function(Node): integerGet the inclusive 1-index of the source string that the given node ends at
Node.end_point: function(Node): PointGet the row and column of where the given node ends
Node.grammar_symbol: function(Node): SymbolReturns 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): stringReturns the type of a given node as a string as it appears in the grammar ignoring aliases
Node.is_extra: function(Node): booleanGet whether or not the current node is extra
Node.is_missing: function(Node): booleanGet whether or not the current node is missing
Node.is_named: function(Node): booleanGet whether or not the current node is named
Node.name: function(Node): stringReturns the type of a given node as a string
print(node) -- => (comment)
print(node:name()) -- => comment
Node.named_child: function(Node, idx: integer): NodeGet the node's idx'th named child (0-indexed)
Node.named_child_count: function(Node): integerGet the number of named children a node has
Node.named_children: function(Node): function(): NodeIterate over a node's named children
Node.next_named_sibling: function(Node): NodeGet a node's next named sibling
Node.next_parse_state: function(Node): StateIdGet the parse state after this node
Node.next_sibling: function(Node): NodeGet a node's next sibling
Node.parse_state: function(Node): StateIdGet this node's parse state
Node.prev_named_sibling: function(Node): NodeGet a node's previous named sibling
Node.prev_sibling: function(Node): NodeGet a node's previous sibling
Node.source: function(Node): stringGet the substring of the source that was parsed to create Node
Node.start_byte_offset: function(Node): integerGet the byte offset of the source string that the given node starts at
Node.start_index: function(Node): integerGet the inclusive 1-index of the source string that the given node starts at
Node.start_point: function(Node): PointGet the row and column of where the given node starts
Node.symbol: function(Node): SymbolReturns the type of a given node as a numeric id
Node.type: function(Node): stringGet 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.parse_string: function(Parser, string, ?Encoding, ?Tree): TreeUses 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
): Treereader 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.reset: function(Parser)Reset the parser, causing the next parse to start from the beginning
Parser.set_ranges: function(Parser, {Range}): booleanSets 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
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.cursor: function(Query, Node): QueryCursorQuery.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 the Query.with method and 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
Query.match: function(Query, Node, predicates?: {string:Predicate}, start?: integer | Point, end_?: integer | Point): function(): MatchIterate 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
(node) @capture-name patterns and (node)? @capture-name patterns),nil or that Node.(node)* @capture-name and (node)+ @capture-name patterns)nil or an array of Node
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'?' character will be seen as conditions that must be met for the pattern to be matched. (#eq? ...) will match if all arguments provided are equal (#match? text pattern) will match the provided text matches the given pattern. Matches are determined by Lua's standard string.match function. (#find? text substring) will match if text contains substring. The substring is found with Lua's standard string.find, but the search always starts from the beginning, and pattern matching is disabled. This is equivalent to string.find(text, substring, 0, true)
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
QueryCursor.set_byte_range: function(QueryCursor, start: integer, end_: integer): booleanreturns true when the given range was non-empty
QueryCursor.set_point_range: function(QueryCursor, start: Point, end_: Point): booleanreturns true when the given range was non-empty
Tree.copy: function(Tree): TreeCreates 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
)Create an edit to the given tree
Tree.edit_s: function(Tree, TreeEdit)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.root: function(Tree): NodeReturns the root node of the given parse tree