aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-08-04 21:56:29 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-08-05 13:57:24 +0200
commit88938634e7418ced4cfb074c48867523460dcc84 (patch)
tree337a13b6d292efd115856e40ed6e0f935736b59a
parente6d77993d1167f4c15c9f67c0c3281444b1d18c2 (diff)
downloadrneovim-88938634e7418ced4cfb074c48867523460dcc84.tar.gz
rneovim-88938634e7418ced4cfb074c48867523460dcc84.tar.bz2
rneovim-88938634e7418ced4cfb074c48867523460dcc84.zip
lua: add vim.in_fast_event() to check if we are in a luv callback
-rw-r--r--runtime/doc/if_lua.txt11
-rw-r--r--src/nvim/lua/executor.c9
-rw-r--r--test/functional/lua/loop_spec.lua6
3 files changed, 24 insertions, 2 deletions
diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt
index f886fd28c5..7ddcb6cc92 100644
--- a/runtime/doc/if_lua.txt
+++ b/runtime/doc/if_lua.txt
@@ -400,7 +400,8 @@ is safe to execute API methods. >
end))
A subset of the API is available in direct luv callbacks ("fast" callbacks),
-most notably |nvim_get_mode()| and |nvim_input()|.
+most notably |nvim_get_mode()| and |nvim_input()|. It is possible to
+check whether code is running in this context using |vim.in_fast_event()|.
Example: repeating timer
@@ -462,6 +463,14 @@ vim.schedule({callback}) *vim.schedule()*
Schedules {callback} to be invoked soon by the main event-loop. Useful
to avoid |textlock| or other temporary restrictions.
+vim.in_fast_event() *vim.in_fast_event()*
+ Returns true if the code is executing as part of a "fast" event
+ handler, where most of the API is disabled. These are low-level event
+ such as luv callbacks |lua-loop-callbacks|, which can be invoked at
+ any time nvim polls for input. When this returns `false` most API
+ functions are callable, but can be subjected to other restrictions,
+ such as |textlock|.
+
vim.type_idx *vim.type_idx*
Type index for use in |lua-special-tbl|. Specifying one of the
values from |vim.types| allows typing the empty table (it is
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 1f2651e243..4051354d65 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -223,6 +223,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
// schedule
lua_pushcfunction(lstate, &nlua_schedule);
lua_setfield(lstate, -2, "schedule");
+ // in_fast_event
+ lua_pushcfunction(lstate, &nlua_in_fast_event);
+ lua_setfield(lstate, -2, "in_fast_event");
// vim.loop
luv_set_loop(lstate, &main_loop.uv);
@@ -457,6 +460,12 @@ int nlua_debug(lua_State *lstate)
return 0;
}
+int nlua_in_fast_event(lua_State *lstate)
+{
+ lua_pushboolean(lstate, in_fast_callback > 0);
+ return 1;
+}
+
#ifdef WIN32
/// os.getenv: override os.getenv to maintain coherency. #9681
///
diff --git a/test/functional/lua/loop_spec.lua b/test/functional/lua/loop_spec.lua
index b96214738a..992d1666f6 100644
--- a/test/functional/lua/loop_spec.lua
+++ b/test/functional/lua/loop_spec.lua
@@ -75,6 +75,7 @@ describe('vim.loop', function()
exec_lua([[
local timer = vim.loop.new_timer()
timer:start(20, 0, function ()
+ _G.is_fast = vim.in_fast_event()
timer:close()
vim.api.nvim_set_var("valid", true)
vim.api.nvim_command("echomsg 'howdy'")
@@ -89,18 +90,20 @@ describe('vim.loop', function()
{1:~ }|
{2: }|
{3:Error executing luv callback:} |
- {3:[string "<nvim>"]:4: E5560: nvim_set_var must not }|
+ {3:[string "<nvim>"]:5: E5560: nvim_set_var must not }|
{3:be called in a lua loop callback} |
{4:Press ENTER or type command to continue}^ |
]])
feed('<cr>')
eq(false, eval("get(g:, 'valid', v:false)"))
+ eq(true, exec_lua("return _G.is_fast"))
-- callbacks can be scheduled to be executed in the main event loop
-- where the entire API is available
exec_lua([[
local timer = vim.loop.new_timer()
timer:start(20, 0, vim.schedule_wrap(function ()
+ _G.is_fast = vim.in_fast_event()
timer:close()
vim.api.nvim_set_var("valid", true)
vim.api.nvim_command("echomsg 'howdy'")
@@ -120,6 +123,7 @@ describe('vim.loop', function()
howdy |
]])
eq(true, eval("get(g:, 'valid', v:false)"))
+ eq(false, exec_lua("return _G.is_fast"))
-- fast (not deferred) API functions are allowed to be called directly
exec_lua([[