mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
fix(treesitter): make foldexpr work without highlighting (#24167)
Problem: Treesitter fold is not updated if treesitter hightlight is not active. More precisely, updating folds requires `LanguageTree:parse()`. Solution: Call `parse()` before computing folds and compute folds when lines are added/removed. This doesn't guarantee correctness of the folds, because some changes that don't add/remove line won't update the folds even if they should (e.g. adding pair of braces). But it is good enough for most cases, while not introducing big overhead. Also, if highlighting is active, it is likely that `TSHighlighter._on_buf` already ran `parse()` (or vice versa).
This commit is contained in:
parent
ab65a98adb
commit
c7e7f1d4b4
@ -162,9 +162,7 @@ local function get_folds_levels(bufnr, info, srow, erow)
|
||||
|
||||
local parser = ts.get_parser(bufnr)
|
||||
|
||||
if not parser:is_valid() then
|
||||
return
|
||||
end
|
||||
parser:parse()
|
||||
|
||||
parser:for_each_tree(function(tree, ltree)
|
||||
local query = ts.query.get(ltree:lang(), 'folds')
|
||||
@ -283,10 +281,12 @@ local function on_bytes(bufnr, foldinfo, start_row, old_row, new_row)
|
||||
local end_row_old = start_row + old_row
|
||||
local end_row_new = start_row + new_row
|
||||
|
||||
if new_row ~= old_row then
|
||||
if new_row < old_row then
|
||||
foldinfo:remove_range(end_row_new, end_row_old)
|
||||
elseif new_row > old_row then
|
||||
else
|
||||
foldinfo:add_range(start_row, end_row_new)
|
||||
end
|
||||
schedule_if_loaded(bufnr, function()
|
||||
get_folds_levels(bufnr, foldinfo, start_row, end_row_new)
|
||||
recompute_folds()
|
||||
|
@ -922,12 +922,6 @@ int x = INT_MAX;
|
||||
[19] = '1' }, get_fold_levels())
|
||||
|
||||
helpers.command('1,2d')
|
||||
helpers.poke_eventloop()
|
||||
|
||||
exec_lua([[vim.treesitter.get_parser():parse()]])
|
||||
|
||||
helpers.poke_eventloop()
|
||||
helpers.sleep(100)
|
||||
|
||||
eq({
|
||||
[1] = '0',
|
||||
@ -947,6 +941,29 @@ int x = INT_MAX;
|
||||
[15] = '2',
|
||||
[16] = '1',
|
||||
[17] = '0' }, get_fold_levels())
|
||||
|
||||
helpers.command('1put!')
|
||||
|
||||
eq({
|
||||
[1] = '>1',
|
||||
[2] = '1',
|
||||
[3] = '1',
|
||||
[4] = '1',
|
||||
[5] = '>2',
|
||||
[6] = '2',
|
||||
[7] = '2',
|
||||
[8] = '1',
|
||||
[9] = '1',
|
||||
[10] = '>2',
|
||||
[11] = '2',
|
||||
[12] = '2',
|
||||
[13] = '2',
|
||||
[14] = '2',
|
||||
[15] = '>3',
|
||||
[16] = '3',
|
||||
[17] = '3',
|
||||
[18] = '2',
|
||||
[19] = '1' }, get_fold_levels())
|
||||
end)
|
||||
|
||||
it('tracks the root range properly (#22911)', function()
|
||||
|
Loading…
Reference in New Issue
Block a user