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.
This commit is contained in:
Jaehwang Jung 2023-12-23 19:45:19 +09:00 committed by Christian Clason
parent 0b66ab42c7
commit 7fa292c52d
2 changed files with 19 additions and 1 deletions

View File

@ -348,7 +348,13 @@ function LanguageTree:_parse_regions(range)
-- If there are no ranges, set to an empty list -- If there are no ranges, set to an empty list
-- so the included ranges in the parser are cleared. -- so the included ranges in the parser are cleared.
for i, ranges in pairs(self:included_regions()) do 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) self._parser:set_included_ranges(ranges)
local parse_time, tree, tree_changes = local parse_time, tree, tree_changes =
tcall(self._parser.parse, self._parser, self._trees[i], self._source, true) tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)

View File

@ -693,6 +693,18 @@ int x = INT_MAX;
{2, 26, 3, 66} -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) {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)) -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
}, get_ranges()) }, get_ranges())
helpers.feed('7ggI//<esc>')
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)
end) end)