ltreesitter

_get_registry_entry
load
require

Cursor

Cursor.current_field_name
Cursor.current_node
Cursor.goto_first_child
Cursor.goto_next_sibling
Cursor.goto_parent
Cursor.reset

Node

Node.child
Node.child_by_field_name
Node.child_count
Node.children
Node.create_cursor
Node.end_byte
Node.end_point
Node.is_extra
Node.is_missing
Node.is_named
Node.name
Node.named_child
Node.named_child_count
Node.named_children
Node.next_named_sibling
Node.next_sibling
Node.prev_named_sibling
Node.prev_sibling
Node.source
Node.start_byte
Node.start_point
Node.type

Parser

Parser.parse_string
Parser.query
Parser.set_timeout

Query

Query.capture
Query.exec
Query.match
Query.with

Tree

Tree.copy
Tree.edit
Tree.root











_get_registry_entry: function(): table

ltreesitter uses a table in the Lua registry to keep references alive and prevent Lua's garbage collection from collecting things that the library needs internally.
The behavior nor existence of this function should not be relied upon and is included strictly for memory debugging purposes

Though, if you are looking to debug a segfault/garbage collection bug, this is a useful tool in addition to the lua inspect module


load: function(file_name: string, language_name: string): Parser, string

Load a parser from a given file

On unix this uses dlopen, so if a path without a path separator is given, dlopen has its own path's that it will search for your file in.
So if in doubt use a file path like


local my_parser = ltreesitter.load("./my_parser.so", "my_language")


* Currently this does not work on Windows
(The entire library doesn't work on Windows since this is one of the entry points to any of the functionality)


require: function(library_file_name: string, language_name: string): Parser

Search package.cpath for a parser with the filename 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.


local my_parser = ltreesitter.require("my_language")
my_parser:parse_string(...)
-- etc.


* Currently this does not work on Windows
(The entire library doesn't work on Windows since this is one of the entry points to any of the functionality)



Cursor.current_field_name: function(Cursor): string

Get the field name of the current node under the cursor


Cursor.current_node: function(Cursor): Node

Get the current node under the cursor


Cursor.goto_first_child: function(Cursor): boolean

Position the cursor at the first child of the current node


Cursor.goto_next_sibling: function(Cursor): boolean

Position the cursor at the sibling of the current node


Cursor.goto_parent: function(Cursor): boolean

Position the cursor at the parent of the current node


Cursor.reset: function(Cursor, Node)

Position the cursor at the given node



Node.child: function(Node, idx: number): Node

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


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

Get a node's child given a field name


Node.child_count: function(Node): number

Get the number of children a node has


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

Iterate over a node's children


Node.create_cursor: function(Node): Cursor

Create a new cursor at the given node


Node.end_byte: function(Node): number

Get the byte 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.is_extra: function(Node): boolean

Get whether or not the current node is missing


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.name: function(Node): string

Returns the name of a given node


print(node) -- => (comment)
print(node:name()) -- => comment


Node.named_child: function(Node, idx: number): Node

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


Node.named_child_count: function(Node): number

Get the number of named children a node has


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

Iterate over a node's named children


Node.next_named_sibling: function(Node): Node

Get a node's next named sibling


Node.next_sibling: function(Node): Node

Get a node's next sibling


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: function(Node): number

Get the byte 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.type: function(Node): string

Get the type of the given node



Parser.parse_string: function(Parser, string, 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)

Could return nil if the parser has a timeout


Parser.query: function(Parser, string): Query

Create a query out of the given string for the language of the given parser


Parser.set_timeout: function(Parser, number)

Sets how long the parser is allowed to take in microseconds



Query.capture: function(Query, Node): function(): Node, string

Iterate over the captures of a given query in Node, name pairs


local q = parser:query[[ (comment) @my_match ]]
for capture, name in q:capture(node) do
print(capture, name) -- => (comment), "my_match"
end


Query.exec: function(Query, Node)

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.


local parser = ltreesitter.require("teal")

-- 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)
)]]
:with{["set!"] = function(a, b) _G[a] = b:sub(2, -2) end}
:exec(root_node)

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.match: function(Query, Node): function(): Match

Iterate over the matches of a given query

The match object is a record populated with all the information given by treesitter


type Query.Match = record
id: number
pattern_index: number
capture_count: number
captures: {string|number:Node}
end


Example:

local q = parser:query[[ (comment) @my_match ]]
for match in q:match(node) do
print(match.captures.my_match)
end


Query.with: function(Query, {string:function(...: string): any...}): Query

Creates a new query equipped with predicates defined in the {string:function} map given

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.
(#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)

Example:
The following snippet will match lua functions that have a single LDoc/EmmyLua style comment above them


local parser = ltreesitter.require("lua")

-- 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)
)]]
:with{
["is_doc_comment?"] = function(str)
return str:sub(1, 4) == "---@"
end
}
:match(root_node)
do
print("Function: " .. match.captures["the-function-name"] .. " has documentation")
print(" " .. match.captures["the-comment"])
end



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, TreeEdit)

Create an edit to the given tree


Tree.root: function(Tree): Node

Returns the root node of the given parse tree