aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/_fold.lua
diff options
context:
space:
mode:
authorJaehwang Jung <tomtomjhj@gmail.com>2023-06-28 03:05:09 +0900
committerGitHub <noreply@github.com>2023-06-27 19:05:09 +0100
commitc7e7f1d4b4b62c75bb54e652f25c6c6b8785a7f4 (patch)
tree4faaaa5698deec86260175df77b7ef775175e2c2 /runtime/lua/vim/treesitter/_fold.lua
parentab65a98adba4d32b03e7296529c4bf1491c783eb (diff)
downloadrneovim-c7e7f1d4b4b62c75bb54e652f25c6c6b8785a7f4.tar.gz
rneovim-c7e7f1d4b4b62c75bb54e652f25c6c6b8785a7f4.tar.bz2
rneovim-c7e7f1d4b4b62c75bb54e652f25c6c6b8785a7f4.zip
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).
Diffstat (limited to 'runtime/lua/vim/treesitter/_fold.lua')
-rw-r--r--runtime/lua/vim/treesitter/_fold.lua14
1 files changed, 7 insertions, 7 deletions
diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua
index a8f8c7967e..d308657237 100644
--- a/runtime/lua/vim/treesitter/_fold.lua
+++ b/runtime/lua/vim/treesitter/_fold.lua
@@ -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
- foldinfo:remove_range(end_row_new, end_row_old)
- elseif new_row > old_row then
- foldinfo:add_range(start_row, end_row_new)
+ if new_row ~= old_row then
+ if new_row < old_row then
+ foldinfo:remove_range(end_row_new, end_row_old)
+ 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()