aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/_query_linter.lua
diff options
context:
space:
mode:
authorThomas Vigouroux <thomas.vigouroux@protonmail.com>2024-02-16 18:54:47 +0100
committerGitHub <noreply@github.com>2024-02-16 11:54:47 -0600
commitbd5008de07d29a6457ddc7fe13f9f85c9c4619d2 (patch)
tree1c73e5c0bdefb1fa635afdae86516219a7c34fff /runtime/lua/vim/treesitter/_query_linter.lua
parent1ba3500abdb23027b7ba9bcc9b4f697dcd5ad886 (diff)
downloadrneovim-bd5008de07d29a6457ddc7fe13f9f85c9c4619d2.tar.gz
rneovim-bd5008de07d29a6457ddc7fe13f9f85c9c4619d2.tar.bz2
rneovim-bd5008de07d29a6457ddc7fe13f9f85c9c4619d2.zip
fix(treesitter): correctly handle query quantifiers (#24738)
Query patterns can contain quantifiers (e.g. (foo)+ @bar), so a single capture can map to multiple nodes. The iter_matches API can not handle this situation because the match table incorrectly maps capture indices to a single node instead of to an array of nodes. The match table should be updated to map capture indices to an array of nodes. However, this is a massively breaking change, so must be done with a proper deprecation period. `iter_matches`, `add_predicate` and `add_directive` must opt-in to the correct behavior for backward compatibility. This is done with a new "all" option. This option will become the default and removed after the 0.10 release. Co-authored-by: Christian Clason <c.clason@uni-graz.at> Co-authored-by: MDeiml <matthias@deiml.net> Co-authored-by: Gregory Anders <greg@gpanders.com>
Diffstat (limited to 'runtime/lua/vim/treesitter/_query_linter.lua')
-rw-r--r--runtime/lua/vim/treesitter/_query_linter.lua28
1 files changed, 15 insertions, 13 deletions
diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua
index 8651e187c2..378e9c67aa 100644
--- a/runtime/lua/vim/treesitter/_query_linter.lua
+++ b/runtime/lua/vim/treesitter/_query_linter.lua
@@ -122,7 +122,7 @@ local parse = vim.func._memoize(hash_parse, function(node, buf, lang)
end)
--- @param buf integer
---- @param match table<integer,TSNode>
+--- @param match table<integer,TSNode[]>
--- @param query Query
--- @param lang_context QueryLinterLanguageContext
--- @param diagnostics Diagnostic[]
@@ -130,20 +130,22 @@ local function lint_match(buf, match, query, lang_context, diagnostics)
local lang = lang_context.lang
local parser_info = lang_context.parser_info
- for id, node in pairs(match) do
- local cap_id = query.captures[id]
+ for id, nodes in pairs(match) do
+ for _, node in ipairs(nodes) do
+ local cap_id = query.captures[id]
- -- perform language-independent checks only for first lang
- if lang_context.is_first_lang and cap_id == 'error' then
- local node_text = vim.treesitter.get_node_text(node, buf):gsub('\n', ' ')
- add_lint_for_node(diagnostics, { node:range() }, 'Syntax error: ' .. node_text)
- end
+ -- perform language-independent checks only for first lang
+ if lang_context.is_first_lang and cap_id == 'error' then
+ local node_text = vim.treesitter.get_node_text(node, buf):gsub('\n', ' ')
+ add_lint_for_node(diagnostics, { node:range() }, 'Syntax error: ' .. node_text)
+ end
- -- other checks rely on Neovim parser introspection
- if lang and parser_info and cap_id == 'toplevel' then
- local err = parse(node, buf, lang)
- if err then
- add_lint_for_node(diagnostics, err.range, err.msg, lang)
+ -- other checks rely on Neovim parser introspection
+ if lang and parser_info and cap_id == 'toplevel' then
+ local err = parse(node, buf, lang)
+ if err then
+ add_lint_for_node(diagnostics, err.range, err.msg, lang)
+ end
end
end
end