mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 00:08:19 +00:00
lua: vim.rpcrequest, vim.rpcnotify, vim.NIL
This commit is contained in:
@@ -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
|
||||
///
|
||||
|
Reference in New Issue
Block a user