diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-10-27 20:49:03 +0100 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-11-10 13:08:05 +0100 |
commit | 474d0bcbf724c7eed740f60391a0ed35d651e1d3 (patch) | |
tree | 2a609072157fd975cea1d5f0c4c99ebdd0eca2c3 /src/nvim/lua/executor.c | |
parent | 5689008060d29dd7b45157a8f82cb96018c284e8 (diff) | |
download | rneovim-474d0bcbf724c7eed740f60391a0ed35d651e1d3.tar.gz rneovim-474d0bcbf724c7eed740f60391a0ed35d651e1d3.tar.bz2 rneovim-474d0bcbf724c7eed740f60391a0ed35d651e1d3.zip |
lua: vim.rpcrequest, vim.rpcnotify, vim.NIL
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r-- | src/nvim/lua/executor.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index c7ff163f83..5e5cb0cea5 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -12,6 +12,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/vim.h" #include "nvim/ex_getln.h" #include "nvim/ex_cmds2.h" @@ -299,6 +300,14 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, &nlua_call); lua_setfield(lstate, -2, "call"); + // rpcrequest + lua_pushcfunction(lstate, &nlua_rpcrequest); + lua_setfield(lstate, -2, "rpcrequest"); + + // rpcnotify + lua_pushcfunction(lstate, &nlua_rpcnotify); + lua_setfield(lstate, -2, "rpcnotify"); + // vim.loop luv_set_loop(lstate, &main_loop.uv); luv_set_callback(lstate, nlua_luv_cfpcall); @@ -314,6 +323,15 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_setfield(lstate, -2, "luv"); lua_pop(lstate, 3); + // vim.NIL + lua_newuserdata(lstate, 0); + lua_createtable(lstate, 0, 0); + lua_pushcfunction(lstate, &nlua_nil_tostring); + lua_setfield(lstate, -2, "__tostring"); + lua_setmetatable(lstate, -2); + nlua_nil_ref = nlua_ref(lstate, -1); + lua_setfield(lstate, -2, "NIL"); + // internal vim._treesitter... API nlua_add_treesitter(lstate); @@ -547,6 +565,10 @@ int nlua_call(lua_State *lstate) Error err = ERROR_INIT; size_t name_len; const char_u *name = (const char_u *)luaL_checklstring(lstate, 1, &name_len); + if (!nlua_is_deferred_safe(lstate)) { + return luaL_error(lstate, e_luv_api_disabled, "vimL function"); + } + int nargs = lua_gettop(lstate)-1; if (nargs > MAX_FUNC_ARGS) { return luaL_error(lstate, "Function called with too many arguments"); @@ -596,6 +618,67 @@ free_vim_args: return 1; } +static int nlua_rpcrequest(lua_State *lstate) +{ + if (!nlua_is_deferred_safe(lstate)) { + return luaL_error(lstate, e_luv_api_disabled, "rpcrequest"); + } + return nlua_rpc(lstate, true); +} + +static int nlua_rpcnotify(lua_State *lstate) +{ + return nlua_rpc(lstate, false); +} + +static int nlua_rpc(lua_State *lstate, bool request) +{ + size_t name_len; + uint64_t chan_id = (uint64_t)luaL_checkinteger(lstate, 1); + const char *name = luaL_checklstring(lstate, 2, &name_len); + int nargs = lua_gettop(lstate)-2; + Error err = ERROR_INIT; + Array args = ARRAY_DICT_INIT; + + for (int i = 0; i < nargs; i++) { + lua_pushvalue(lstate, (int)i+3); + ADD(args, nlua_pop_Object(lstate, false, &err)); + if (ERROR_SET(&err)) { + api_free_array(args); + goto check_err; + } + } + + if (request) { + Object result = rpc_send_call(chan_id, name, args, &err); + if (!ERROR_SET(&err)) { + nlua_push_Object(lstate, result, false); + api_free_object(result); + } + } else { + if (!rpc_send_event(chan_id, name, args)) { + api_set_error(&err, kErrorTypeValidation, + "Invalid channel: %"PRIu64, chan_id); + } + } + +check_err: + if (ERROR_SET(&err)) { + lua_pushstring(lstate, err.msg); + api_clear_error(&err); + return lua_error(lstate); + } + + return request ? 1 : 0; +} + +static int nlua_nil_tostring(lua_State *lstate) +{ + lua_pushstring(lstate, "vim.NIL"); + return 1; +} + + #ifdef WIN32 /// os.getenv: override os.getenv to maintain coherency. #9681 /// |