From 7fa292c52d7bf63d59730946ef220befe4d51900 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Sat, 23 Dec 2023 19:45:19 +0900 Subject: [PATCH] fix(treesitter): outdated highlight due to tree with outdated region Problem: A region managed by an injected parser may shrink after re-running the injection query. If the updated region goes out of the range to be parsed, then the corresponding tree will remain outdated, possibly retaining the nodes that shouldn't exist anymore. This results in outdated highlights. Solution: Re-parse an invalid tree if its region intersects the range to be parsed. --- runtime/lua/vim/treesitter/languagetree.lua | 8 +++++++- test/functional/treesitter/parser_spec.lua | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 0171b416cd..a249a10f47 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -348,7 +348,13 @@ function LanguageTree:_parse_regions(range) -- If there are no ranges, set to an empty list -- so the included ranges in the parser are cleared. for i, ranges in pairs(self:included_regions()) do - if not self._valid[i] and intercepts_region(ranges, range) then + if + not self._valid[i] + and ( + intercepts_region(ranges, range) + or (self._trees[i] and intercepts_region(self._trees[i]:included_ranges(false), range)) + ) + then self._parser:set_included_ranges(ranges) local parse_time, tree, tree_changes = tcall(self._parser.parse, self._parser, self._trees[i], self._source, true) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index 6f386115ae..94642552d9 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -693,6 +693,18 @@ int x = INT_MAX; {2, 26, 3, 66} -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) + + helpers.feed('7ggI//') + exec_lua([[parser:parse({6, 7})]]) + eq("table", exec_lua("return type(parser:children().c)")) + eq(2, exec_lua("return #parser:children().c:trees()")) + eq({ + {0, 0, 8, 0}, -- root tree + {4, 14, 5, 18}, -- VALUE 123 + -- VALUE1 123 + {2, 26, 3, 66} -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + }, get_ranges()) end) end)