diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-08-04 21:56:29 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-08-05 13:57:24 +0200 |
commit | 88938634e7418ced4cfb074c48867523460dcc84 (patch) | |
tree | 337a13b6d292efd115856e40ed6e0f935736b59a | |
parent | e6d77993d1167f4c15c9f67c0c3281444b1d18c2 (diff) | |
download | rneovim-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.txt | 11 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 9 | ||||
-rw-r--r-- | test/functional/lua/loop_spec.lua | 6 |
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([[ |