diff options
author | Andrey Popp <8mayday@gmail.com> | 2019-01-24 19:52:05 +0300 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-06-05 10:42:23 +0200 |
commit | 81e1dbca99c1485ab28ecb2c46d8d71a61bdb35d (patch) | |
tree | 1540fb6f1179f41eced66dabe6bad3c828d720d4 /src/nvim/lua/executor.c | |
parent | 16ee24082f72162d3bdfbddb0b40b5abc2c90fda (diff) | |
download | rneovim-81e1dbca99c1485ab28ecb2c46d8d71a61bdb35d.tar.gz rneovim-81e1dbca99c1485ab28ecb2c46d8d71a61bdb35d.tar.bz2 rneovim-81e1dbca99c1485ab28ecb2c46d8d71a61bdb35d.zip |
lua: add vim.schedule(cb)
This executes Lua callback on main loop's event queue so that nvim API
is safe to call.
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r-- | src/nvim/lua/executor.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index fa8a67ff39..1c1d51a10a 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -36,6 +36,12 @@ typedef struct { String lua_err_str; } LuaError; +/// We use this to store Lua callbacks +typedef struct { + // TODO: store more info for debugging, traceback? + int cb; +} nlua_ctx; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/vim_module.generated.h" # include "lua/executor.c.generated.h" @@ -108,6 +114,36 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 1; } +static void nlua_schedule_cb(void **argv) +{ + nlua_ctx *ctx = argv[0]; + lua_State *const lstate = nlua_enter(); + lua_rawgeti(lstate, LUA_REGISTRYINDEX, ctx->cb); + luaL_unref(lstate, LUA_REGISTRYINDEX, ctx->cb); + lua_pcall(lstate, 0, 0, 0); + free(ctx); +} + +/// Schedule Lua callback on main loop's event queue +/// +/// This is used to make sure nvim API is called at the right moment. +/// +/// @param lstate Lua interpreter state. +/// @param[in] msg Message base, must contain one `%s`. +static int nlua_schedule(lua_State *const lstate) + FUNC_ATTR_NONNULL_ALL +{ + // TODO: report error using nlua_error instead + luaL_checktype(lstate, 1, LUA_TFUNCTION); + + nlua_ctx* ctx = (nlua_ctx*)malloc(sizeof(nlua_ctx)); + lua_pushvalue(lstate, 1); + ctx->cb = luaL_ref(lstate, LUA_REGISTRYINDEX); + + multiqueue_put(main_loop.events, nlua_schedule_cb, 1, ctx); + return 0; +} + /// Initialize lua interpreter state /// /// Called by lua interpreter itself to initialize state. @@ -143,6 +179,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL // stricmp lua_pushcfunction(lstate, &nlua_stricmp); lua_setfield(lstate, -2, "stricmp"); + // schedule + lua_pushcfunction(lstate, &nlua_schedule); + lua_setfield(lstate, -2, "schedule"); lua_setglobal(lstate, "vim"); return 0; |