aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaehwang Jung <tomtomjhj@gmail.com>2024-04-20 02:33:44 +0900
committerChristian Clason <c.clason@uni-graz.at>2024-04-21 10:42:00 +0200
commit2b6c9bbe7f7ac950683e81129b76e35e35839ede (patch)
tree901e6110c7d7c8e8bc0c4e1cade28c7052bda815 /src
parentf42ab1dc4848eceab12c7180c2b9049da29a9ba6 (diff)
downloadrneovim-2b6c9bbe7f7ac950683e81129b76e35e35839ede.tar.gz
rneovim-2b6c9bbe7f7ac950683e81129b76e35e35839ede.tar.bz2
rneovim-2b6c9bbe7f7ac950683e81129b76e35e35839ede.zip
perf(treesitter): incremental foldupdate
Problem: While the fold level computation is incremental, the evaluation of the foldexpr is done on the full buffer. Despite that the foldexpr reads from the cache, it can take tens of milliseconds for moderately big (10K lines) buffers. Solution: Track the range of lines on which the foldexpr should be evaluated.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/lua/stdlib.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index 788185f2b4..032cb246bf 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -543,14 +543,25 @@ static int nlua_iconv(lua_State *lstate)
return 1;
}
-// Update foldlevels (e.g., by evaluating 'foldexpr') for all lines in the current window without
-// invoking other side effects. Unlike `zx`, it does not close manually opened folds and does not
-// open folds under the cursor.
+// Update foldlevels (e.g., by evaluating 'foldexpr') for the given line range in the given window,
+// without invoking other side effects. Unlike `zx`, it does not close manually opened folds and
+// does not open folds under the cursor.
static int nlua_foldupdate(lua_State *lstate)
{
- curwin->w_foldinvalid = true; // recompute folds
- foldUpdate(curwin, 1, (linenr_T)MAXLNUM);
- curwin->w_foldinvalid = false;
+ handle_T window = (handle_T)luaL_checkinteger(lstate, 1);
+ Error err = ERROR_INIT;
+ win_T *win = find_window_by_handle(window, &err);
+ if (ERROR_SET(&err)) {
+ nlua_push_errstr(lstate, err.msg);
+ api_clear_error(&err);
+ lua_error(lstate);
+ return 0;
+ }
+
+ linenr_T start = (linenr_T)luaL_checkinteger(lstate, 2);
+ linenr_T end = (linenr_T)luaL_checkinteger(lstate, 3);
+
+ foldUpdate(win, start + 1, end);
return 0;
}