diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index a79b26dfb0..a35d70cae8 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1143,6 +1143,8 @@ vim.wait({time}, {callback}, {interval}, {fast_only}) *vim.wait()* milliseconds (default 200). Nvim still processes other events during this time. + Cannot be called while in an |api-fast| event. + Examples: >lua --- -- Wait for 100 ms, allowing other events to process @@ -1173,8 +1175,7 @@ vim.wait({time}, {callback}, {interval}, {fast_only}) *vim.wait()* • {interval} (integer|nil) (Approximate) number of milliseconds to wait between polls • {fast_only} (boolean|nil) If true, only |api-fast| events will be - processed. If called from while in an |api-fast| event, - will automatically be set to `true`. + processed. Return: ~ boolean, nil|-1|-2 @@ -1828,7 +1829,8 @@ vim.system({cmd}, {opts}, {on_exit}) *vim.system()* • pid (integer) Process ID • wait (fun(timeout: integer|nil): SystemCompleted) Wait for the process to complete. Upon timeout the process is sent the KILL - signal (9) and the exit code is set to 124. + signal (9) and the exit code is set to 124. Cannot be called in + |api-fast|. • SystemCompleted is an object with the fields: • code: (integer) • signal: (integer) diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index b5bef13325..825e5ba41f 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -325,6 +325,8 @@ The following changes to existing APIs or features add new behavior. NOTE: the regexp engine still has a hard-coded limit of considering 6 composing chars only. +• |vim.wait()| is no longer allowed to be called in |api-fast|. + ============================================================================== REMOVED FEATURES *news-removed* diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 12b632075d..6cccbe8313 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -124,7 +124,8 @@ vim.log = { --- @return vim.SystemObj Object with the fields: --- - pid (integer) Process ID --- - wait (fun(timeout: integer|nil): SystemCompleted) Wait for the process to complete. Upon ---- timeout the process is sent the KILL signal (9) and the exit code is set to 124. +--- timeout the process is sent the KILL signal (9) and the exit code is set to 124. Cannot +--- be called in |api-fast|. --- - SystemCompleted is an object with the fields: --- - code: (integer) --- - signal: (integer) diff --git a/runtime/lua/vim/_meta/builtin.lua b/runtime/lua/vim/_meta/builtin.lua index 92c23f7764..eeba356672 100644 --- a/runtime/lua/vim/_meta/builtin.lua +++ b/runtime/lua/vim/_meta/builtin.lua @@ -205,6 +205,8 @@ function vim.schedule(fn) end --- milliseconds (default 200). Nvim still processes other events during --- this time. --- +--- Cannot be called while in an |api-fast| event. +--- --- Examples: --- --- ```lua @@ -235,8 +237,6 @@ function vim.schedule(fn) end --- @param callback? fun(): boolean Optional callback. Waits until {callback} returns true --- @param interval? integer (Approximate) number of milliseconds to wait between polls --- @param fast_only? boolean If true, only |api-fast| events will be processed. ---- If called from while in an |api-fast| event, will ---- automatically be set to `true`. --- @return boolean, nil|-1|-2 --- - If {callback} returns `true` during the {time}: `true, nil` --- - If {callback} never returns `true` during the {time}: `false, -1` diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index ce2a247a6f..04eda99d17 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -411,6 +411,10 @@ static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_r static int nlua_wait(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { + if (in_fast_callback) { + return luaL_error(lstate, e_luv_api_disabled, "vim.wait"); + } + intptr_t timeout = luaL_checkinteger(lstate, 1); if (timeout < 0) { return luaL_error(lstate, "timeout must be >= 0"); @@ -449,8 +453,7 @@ static int nlua_wait(lua_State *lstate) fast_only = lua_toboolean(lstate, 4); } - MultiQueue *loop_events = fast_only || in_fast_callback > 0 - ? main_loop.fast_events : main_loop.events; + MultiQueue *loop_events = fast_only ? main_loop.fast_events : main_loop.events; TimeWatcher *tw = xmalloc(sizeof(TimeWatcher)); diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 1533a1823f..61fa16f59d 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -2769,6 +2769,19 @@ describe('lua stdlib', function() eq({'notification', 'wait', {-2}}, next_msg(500)) end) end) + + it('should not run in fast callbacks #26122', function() + exec_lua([[ + vim.uv.new_timer():start(0, 100, function() + local count = 0 + vim.wait(100, function() + count = count + 1 + return count == 10 + end, 100) + end) + ]]) + assert_alive() + end) end) it('vim.notify_once', function()