mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
fix(languagetree): don't treat unparsed nodes as occupying full range
This is incorrect in the following scenario: 1. The language tree is Lua > Vim > Lua. 2. An edit simultaneously wipes out the `_regions` of all nodes, while taking the Vim injection off-screen. 3. The Vim injection is not re-parsed, so the child Lua `_regions` is still `nil`. 4. The child Lua is assumed, incorrectly, to occupy the whole document. 5. This causes the injections to be parsed again, resulting in Lua > Vim > Lua > Vim. 6. Now, by the same process, Vim ends up with its range assumed over the whole document. Now the parse is broken and results in broken highlighting and poor performance. It should be fine to instead treat an unparsed node as occupying nothing (i.e. effectively non-existent). Since, either: - The parent was just parsed, hence defining `_regions` - The parent was not just parsed, in which case this node doesn't need to be parsed either. Also, the name `has_regions` is confusing; it seems to simply mean the opposite of "root" or "full_document". However, this PR does not touch it.
This commit is contained in:
parent
b7763d7f6b
commit
e353c869ce
@ -650,8 +650,8 @@ function LanguageTree:included_regions()
|
||||
return self._regions
|
||||
end
|
||||
|
||||
if not self._has_regions or next(self._trees) == nil then
|
||||
-- treesitter.c will default empty ranges to { -1, -1, -1, -1, -1, -1}
|
||||
if not self._has_regions then
|
||||
-- treesitter.c will default empty ranges to { -1, -1, -1, -1, -1, -1} (the full range)
|
||||
return { {} }
|
||||
end
|
||||
|
||||
|
@ -838,3 +838,67 @@ describe('treesitter highlighting (help)', function()
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
describe('treesitter highlighting (nested injections)', function()
|
||||
local screen
|
||||
|
||||
before_each(function()
|
||||
screen = Screen.new(80, 7)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids {
|
||||
[1] = {foreground = Screen.colors.SlateBlue};
|
||||
[2] = {bold = true, foreground = Screen.colors.Brown};
|
||||
[3] = {foreground = Screen.colors.Cyan4};
|
||||
[4] = {foreground = Screen.colors.Fuchsia};
|
||||
}
|
||||
end)
|
||||
|
||||
it("correctly redraws nested injections (GitHub #25252)", function()
|
||||
insert[=[
|
||||
function foo() print("Lua!") end
|
||||
|
||||
local lorem = {
|
||||
ipsum = {},
|
||||
bar = {},
|
||||
}
|
||||
vim.cmd([[
|
||||
augroup RustLSP
|
||||
autocmd CursorHold silent! lua vim.lsp.buf.document_highlight()
|
||||
augroup END
|
||||
]])
|
||||
]=]
|
||||
|
||||
exec_lua [[
|
||||
vim.opt.scrolloff = 0
|
||||
vim.bo.filetype = 'lua'
|
||||
vim.treesitter.start()
|
||||
]]
|
||||
|
||||
-- invalidate the language tree
|
||||
feed("ggi--[[<ESC>04x")
|
||||
|
||||
screen:expect{grid=[[
|
||||
{2:^function} {3:foo}{1:()} {1:print(}{4:"Lua!"}{1:)} {2:end} |
|
||||
|
|
||||
{2:local} {3:lorem} {2:=} {1:{} |
|
||||
{3:ipsum} {2:=} {1:{},} |
|
||||
{3:bar} {2:=} {1:{},} |
|
||||
{1:}} |
|
||||
|
|
||||
]]}
|
||||
|
||||
-- spam newline insert/delete to invalidate Lua > Vim > Lua region
|
||||
feed("3jo<ESC>ddko<ESC>ddko<ESC>ddko<ESC>ddk0")
|
||||
|
||||
screen:expect{grid=[[
|
||||
{2:function} {3:foo}{1:()} {1:print(}{4:"Lua!"}{1:)} {2:end} |
|
||||
|
|
||||
{2:local} {3:lorem} {2:=} {1:{} |
|
||||
^ {3:ipsum} {2:=} {1:{},} |
|
||||
{3:bar} {2:=} {1:{},} |
|
||||
{1:}} |
|
||||
|
|
||||
]]}
|
||||
end)
|
||||
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user