Nvim 的 :help 页面,生成 自 源代码 使用 tree-sitter-vimdoc 解析器。
tree-sitter 库,用于对缓冲区进行增量解析:https://tree-sitter.github.io/tree-sitter/parser 运行时目录中搜索的库。parser/{lang}.* 搜索。如果找到多个相同语言的解析器,则使用第一个解析器。(注意:这通常意味着优先级“用户配置 > 插件 > 捆绑”。)vim.treesitter.language.add('python', { path = "/path/to/python.so" })xml treesitter 解析器用于文件类型为 svg 或 xslt 的缓冲区,请使用vim.treesitter.language.register('xml', { 'svg', 'xslt' })ENABLE_WASMTIME 构建,则也可以加载 wasm 解析器vim.treesitter.language.add('python', { path = "/path/to/python.wasm" })query 包含一个或多个模式。一个 pattern 在语法树中的节点类型上定义。一个 match 对应于与模式匹配的语法树的特定元素。模式可以选择性地定义捕获和谓词。一个 capture 允许您将名称与模式中的特定节点关联。一个 predicate 为匹配添加任意元数据和条件数据。runtimepath 下的 queries 目录中以 *.scm 文件形式查找查询,每个文件包含特定语言和目的的查询,例如,queries/lua/highlights.scm 用于突出显示 Lua 文件。默认情况下,使用 runtimepath 上的第一个查询(这通常意味着用户配置优先于插件,插件优先于 Nvim 捆绑的查询)。如果查询应该扩展其他查询而不是替换它们,请使用 treesitter-query-modeline-extends。eq? 谓词可以按以下方式使用((identifier) @variable.builtin
(#eq? @variable.builtin "self"))"self" 相对应的标识符。例如,此类查询可用于以不同的方式突出显示内置函数或变量。eq? treesitter-predicate-eq?((identifier) @variable.builtin (#eq? @variable.builtin "self"))
((node1) @left (node2) @right (#eq? @left @right))match? treesitter-predicate-match?vim-match? treesitter-predicate-vim-match?((identifier) @constant (#match? @constant "^[A-Z_]+$"))^ 和 $ 锚点将匹配节点文本的开头和结尾。any-match? treesitter-predicate-any-match?any-vim-match? treesitter-predicate-any-vim-match?match?,但对于量化模式,仅需一个捕获的节点匹配即可。contains? treesitter-predicate-contains?((identifier) @foo (#contains? @foo "foo"))
((identifier) @foo-bar (#contains? @foo-bar "foo" "bar"))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))eq?、match?、lua-match?、contains?)接受 any- 前缀,以在捕获包含的任何节点与谓词匹配时匹配。-- TODO: This is a
-- very long
-- comment (just imagine it)(((comment)+ @comment)
(#match? @comment "TODO"))(((comment)+ @comment)
(#any-match? @comment "TODO"))set! 指令为匹配或节点设置元数据((identifier) @foo (#set! type "parameter"))set! treesitter-directive-set!metadata[key](匹配特定)或 metadata[capture_id][key](捕获特定)访问。{capture_id}(可选){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} },其中 capture_id 作为 metadata[capture_id].range。对 treesitter-language-injections 有用。{capture_id} {start_row} {start_col} {end_row} {end_col}((identifier) @constant (#offset! @constant 0 1 0 -1)){capture_id} {pattern} {replacement}(#gsub! @_node ".*%.(.*)" "%1"){capture_id}(#trim! @fold); 开头的注释。以下是当前支持的模式行替代方案inherits: {lang}... treesitter-query-modeline-inherits{lang} 的查询。这将递归地向下遍历 {lang} 的查询,除非它们包含在括号中:({lang})。 注意:这是为了包含来自另一种语言的查询。如果您希望查询扩展同一语言的查询,请使用 extends。extends treesitter-query-modeline-extends;; inherits: typescript,jsx
;; extends;; extends
;;
;; inherits: csshighlights.scm 的查询指定,该查询将已解析 TSTree 中的 TSNode 匹配到 capture,该 capture 可以分配高亮组。例如,查询(parameters (identifier) @variable.parameter)identifier 节点,与名为 @variable.parameter 的捕获内容匹配。例如,对于 Lua 代码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 和 bar 作为 @variable.parameter。[
"if"
"else"
] @keyword.conditionalhighlights.scm 查询,则可以通过 vim.treesitter.start() 简单地为当前缓冲区启用 treesitter 突出显示。@ 为前缀的捕获名称可以直接用作突出显示组。对于许多常用的捕获,相应的突出显示组默认情况下会链接到 Nvim 的标准 highlight-groups(例如,@comment 链接到 Comment),但可以在颜色方案中覆盖。@comment.documentation。如果未定义此组,则使用普通 @comment 的突出显示。这样,现有的颜色方案就可以开箱即用,但可以为使它们可用的查询添加更具体的变体。hi @comment.c guifg=Blue
hi @comment.lua guifg=DarkBlue
hi link @comment.documentation.java Stringthis、self) @variable.parameter 函数参数 @variable.parameter.builtin 特殊参数(例如 _、it) @variable.member 对象和结构体字段GOTO 和其他标签(例如,C 中的 label:),包括 heredoc 标签typedef <type> <identifier>)@property) @property 键值对中的键+、*)go、Python 中的 async/await) @keyword.function 定义函数的关键字(例如,Go 中的 func、Python 中的 def) @keyword.operator 作为英文单词的运算符(例如,and、or) @keyword.import 用于包含或导出模块的关键字(例如,Python 中的 import、from) @keyword.type 描述命名空间和复合类型的关键字(例如,struct、enum) @keyword.modifier 修改其他结构的关键字(例如,const、static、public) @keyword.repeat 与循环相关的关键字(例如,for、while) @keyword.return 像 return 和 yield 这样的关键字 @keyword.debug 与调试相关的关键字 @keyword.exception 与异常相关的关键字(例如,throw、catch)if、else) @keyword.conditional.ternary 三元运算符(例如,?、:);、.、,) @punctuation.bracket 括号(例如,()、{}、[]) @punctuation.special 特殊符号(例如,字符串插值中的 {})ERROR、FIXME、DEPRECATED) @comment.warning 警告类型注释(例如,WARNING、FIX、HACK) @comment.todo 待办事项类型注释(例如,TODO、WIP) @comment.note 注释类型注释(例如,NOTE、INFO、XXX)$ ... $)@spell 捕获可以用来指示一个节点应该被 Nvim 的内置 spell 检查器进行拼写检查。例如,以下捕获将注释标记为要检查(comment) @spell@nospell,它禁用对具有 @spell 的区域的拼写检查。conceal 元数据进行 conceal。按照惯例,要隐藏的节点被捕获为 @conceal,但可以使用任何捕获。例如,以下查询可用于隐藏 Markdown 中的代码块分隔符(fenced_code_block_delimiter @conceal (#set! conceal ""))!= 运算符替换为 Unicode 字符,该字符仍然与其他运算符的突出显示方式相同"!=" @operator (#set! conceal "≠")"priority" 元数据属性来手动更改单个查询模式的优先级((super_important_node) @superimportant (#set! priority 105))<script> 标签内包含 JavaScript,在 <style> 标签内包含 CSS<% %> 标签内包含 Ruby,在这些标签之外包含 HTML<php 标签之间包含 HTML@injection.content - 指示捕获的节点应该使用另一种语言重新解析其内容。@injection.language - 指示捕获的节点的文本可能包含应该用于重新解析 @injection.content 的语言名称。@injection.filename - 指示捕获的节点的文本可能包含一个文件名;然后通过 vim.filetype.match() 查找相应的文件类型,并将其视为应该用于重新解析 @injection.content 的语言名称。injection.language - 可用于硬编码特定语言的名称。injection.combined - 指示树中所有匹配的节点都应该将其内容解析为一个嵌套的文档。injection.include-children - 指示 @injection.content 节点的整个文本应该被重新解析,包括其子节点的文本。默认情况下,子节点的文本将从注入的文档中排除。injection.self - 指示节点的文本应该使用与节点的 LanguageTree 相同的语言解析。injection.parent - 指示捕获的节点的文本应该使用与节点的父 LanguageTree 相同的语言解析。vim.treesitter Lua 模块的参考手册,它是 Nvim treesitter 集成的主要接口。以下内容中的大部分内容是从函数文档自动生成的。TSTree 支持以下方法。TSTree)TSNode)TSNode 支持以下方法。integer){index} (integer)TSNode?)integer){descendant}) 获取包含 {descendant} 的节点的子节点(包括 {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}) 获取此节点内跨越给定 (行,列) 位置范围的最小节点{start_row} (integer){start_col} (integer){end_row} (integer){end_col} (integer)TSNode?)integer) (integer) (integer){node} (TSNode)boolean)boolean){name} (string)TSNode[])boolean)boolean)id 不保证对来自不同树的节点是唯一的。string)fun(): TSNode, string)boolean)boolean){index} (integer)TSNode?)integer){start_row}, {start_col}, {end_row}, {end_col}) 获取此节点内跨越给定 (行,列) 位置范围的最小命名节点{start_row} (integer){start_col} (integer){end_row} (integer){end_col} (integer)TSNode?)TSNode?)TSNode?)TSNode?)TSNode?)TSNode?){include_bytes} 为 true){include_bytes} 为 true){include_bytes} (boolean?)string)integer) (integer) (integer)integer)TSTree)string){lnum}) vim.treesitter.foldexpr(){lnum} 的折叠级别。可以直接设置为 'foldexpr'vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'{lnum} (integer?) 要计算折叠级别的行号string){winnr} (integer?) 窗口句柄或 0 代表当前窗口(默认)string[]) 捕获名称列表priority、conceal 等;如果未定义,则为空)。{bufnr} (integer) 缓冲区编号(0 代表当前缓冲区){row} (integer) 位置行{col} (integer) 位置列{capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata}[])vim.treesitter.get_parser(bufnr):parse(range){opts} (table?) 可选关键字参数{bufnr} (integer?) 缓冲区编号(nil 或 0 代表当前缓冲区){pos} ([integer, integer]?) 0 索引 (行,列) 元组。默认情况下,为当前窗口中的光标位置。如果 {bufnr} 不是当前缓冲区,则需要此参数。{lang} (string?) 解析器语言。(默认:来自缓冲区文件类型){ignore_injections} (boolean?) 忽略注入的语言(默认 true){include_anonymous} (boolean?) 包含匿名节点(默认 false)TSNode?) 给定位置的节点{node_or_range} (TSNode|table) 节点或位置表integer) start_row (integer) start_col (integer) end_row (integer) end_col{node} (TSNode){source} (integer|string) 提取 {node} 的缓冲区或字符串{opts} (table?) 可选参数。metadata[capture_id]。string)opts.error = false 设置为抑制此行为并返回 nil(以及错误消息)而不是抛出错误。 警告: 此行为将在 Nvim 0.12 中成为默认行为,并且该选项将被删除。{bufnr} (integer?) 解析器应绑定的缓冲区(默认:当前缓冲区){lang} (string?) 此解析器的语言(默认:来自缓冲区文件类型){opts} (table?) 传递给创建的语言树的选项vim.treesitter.LanguageTree?) 用于解析的对象 (string?) 错误消息(如果适用){node}, {source}, {metadata}) vim.treesitter.get_range(){source} 和 {metadata} 来获取应用了指令的范围。{node} (TSNode){source} (integer|string?) 提取 {node} 的缓冲区或字符串{metadata} (vim.treesitter.query.TSMetadata?)table) 包含以下字段的表{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 开始字节{[4]} (integer) 结束行{[5]} (integer) 结束列{[6]} (integer) 结束字节{str} (string) 要解析的文本{lang} (string) 此字符串的语言{opts} (table?) 传递给创建的语言树的选项vim.treesitter.LanguageTree) 用于解析的对象{opts} (table?) 可选选项表,包含以下可能的键{command} 创建一个新窗口。{winid} 为 nil 时使用。{dest} (TSNode) 可能的祖先{source} (TSNode) 可能的后代布尔值) 如果 {dest} 是 {source} 的祖先,则为真{node} (TSNode) 定义范围{line} (整数) 行 (从 0 开始){col} (整数) 列 (从 0 开始)布尔值) 如果位置在节点范围内,则为真{node} (TSNode){range} (表)布尔值) 如果 {node} 包含 {range},则为真start 后添加 vim.bo.syntax = 'on'。vim.api.nvim_create_autocmd( 'FileType', { pattern = 'tex',
callback = function(args)
vim.treesitter.start(args.buf, 'latex')
vim.bo[args.buf].syntax = 'on' -- only if additional legacy syntax is needed
end
}){bufnr} (整数?) 要高亮显示的缓冲区 (默认值: 当前缓冲区){lang} (字符串?) 解析器的语言 (默认值: 来自缓冲区文件类型){bufnr} (整数?) 要停止高亮显示的缓冲区 (默认值: 当前缓冲区)parser 运行时目录或提供的 {path} 中搜索。可以在启用树状语法功能之前用来检查可用的解析器,例如:if vim.treesitter.language.add('markdown') then
vim.treesitter.start(bufnr, 'markdown')
end{lang} (字符串) 解析器的名称 (仅限字母数字和 _){opts} (表?) 选项{path} (字符串) 解析器所在的可选路径{symbol_name} (字符串) 要加载的语言的内部符号名称布尔值?) 如果解析器已加载,则为真 (字符串?) 如果解析器无法加载,则为错误{lang} 本身以及通过 vim.treesitter.language.register() 注册的所有文件类型。{lang} (字符串) 解析器的名称字符串[]) 文件类型{filetype}。对于复合文件类型(如 html.glimmer),仅返回主文件类型。{filetype} (字符串)字符串?)布尔值,指示该节点是否被命名(即,不是匿名的)。匿名节点用双引号 (") 包围。{lang} (字符串) 语言表){filetype} 的映射,任何其他文件类型到 {lang} 的现有映射都将保留。{lang} (字符串) 解析器的名称{filetype} (字符串|字符串[]) 与 lang 关联的文件类型metadata.key = value 来设置匹配级别数据。此外,处理程序可以通过使用元数据表上的捕获 ID 来设置节点级别数据 metadata[capture_id].key = value{name} (字符串) 指令的名称,不带前导 #{handler} (fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata))(node (#set! conceal "-")) 将获得 { "#set!", "conceal", "-" } 的 predicate{opts} (表) 具有以下字段的表{force} (布尔值) 覆盖相同名称的现有 predicate{all} (布尔值) 使用匹配表的正确实现,其中捕获 ID 映射到节点列表而不是单个节点。默认为 true。此选项将在将来的版本中删除。{name}, {handler}, {opts}) 添加一个新的 predicate,用于在查询中使用。{name} (字符串) predicate 的名称,不带前导 #{handler} (fun(match: table<integer,TSNode[]>, pattern: integer, source: integer|string, predicate: any[], metadata: vim.treesitter.query.TSMetadata): boolean?){opts} (表?) 具有以下字段的表{force} (布尔值) 覆盖相同名称的现有 predicate{all} (布尔值) 使用匹配表的正确实现,其中捕获 ID 映射到节点列表而不是单个节点。默认为 true。此选项将在将来的版本中删除。:write 保存它。你可以在 $VIMRUNTIME/queries/ 中找到查询示例。{lang} (字符串?) 要为其打开查询编辑器的语言。如果省略,则从当前缓冲区的文件类型推断。{lang} (字符串) 要用于查询的语言{query_name} (字符串) 查询的名称 (例如 "highlights")vim.treesitter.Query?) 已解析的查询。如果未找到任何查询文件,则为 nil。{lang} (字符串) 要获取查询的语言{query_name} (字符串) 要加载的查询的名称 (例如 "highlights"){is_included} (布尔值?) 内部参数,大多数情况下保留为 nil字符串[]) query_files 用于给定查询和语言的要加载的文件列表{buf} 中的查询文件是否有错误。/lua/highlights.scm 结尾,则将使用 lua 语言的解析器。{buf} (整数) 缓冲区句柄{opts} (table?) 可选关键字参数{langs} (字符串|字符串[]) 用于检查查询的语言。如果指定了多种语言,则会针对所有语言验证查询{clear} (布尔值) 仅清除当前的 lint 错误字符串[]) 支持的指令。字符串[]) 支持的 predicate。{findstart}, {base}) vim.treesitter.query.omnifunc()vim.bo.omnifunc = 'v:lua.vim.treesitter.query.omnifunc'{findstart} (0|1){base} (字符串){lang}, {query}) vim.treesitter.query.parse(){query} 解析为字符串。 (如果查询在一个文件中,则调用者应在调用之前将内容读取到一个字符串中)。Query (参阅 lua-treesitter-query) 对象,可以使用该对象来搜索语法树中的节点,以查找使用 iter_captures 和 iter_matches 方法在 {query} 中定义的模式。info 和 captures,其中包含有关 {query} 的更多上下文信息。captures 包含在 {query} 中定义的唯一捕获名称列表。info.captures 也指向 captures。info.patterns 包含有关 predicate 的信息。{lang} (字符串) 要用于查询的语言{query} (字符串) s-expr 语法中的查询vim.treesitter.Query) 已解析的查询{source};在这种情况下,调用者必须确保使用与缓冲区当前文本一致的新解析的树(如果相关)。{start} 和 {stop} 可用于限制行范围内的匹配项(这通常与根节点作为 {node} 一起使用,即获取当前视窗中的语法高亮匹配项)。如果省略,则使用给定节点的 {start} 和 {stop} 行值。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) 将在其中进行搜索的节点{source} (integer|string) 用于提取文本的源缓冲区或字符串{start} (integer?) 搜索的起始行。默认为 node:start()。{stop} (integer?) 搜索的停止行(不包含末尾)。默认为 node:end_()。fun(end_line: integer?): integer, TSNode, vim.treesitter.query.TSMetadata, TSQueryMatch) 捕获 ID,捕获节点,元数据,匹配{node} 内的所有匹配项。参数与 Query:iter_captures() 相同,但迭代的值不同:查询中模式的(从 1 开始的)索引,一个将捕获索引映射到节点列表的表格,以及来自任何处理匹配的指令的元数据。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) 将在其中进行搜索的节点{source} (integer|string) 要搜索的源缓冲区或字符串{start} (integer?) 搜索的起始行。默认为 node:start()。{stop} (integer?) 搜索的停止行(不包含末尾)。默认为 node:end_()。{opts} (table?) 可选关键字参数false(默认值为 true)时,返回的表格将捕获 ID 映射到单个(最后一个)节点,而不是完整的匹配节点列表。此选项仅用于向后兼容性,将在将来的版本中移除。fun(): integer, table<integer, TSNode[]>, vim.treesitter.query.TSMetadata) 模式 ID,匹配,元数据{lang} (字符串) 要用于查询的语言{query_name} (string) 查询的名称(例如,“highlights”){text} (string) 查询文本(未解析)。{lang} 的根树状解析器以及任何“注入”的语言解析器,这些解析器本身可能会递归地注入其他语言。例如,包含一些 Vimscript 命令的 Lua 缓冲区需要多个解析器才能完全理解其内容。local parser = vim.treesitter.get_parser(bufnr, lang)local tree = parser:parse({ start_row, end_row })parse()。如果缓冲区没有被编辑,则将再次返回相同的树,无需额外工作。如果缓冲区之前已被解析,则将对更改的部分进行增量解析。{range} (table) 一个具有以下字段的表格{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 结束行{[4]} (integer) 结束列boolean)remove_child 来删除它。{fn} (fun(tree: TSTree, ltree: vim.treesitter.LanguageTree)){start_row}, {start_col}, {start_bytes}, {end_row}, {end_col}, {end_bytes} }。table<integer, Range6[]>){reload} (boolean?){exclude_children}) LanguageTree:is_valid(){exclude_children} (boolean?) 是否忽略子节点的有效性(默认值为 false)boolean){range} (table) 一个具有以下字段的表格{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 结束行{[4]} (integer) 结束列vim.treesitter.LanguageTree) 管理 {range} 的树{range}, {opts}) 获取包含 {range} 的最小命名节点。{range} (table) 一个具有以下字段的表格{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 结束行{[4]} (integer) 结束列{opts} (表?) 具有以下字段的表{ignore_injections} (boolean, default: true) 忽略注入的语言TSNode?){range} (table) 一个具有以下字段的表格{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 结束行{[4]} (integer) 结束列{opts} (表?) 具有以下字段的表{ignore_injections} (boolean, default: true) 忽略注入的语言TSNode?){range}) LanguageTree:parse(){},通常只有根树)的区域总是被解析;否则(通常是注入)只有在它与 {range} 相交时(或者如果 {range} 为 true)才会被解析。{range} (boolean|Range?) 解析解析器源中的此范围。设置为 true 以对源进行完全解析(注意:可能会很慢!)设置为 false|nil 仅解析具有空范围的区域(通常只有没有注入的根树)。table<integer, TSTree>)on_bytes : 见 nvim_buf_attach(),但这将在解析器回调之后被调用。on_changedtree : 每当树发生语法变化时,都会调用一个回调。它将传递两个参数:一个包含发生变化的范围(作为节点范围)的表格以及发生变化的树。on_child_added : 当子节点被添加到树中时发出。on_child_removed : 当子节点从树中移除时发出。on_detach : 当缓冲区被分离时发出,参见 nvim_buf_detach_event。接受一个参数,即缓冲区的编号。{recursive} (boolean?) 递归地为所有子节点应用回调。任何新的子节点也将继承这些回调。{range} (table) 一个具有以下字段的表格{[1]} (integer) 开始行{[2]} (integer) 开始列{[3]} (integer) 结束行{[4]} (integer) 结束列{opts} (表?) 具有以下字段的表{ignore_injections} (boolean, default: true) 忽略注入的语言TSTree?)table<integer, TSTree>)