Nvim :help pages, generated
from source
using the tree-sitter-vimdoc parser.
tree-sitter library for incremental parsing of buffers:
https://tree-sitter.github.io/tree-sitter/
parser runtime directory.
parser/{lang}.* in any 'runtimepath' directory.
If multiple parsers for the same language are found, the first one is used.
(NOTE: This typically implies the priority "user config > plugins > bundled".)
vim.treesitter.language.add('python', { path = "/path/to/python.so" })
xml
treesitter parser for buffers with filetype svg or xslt, use:
vim.treesitter.language.register('xml', { 'svg', 'xslt' })
ENABLE_WASMTIME, then wasm parsers can also be
loaded:
vim.treesitter.language.add('python', { path = "/path/to/python.wasm" })
query consists of one or
more patterns. A pattern is defined over node types in the syntax tree. A
match corresponds to specific elements of the syntax tree which match a
pattern. Patterns may optionally define captures and predicates. A capture
allows you to associate names with a specific node in a pattern. A predicate
adds arbitrary metadata and conditional data to a match.
*.scm files in a queries directory under
runtimepath, where each file contains queries for a specific language and
purpose, e.g., queries/lua/highlights.scm for highlighting Lua files.
By default, the first query on runtimepath is used (which usually implies
that user config takes precedence over plugins, which take precedence over
queries bundled with Nvim). If a query should extend other queries instead
of replacing them, use treesitter-query-modeline-extends.
eq? predicate can be used as follows:
((identifier) @variable.builtin
(#eq? @variable.builtin "self"))
"self" text. Such queries can
be used to highlight built-in functions or variables differently, for instance.
((identifier) @variable.builtin (#eq? @variable.builtin "self"))
((node1) @left (node2) @right (#eq? @left @right))
any-eq?treesitter-predicate-any-eq?eq?, but for quantified patterns only one captured node must
match.
vim-match?treesitter-predicate-vim-match?((identifier) @constant (#match? @constant "^[A-Z_]+$"))
^ and $ anchors will match the start and end of the
node's text.
any-match?treesitter-predicate-any-match?any-vim-match?treesitter-predicate-any-vim-match?match?, but for quantified patterns only one captured node must
match.
lua-match?treesitter-predicate-lua-match?match?
any-lua-match?treesitter-predicate-any-lua-match?lua-match?, but for quantified patterns only one captured node
must match.
contains?treesitter-predicate-contains?((identifier) @foo (#contains? @foo "foo"))
((identifier) @foo-bar (#contains? @foo-bar "foo" "bar"))
any-contains?treesitter-predicate-any-contains?contains?, but for quantified patterns only one captured node
must match.
any-of?treesitter-predicate-any-of?((identifier) @foo (#any-of? @foo "foo" "bar"))
has-ancestor?treesitter-predicate-has-ancestor?((identifier) @variable.builtin
(#any-of? @variable.builtin "begin" "end")
(#has-ancestor? @variable.builtin range_expression))
has-parent?treesitter-predicate-has-parent?(((field_expression
(field_identifier) @method)) @_parent
(#has-parent? @_parent template_method function_declarator))
not- prefixed predicate that is just the negation of
the predicate.
eq?, match?, lua-match?,
contains?) accept an any- prefix to instead match if ANY of the nodes
contained by the capture match the predicate.
-- TODO: This is a
-- very long
-- comment (just imagine it)
(((comment)+ @comment)
(#match? @comment "TODO"))
(((comment)+ @comment)
(#any-match? @comment "TODO"))
set! directive sets metadata on the match or node:
((identifier) @foo (#set! type "parameter"))
metadata[key] (match specific) or
metadata[capture_id][key] (capture specific).
{capture_id} (optional)
{key}
{value}
((identifier) @foo (#set! @foo kind "parameter"))
((node1) @left (node2) @right (#set! type "pair"))
((codeblock) @markup.raw.block (#set! priority 90))
offset!treesitter-directive-offset!{start_row}, {start_col},
{end_row}, {end_col} } for the captured node with capture_id as
metadata[capture_id].offset. This offset will be applied to the
range returned in vim.treesitter.get_range(). Useful for
treesitter-language-injections.
{capture_id}
{start_row}
{start_col}
{end_row}
{end_col}
((identifier) @constant (#offset! @constant 0 1 0 -1))
metadata[capture_id].text.
{capture_id}
{pattern}
{replacement}
(#gsub! @_node ".*%.(.*)" "%1")
metadata[capture_id].range. Takes a capture ID and, optionally, four
integers to customize trimming behavior (1 meaning trim, 0 meaning
don't trim). When only given a capture ID, trims blank lines (lines
that contain only whitespace, or are empty) from the end of the node
(for backwards compatibility). Can trim all whitespace from both sides
of the node if parameters are given.
; only trim blank lines from the end of the node
; (equivalent to (#trim! @fold 0 0 1 0))
(#trim! @fold)
; trim blank lines from both sides of the node
(#trim! @fold 1 0 1 0)
; trim all whitespace around the node
(#trim! @fold 1 1 1 1)
{capture_id}
{trim_start_linewise}
{trim_start_charwise}
{trim_end_linewise} (default 1 if only given {capture_id})
{trim_end_charwise}
;. Here are the
currently supported modeline alternatives:
inherits: {lang}...treesitter-query-modeline-inherits{lang}.
This will recursively descend in the queries of {lang} unless wrapped
in parentheses: ({lang}).
Note: This is meant to be used to include queries from another
language. If you want your query to extend the queries of the same
language, use extends.
;; inherits: typescript,jsx
;; extends
;; extends
;;
;; inherits: css
highlights.scm,
which match a TSNode in the parsed TSTree to a capture that can be
assigned a highlight group. For example, the query
(parameters (identifier) @variable.parameter)
identifier node inside a function parameters node to the
capture named @variable.parameter. For example, for a Lua code
function f(foo, bar) end
(function_declaration ; [1:1 - 24]
name: (identifier) ; [1:10 - 10]
parameters: (parameters ; [1:11 - 20]
name: (identifier) ; [1:12 - 14]
name: (identifier))) ; [1:17 - 19]
foo and bar as @variable.parameter.
[
"if"
"else"
] @keyword.conditional
highlights.scm query is found in runtimepath,
treesitter highlighting for the current buffer can be enabled simply via
vim.treesitter.start().
@, are directly usable as highlight groups.
For many commonly used captures, the corresponding highlight groups are linked
to Nvim's standard highlight-groups by default (e.g., @comment links to
Comment) but can be overridden in colorschemes.
@comment.documentation could be used. If this group
is not defined, the highlighting for an ordinary @comment is used. This way,
existing color schemes already work out of the box, but it is possible to add
more specific variants for queries that make them available.
hi @comment.c guifg=Blue
hi @comment.lua guifg=DarkBlue
hi link @comment.documentation.java String
| Capture | Meaning |
|---|---|
| @variable | various variable names |
| @variable.builtin | built-in variable names (e.g. this, self) |
| @variable.parameter | parameters of a function |
| @variable.parameter.builtin | special parameters (e.g. _, it) |
| @variable.member | object and struct fields |
| @constant | constant identifiers |
| @constant.builtin | built-in constant values |
| @constant.macro | constants defined by the preprocessor |
| @module | modules or namespaces |
| @module.builtin | built-in modules or namespaces |
| @label | GOTO and other labels (e.g. label: in C), including heredoc labels |
| @string | string literals |
| @string.documentation | string documenting code (e.g. Python docstrings) |
| @string.regexp | regular expressions |
| @string.escape | escape sequences |
| @string.special | other special strings (e.g. dates) |
| @string.special.symbol | symbols or atoms |
| @string.special.path | filenames |
| @string.special.url | URIs (e.g. hyperlinks) |
| @character | character literals |
| @character.special | special characters (e.g. wildcards) |
| @boolean | boolean literals |
| @number | numeric literals |
| @number.float | floating-point number literals |
| @type | type or class definitions and annotations |
| @type.builtin | built-in types |
| @type.definition | identifiers in type definitions (e.g. typedef <type> <identifier> in C) |
| @attribute | attribute annotations (e.g. Python decorators, Rust lifetimes) |
| @attribute.builtin | builtin annotations (e.g. @property in Python) |
| @property | the key in key/value pairs |
| @function | function definitions |
| @function.builtin | built-in functions |
| @function.call | function calls |
| @function.macro | preprocessor macros |
| @function.method | method definitions |
| @function.method.call | method calls |
| @constructor | constructor calls and definitions |
| @operator | symbolic operators (e.g. +, *) |
| @keyword | keywords not fitting into specific categories |
| @keyword.coroutine | keywords related to coroutines (e.g. go in Go, async/await in Python) |
| @keyword.function | keywords that define a function (e.g. func in Go, def in Python) |
| @keyword.operator | operators that are English words (e.g. and, or) |
| @keyword.import | keywords for including or exporting modules (e.g. import, from in Python) |
| @keyword.type | keywords describing namespaces and composite types (e.g. struct, enum) |
| @keyword.modifier | keywords modifying other constructs (e.g. const, static, public) |
| @keyword.repeat | keywords related to loops (e.g. for, while) |
| @keyword.return | keywords like return and yield |
| @keyword.debug | keywords related to debugging |
| @keyword.exception | keywords related to exceptions (e.g. throw, catch) |
| @keyword.conditional | keywords related to conditionals (e.g. if, else) |
| @keyword.conditional.ternary | ternary operator (e.g. ?, :) |
| @keyword.directive | various preprocessor directives and shebangs |
| @keyword.directive.define | preprocessor definition directives |
| @punctuation.delimiter | delimiters (e.g. ;, ., ,) |
| @punctuation.bracket | brackets (e.g. (), {}, []) |
| @punctuation.special | special symbols (e.g. {} in string interpolation) |
| @comment | line and block comments |
| @comment.documentation | comments documenting code |
| @comment.error | error-type comments (e.g. ERROR, FIXME, DEPRECATED) |
| @comment.warning | warning-type comments (e.g. WARNING, FIX, HACK) |
| @comment.todo | todo-type comments (e.g. TODO, WIP) |
| @comment.note | note-type comments (e.g. NOTE, INFO, XXX) |
| @markup.strong | bold text |
| @markup.italic | italic text |
| @markup.strikethrough | struck-through text |
| @markup.underline | underlined text (only for literal underline markup!) |
| @markup.heading | headings, titles (including markers) |
| @markup.heading.1 | top-level heading |
| @markup.heading.2 | section heading |
| @markup.heading.3 | subsection heading |
| @markup.heading.4 | and so on |
| @markup.heading.5 | and so forth |
| @markup.heading.6 | six levels ought to be enough for anybody |
| @markup.quote | block quotes |
| @markup.math | math environments (e.g. $ ... $ in LaTeX) |
| @markup.link | text references, footnotes, citations, etc. |
| @markup.link.label | link, reference descriptions |
| @markup.link.url | URL-style links |
| @markup.raw | literal or verbatim text (e.g. inline code) |
| @markup.raw.block | literal or verbatim text as a stand-alone block |
| @markup.list | list markers |
| @markup.list.checked | checked todo-style list markers |
| @markup.list.unchecked | unchecked todo-style list markers |
| @diff.plus | added text (for diff files) |
| @diff.minus | deleted text (for diff files) |
| @diff.delta | changed text (for diff files) |
| @tag | XML-style tag names (e.g. in XML, HTML, etc.) |
| @tag.builtin | builtin tag names (e.g. HTML5 tags) |
| @tag.attribute | XML-style tag attributes |
| @tag.delimiter | XML-style tag delimiters |
@spell capture can be used to indicate that a node should be
spell checked by Nvim's builtin spell checker. For example, the following
capture marks comments as to be checked:
(comment) @spell
@nospell which disables spellchecking regions with @spell.
conceal and conceal_lines
metadata. By convention, nodes to be concealed are captured as @conceal, but
any capture can be used. For example, the following query can be used to hide
code block delimiters in Markdown:
((fenced_code_block_delimiter) @conceal (#set! conceal ""))
!= operator by a Unicode glyph, which is
still highlighted the same as other operators:
"!=" @operator (#set! conceal "≠")
conceal_lines
metadata can be used:
((comment) @comment @spell
(#set! conceal_lines ""))
conceal, only the first
character will be used:
; identifiers will be concealed with 'f'.
((identifier) @conceal (#set! conceal "foo"))
@noconceal capture to
override any existing conceal highlight set for the range.
((identifier) @noconceal)
"priority" metadata
attribute:
((super_important_node) @superimportant (#set! priority 105))
bo.commentstring metadata property (treesitter-directive-set!), that
property defines the comment delimiter (where "innermost wins"). This is
useful for languages like JSX that have different comment syntax depending
on the code region, for example:
((jsx_element) @_tag (#set! @_tag bo.commentstring "{/* %s */}"))
<script> tags and
CSS inside of <style> tags
<% %> tags, and HTML outside of
those tags
<php tags
@injection.content - indicates that the captured node should have its
contents re-parsed using another language. If there are multiple
@injection.content captures in one pattern, all ranges will be
collected and parsed as one tree. This allows query authors to create
"scoped" injections with injection query quantifiers.
@injection.language - indicates that the captured node’s text may
contain the name of a language that should be used to re-parse the
@injection.content.
@injection.filename - indicates that the captured node’s text may
contain a filename; the corresponding filetype is then looked-up up via
vim.filetype.match() and treated as the name of a language that should
be used to re-parse the @injection.content.
injection.language - can be used to hard-code the name of a specific
language.
injection.combined - indicates that all of the matching nodes in the
tree should have their content parsed as one nested document.
injection.include-children - indicates that the @injection.content
node's entire text should be re-parsed, including the text of its child
nodes. By default, child nodes' text will be excluded from the injected
document.
injection.self - indicates that the node's text should be parsed with
the same language as the node's LanguageTree.
injection.parent - indicates that the captured node’s text should
be parsed with the same language as the node's parent LanguageTree.
c, just place an
empty queries/c/injections.scm file in your 'runtimepath'.
vim.treesitter
Lua module, which is the main interface for Nvim's treesitter integration.
Most of the following content is automatically generated from the function
documentation.
TSTree of a treesitter tree supports the following methods.
TSTree.
TSTree)
TSNode)
TSNode of a treesitter node supports the following methods.
integer)
{index})TSNode:child(){index}, where zero represents the first
child.
{index} (integer)
TSNode?)
integer)
{descendant})TSNode:child_with_descendant(){descendant} (includes {descendant}).
a -> b -> c a:child_with_descendant(c) == b a:child_with_descendant(b) == b a:child_with_descendant(a) == nil
{descendant} (TSNode)
TSNode?)
{start_row}, {start_col}, {end_row}, {end_col})TSNode:descendant_for_range(){start_row} (integer)
{start_col} (integer)
{end_row} (integer)
{end_col} (integer)
TSNode?)
integer)
(integer)
(integer)
{node})TSNode:equal(){node} refers to the same node within the same tree.
{node} (TSNode)
boolean)
boolean)
{name})TSNode:field(){name} (string)
TSNode[])
boolean)
boolean)
id is not guaranteed to be unique for nodes from different
trees.
string)
{TSNode}, regardless of whether
they are named or not. Returns the child node plus the eventual field name
corresponding to this child node.
fun(): TSNode, string)
boolean)
boolean)
{index})TSNode:named_child(){index}, where zero represents the
first named child.
{index} (integer)
TSNode?)
integer)
TSNode[])
{start_row}, {start_col}, {end_row}, {end_col})TSNode:named_descendant_for_range(){start_row} (integer)
{start_col} (integer)
{end_row} (integer)
{end_col} (integer)
TSNode?)
TSNode?)
TSNode?)
TSNode?)
TSNode?)
TSNode?)
{include_bytes})TSNode:range(){include_bytes} is true)
{include_bytes} is true)
{include_bytes} (false?)
fun(self: TSNode, include_bytes: true): integer, integer, integer, integer, integer, integer
integer)
(integer)
(integer)
(integer)
string)
integer)
(integer)
(integer)
integer)
TSTree)
string)
{capture} (string) Capture name
{col} (integer) Start column
{end_col} (integer) End column (excluded)
{end_row} (integer) End row
{id} (integer) 1-based capture id in the query
{lang} (string) Language name
{metadata} (vim.treesitter.query.TSMetadata) Query metadata, e.g.
priority or conceal
{pattern_id} (integer) 1-based id of the matched pattern in the
query
{row} (integer) Start row
{lnum})vim.treesitter.foldexpr(){lnum} in the current buffer. Can be set
directly to 'foldexpr':vim.wo.foldexpr = vim.treesitter.foldexpr
{lnum} (integer?) Line number to calculate fold level for
string)
{start} and {stop} can be a row number or a {row, col} pair. All rows
and columns are 0-based; columns are byte offsets.
{stop}, a row number queries the whole line and a {row, col}
pair queries one position.
{stop}, return captures that overlap the range. The stop position is
excluded; a row number excludes that row. Empty ranges return no captures.
{buf}.
{buf} (integer) Buffer number (0 for current buffer)
{start} (integer|[integer,integer]) Start row or {row, col}
{stop} (integer|[integer,integer]?) Stop row or {row, col}
(excluded)
vim.treesitter.CaptureInfo[])
{win})vim.treesitter.get_captures_at_cursor()string[]) List of capture names
{opts})vim.treesitter.get_node()vim.treesitter.get_parser(bufnr):parse(range)
{opts} (table?) Optional keyword arguments:
{bufnr} (integer?) Buffer number (nil or 0 for current
buffer)
{ignore_injections} (boolean?, default: true) Ignore
injected languages
{include_anonymous} (boolean?, default: false) Include
anonymous nodes
{pos} ([integer, integer]?, default: window-local cursor)
0-indexed (row, col) tuple. Required if {bufnr} is not the
current buffer
TSNode?) Node at the given position
{node_or_range})vim.treesitter.get_node_range(){node_or_range} (TSNode|Range4) Node or table of positions
integer) start_row
(integer) start_col (byte offset)
(integer) end_row
(integer) end_col (byte offset)
{node} (TSNode)
{source} (integer|string) Buffer or string from which the {node} is
extracted
{opts} (table?) Optional parameters.
metadata[capture_id] when using
vim.treesitter.query.add_directive().
string)
{buf} (integer?) (default: current buffer) Buffer the parser
should be tied to
{opts} (table?) Options to pass to the created language tree
vim.treesitter.LanguageTree?) object to use for parsing
(string?) error message, if applicable
{source} and {metadata} to
get the range with directives applied.
{node} (TSNode)
{source} (integer|string?) Buffer or string from which the {node}
is extracted
{metadata} (vim.treesitter.query.TSMetadata?)
table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) start bytes
{[4]} (integer) end row
{[5]} (integer) end column
{[6]} (integer) end bytes
{str} (string) Text to parse
{lang} (string) Language of this string
{opts} (table?) Options to pass to the created language tree
vim.treesitter.LanguageTree) object to use for parsing
{opts})vim.treesitter.inspect_tree()<Enter> to jump to the node under the cursor
in the source buffer. Folding also works (try zo, zc, etc.).
:InspectTree.:InspectTree{opts} (table?) Optional options table with the following possible
keys:
{winid} is
nil.
{command}.
{dest} (TSNode) Possible ancestor
{source} (TSNode) Possible descendant
boolean) True if {dest} is an ancestor of {source}
{node} (TSNode) defining the range
{line} (integer) Line (0-based)
{col} (integer) Column (0-based)
boolean) True if the position is in node range
{node} (TSNode)
{range} (table)
boolean) True if the {node} contains the {range}
target parameter decides the selection behavior.
{target} ('parent'|'child'|'next'|'prev'|'extend_next'|'extend_prev')
Decides the selection behavior.
{count} (integer?) (default: 1) Expand or adjust the selection
this many times.
vim.bo.syntax = 'ON' after
the call to start.
vim.api.nvim_create_autocmd( 'FileType', { pattern = 'tex',
callback = function(ev)
vim.treesitter.start(ev.buf, 'latex')
vim.bo[ev.buf].syntax = 'ON' -- only if additional legacy syntax is needed
end
})
{buf} (integer?) (default: current buffer) Buffer to be
highlighted
{buf})vim.treesitter.stop(){buf} (integer?) (default: current buffer) Buffer to stop
highlighting
{lang}
parser runtime directory, or the provided
{path}. Can be used to check for available parsers before enabling
treesitter features, e.g.,if vim.treesitter.language.add('markdown') then
vim.treesitter.start(bufnr, 'markdown')
end
{lang} (string) Name of the parser (alphanumerical and _ only)
{opts} (table?) Options:
{path}? (string) Optional path the parser is located at
{symbol_name}? (string) Internal symbol name for the
language to load
boolean?) True if parser is loaded
(string?) Error if parser cannot be loaded
{lang})vim.treesitter.language.get_filetypes(){lang} is used.
{lang} itself plus all filetypes registered via
vim.treesitter.language.register().
{lang} (string) Name of parser
string[]) filetypes
{filetype})vim.treesitter.language.get_lang(){filetype}.
{filetype}. For composite
filetypes like html.glimmer, only the main filetype is returned.
{filetype} (string)
string?)
{lang})vim.treesitter.language.inspect()boolean
indicating whether or not the node is named (i.e., not anonymous).
Anonymous nodes are surrounded with double quotes (").
{lang} (string) Language
TSLangInfo)
{lang} to be used for {filetype}(s).
{filetype}, any existing
mappings from other filetypes to {lang} will be preserved.
{lang} (string) Name of parser
{filetype} (string|string[]) Filetype(s) to associate with lang
{lang} and any "injected" language parsers, which themselves may inject other
languages, recursively. For example a Lua buffer containing some Vimscript
commands needs multiple parsers to fully understand its contents.
local parser = vim.treesitter.get_parser(bufnr, lang)
bufnr=0 means current buffer). lang defaults to 'filetype'. Note:
currently the parser is retained for the lifetime of a buffer but this may
change; a plugin should keep a reference to the parser object if it wants
incremental updates.
local tree = parser:parse({ start_row, end_row })
parse() again. If the buffer wasn't edited, the
same tree will be returned again without extra work. If the buffer was parsed
before, incremental parsing will be done of the changed parts.
table<string,vim.treesitter.LanguageTree>)
{range})LanguageTree:contains(){range} is contained in the LanguageTree.
{range} (table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) end row
{[4]} (integer) end column
boolean)
remove_child must be called on the parent to remove it.
{fn})LanguageTree:for_each_tree(){fn} (fun(tree: TSTree, ltree: vim.treesitter.LanguageTree))
{start_row}, {start_col},
{start_bytes}, {end_row}, {end_col}, {end_bytes} }.
table<integer, Range6[]>)
{reload})LanguageTree:invalidate(){reload} (boolean?)
{exclude_children} (boolean?) whether to ignore the validity of
children (default false)
{range} (Range|Range[]?) range (or list of ranges,
sorted by starting point in ascending order) to
check for validity
boolean)
string)
{range})LanguageTree:language_for_range(){range}.
{range} (table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) end row
{[4]} (integer) end column
vim.treesitter.LanguageTree) tree Managing {range}
{range}.
{range} (table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) end row
{[4]} (integer) end column
{opts} (table?) A table with the following fields:
{ignore_injections}? (boolean, default: true) Ignore
injected languages
TSNode?)
{range}.
{range} (table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) end row
{[4]} (integer) end column
{opts} (table?) A table with the following fields:
{ignore_injections}? (boolean, default: true) Ignore
injected languages
TSNode?)
nil for the root tree.
vim.treesitter.LanguageTree?)
{}, typically only the root tree) is always
parsed; otherwise (typically injections) only if it intersects {range} (or
if {range} is true).
{range} (boolean|Range|Range[]?) Parse this range (or list of
ranges, sorted by starting point in ascending order) in
the parser's source. Set to true to run a complete parse
of the source (Note: Can be slow!) Set to false|nil to
only parse regions with empty ranges (typically only the
root tree without injections).
{on_parse} (fun(err?: string, trees?: table<integer, TSTree>)?)
Function invoked when parsing completes. When omitted,
parsing is synchronous and always returns the trees. When
provided and vim.g._ts_force_sync_parsing is not set,
parsing will run asynchronously. The first argument to the
function is a string representing the error type, in case
of a failure (currently only possible for timeouts). The
second argument is the list of trees returned by the parse
(upon success), or nil if the parse timed out
(determined by 'redrawtime').
parse() returns the list of trees. Otherwise, it
returns nil.
fun(self: vim.treesitter.LanguageTree, range?: boolean|Range|Range[]): table<integer, TSTree>
table<integer, TSTree>?)
{cbs} (table<TSCallbackNameOn,function>) An
nvim_buf_attach()-like table argument with the
following handlers:
on_bytes : see nvim_buf_attach().
on_changedtree : a callback that will be called every
time the tree has syntactical changes. It will be
passed two arguments: a table of the ranges (as node
ranges) that changed and the changed tree.
on_child_added : emitted when a child is added to the
tree.
on_child_removed : emitted when a child is removed
from the tree.
on_detach : emitted when the buffer is detached, see
nvim_buf_detach_event. Takes one argument, the number
of the buffer.
{recursive} (boolean?) Apply callbacks recursively for all
children. Any new children will also inherit the
callbacks.
integer|string)
{range}.
{range} (table) A table with the following fields:
{[1]} (integer) start row
{[2]} (integer) start column
{[3]} (integer) end row
{[4]} (integer) end column
{opts} (table?) A table with the following fields:
{ignore_injections}? (boolean, default: true) Ignore
injected languages
TSTree?)
table<integer, TSTree>)
{captures} (string[]) list of (unique) capture names
defined in query
{has_combined_injections} (boolean) whether the query contains
combined injections
{has_conceal_line} (boolean) whether the query sets
conceal_lines metadata
{info} (vim.treesitter.QueryInfo) query context
(e.g. captures, predicates, directives)
{iter_captures} (fun(self: vim.treesitter.Query, node: TSNode, source: integer|string, start_row: integer?, end_row: integer?, opts: table?): fun(end_line: integer?, end_col: integer?): integer, TSNode, vim.treesitter.query.TSMetadata, TSQueryMatch, TSTree)
See Query:iter_captures().
{iter_matches} (fun(self: vim.treesitter.Query, node: TSNode, source: integer|string, start: integer?, stop: integer?, opts: table?): fun(): integer, table<integer, TSNode[]>, vim.treesitter.query.TSMetadata, TSTree)
See Query:iter_matches().
{lang} (string) parser language name
{query} (TSQuery) userdata query object
metadata.key = value. Additionally, handlers can set node level
data by using the capture id on the metadata table
metadata[capture_id].key = value
{name} (string) Name of the directive, without leading #
{handler} (fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata))
(node (#set! conceal "-")) would get
the predicate { "#set!", "conceal", "-" }
{opts} (table) A table with the following fields:
{force}? (boolean) Override an existing predicate of
the same name
{name} (string) Name of the predicate, without leading #
{handler} (fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata): boolean?)
{opts} (table?) A table with the following fields:
{force}? (boolean) Override an existing predicate of
the same name
{lang})vim.treesitter.query.edit():EditQuery <tab>
completes available parsers.
:write to save it. You
can find example queries at $VIMRUNTIME/queries/.
{lang} (string?) language to open the query editor for. If omitted,
inferred from the current buffer's filetype.
{query_name} for {lang}.
{lang} (string) Language to use for the query
{query_name} (string) Name of the query (e.g. "highlights")
vim.treesitter.Query?) Parsed query. nil if no query files are
found.
{lang} (string) Language to get query for
{query_name} (string) Name of the query to load (e.g.,
"highlights")
{is_included} (boolean?) Internal parameter, most of the time left
as nil
string[]) query_files List of files to load for given query and
language
{buf}
for errors:
/lua/highlights.scm, the parser
for the lua language will be used.
{buf} (integer) Buffer handle
{opts} (table?) Optional keyword arguments:
{clear}? (boolean) Just clear current lint errors
{langs}? (string|string[]) Language(s) to use for checking
the query. If multiple languages are specified, queries are
validated for all of them
string[]) Supported directives.
string[]) Supported predicates.
vim.bo.omnifunc = vim.treesitter.query.omnifunc
{findstart} (0|1)
{base} (string)
{query} string and returns a Query object
(lua-treesitter-query), which can be used to search the tree for the
query patterns (via Query:iter_captures(), Query:iter_matches()), or
inspect/modify the query via these fields:
captures: a list of unique capture names defined in the query (alias:
info.captures).
info.patterns: information about predicates.
query: the underlying TSQuery which can be used to disable patterns
or captures.
local query = vim.treesitter.query.parse('vimdoc', [[
; query
((h1) @str
(#trim! @str 1 1 1 1))
]])
local tree = vim.treesitter.get_parser():parse()[1]
for id, node, metadata in query:iter_captures(tree:root(), 0) do
-- Print the node name and source text.
vim.print({node:type(), vim.treesitter.get_node_text(node, vim.api.nvim_get_current_buf())})
end
{lang} (string) Language to use for the query
{query} (string) Query text, in s-expr syntax
vim.treesitter.Query) Parsed query
{node}.
{source} is required if the query contains predicates; then the caller
must ensure to use a freshly parsed tree consistent with the current text
of the buffer (if relevant). {start} and {stop} can be used to limit
matches inside a row range (this is typically used with root node as the
{node}, i.e., to get syntax highlight matches in the current viewport).
When omitted, the {start} and {stop} row values are used from the given
node.
for id, node, metadata, match in query:iter_captures(tree:root(), bufnr, first, last) do
local name = query.captures[id] -- name of the capture in the query
-- typically useful info about the node:
local type = node:type() -- type of the captured node
local row1, col1, row2, col2 = node:range() -- range of the capture
-- ... use the info here ...
end
{node} (TSNode) under which the search will occur
{source} (integer|string) Source buffer or string to extract
text from
{start_row} (integer?) Starting line for the search. Defaults to
node:start().
{end_row} (integer?) Stopping line for the search (end-inclusive,
unless stop_col is provided). Defaults to
node:end_().
{opts} (table?) Optional keyword arguments:
fun(end_line: integer?, end_col: integer?): integer, TSNode, vim.treesitter.query.TSMetadata, TSQueryMatch, TSTree)
capture-id, capture-node, metadata, match, tree
{node}. The arguments are the same as
for Query:iter_captures() but the iterated values are different: an
(1-based) index of the pattern in the query, a table mapping capture
indices to a list of nodes, and metadata from any directives processing
the match.
for pattern, match, metadata in cquery:iter_matches(tree:root(), bufnr, 0, -1) do
for id, nodes in pairs(match) do
local name = query.captures[id]
for _, node in ipairs(nodes) do
-- `node` was captured by the `name` capture in the match
local node_data = metadata[id] -- Node level metadata
-- ... use the info here ...
end
end
end
{node} (TSNode) under which the search will occur
{source} (integer|string) Source buffer or string to search
{start} (integer?) Starting line for the search. Defaults to
node:start().
{stop} (integer?) Stopping line for the search (end-exclusive).
Defaults to node:end_().
{opts} (table?) Optional keyword arguments:
fun(): integer, table<integer, TSNode[]>, vim.treesitter.query.TSMetadata, TSTree)
pattern-id, match, metadata, tree
{query_name} for {lang}
C identifiers with the
following code:vim.treesitter.query.set(
'c',
'highlights',
[[;inherits c
(identifier) @spell]]
)
{lang} (string) Language to use for the query
{query_name} (string) Name of the query (e.g., "highlights")
{text} (string) Query text (unparsed).
{capture_name})TSQuery:disable_capture(){capture_name} should not include a leading "@".
@variable.parameter capture from the vimdoc
highlights query:local query = vim.treesitter.query.get('vimdoc', 'highlights')
query.query:disable_capture("variable.parameter")
vim.treesitter.get_parser():parse()
{capture_name} (string)
{pattern_index})TSQuery:disable_pattern(){pattern_index} for a particular match can be obtained
with :Inspect!, or by reading the source of the query (i.e. from
vim.treesitter.query.get_files()).
| links in vimdoc but keep other @markup.links
highlighted:local link_pattern = 9 -- from :Inspect!
local query = vim.treesitter.query.get('vimdoc', 'highlights')
query.query:disable_pattern(link_pattern)
local tree = vim.treesitter.get_parser():parse()[1]
{pattern_index} (integer)