diff options
author | Thomas Vigouroux <thomas.vigouroux@protonmail.com> | 2024-02-16 18:54:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-16 11:54:47 -0600 |
commit | bd5008de07d29a6457ddc7fe13f9f85c9c4619d2 (patch) | |
tree | 1c73e5c0bdefb1fa635afdae86516219a7c34fff /runtime/lua/vim/treesitter/_query_linter.lua | |
parent | 1ba3500abdb23027b7ba9bcc9b4f697dcd5ad886 (diff) | |
download | rneovim-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.lua | 28 |
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 |