diff options
author | Lewis Russell <lewis6991@gmail.com> | 2023-04-06 15:16:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-06 15:16:44 +0100 |
commit | e29bc03c046b3a137c2e36b4d34c119b277d62b2 (patch) | |
tree | a801f810952066ff96b4cd2bff3cd76bbcadecd5 | |
parent | fbee2e4d9c627889abd597f2383cf77f96c3d825 (diff) | |
download | rneovim-e29bc03c046b3a137c2e36b4d34c119b277d62b2.tar.gz rneovim-e29bc03c046b3a137c2e36b4d34c119b277d62b2.tar.bz2 rneovim-e29bc03c046b3a137c2e36b4d34c119b277d62b2.zip |
fix(treesitter): do not track ranges of the root tree (#22912)
Fixes #22911
-rw-r--r-- | runtime/lua/vim/treesitter/languagetree.lua | 10 | ||||
-rw-r--r-- | test/functional/treesitter/parser_spec.lua | 44 |
2 files changed, 53 insertions, 1 deletions
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 703d2a1f6d..4aa07d1b96 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -57,6 +57,7 @@ local Range = require('vim.treesitter._range') ---@field private _injection_query Query Queries defining injected languages ---@field private _opts table Options ---@field private _parser TSParser Parser for language +---@field private _has_regions boolean ---@field private _regions Range6[][]? ---List of regions this tree should manage and parse. If nil then regions are ---taken from _trees. This is mostly a short-lived cache for included_regions() @@ -440,6 +441,8 @@ end ---@private ---@param new_regions Range6[][] List of regions this tree should manage and parse. function LanguageTree:set_included_regions(new_regions) + self._has_regions = true + -- Transform the tables from 4 element long to 6 element long (with byte offset) for _, region in ipairs(new_regions) do for i, range in ipairs(region) do @@ -468,7 +471,8 @@ function LanguageTree:included_regions() return self._regions end - if #self._trees == 0 then + if not self._has_regions or #self._trees == 0 then + -- treesitter.c will default empty ranges to { -1, -1, -1, -1, -1, -1} return { {} } end @@ -744,6 +748,10 @@ function LanguageTree:_edit( -- Validate regions after editing the tree self:_iter_regions(function(_, region) + if #region == 0 then + -- empty region, use the full source + return false + end for _, r in ipairs(region) do if Range.intercepts(r, changed_range) then return false diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index ea9958b12a..9afce0b3a0 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -948,4 +948,48 @@ int x = INT_MAX; [16] = '1', [17] = '0' }, get_fold_levels()) end) + + it('tracks the root range properly (#22911)', function() + insert([[ + int main() { + int x = 3; + }]]) + + local query0 = [[ + (declaration) @declaration + (function_definition) @function + ]] + + exec_lua([[ + vim.treesitter.start(0, 'c') + ]]) + + local function run_query() + return exec_lua([[ + local query = vim.treesitter.query.parse("c", ...) + parser = vim.treesitter.get_parser() + tree = parser:parse()[1] + res = {} + for id, node in query:iter_captures(tree:root()) do + table.insert(res, {query.captures[id], node:range()}) + end + return res + ]], query0) + end + + eq({ + { 'function', 0, 0, 2, 1 }, + { 'declaration', 1, 2, 1, 12 } + }, run_query()) + + helpers.command'normal ggO' + insert('int a;') + + eq({ + { 'declaration', 0, 0, 0, 6 }, + { 'function', 1, 0, 3, 1 }, + { 'declaration', 2, 2, 2, 12 } + }, run_query()) + + end) end) |