diff options
Diffstat (limited to 'src/nvim/lua')
-rw-r--r-- | src/nvim/lua/converter.c | 16 | ||||
-rw-r--r-- | src/nvim/lua/converter.h | 8 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 59 | ||||
-rw-r--r-- | src/nvim/lua/executor.h | 1 | ||||
-rw-r--r-- | src/nvim/lua/vim.lua | 4 |
5 files changed, 86 insertions, 2 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 69114c967d..9fc4ca7e7e 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -19,6 +19,7 @@ #include "nvim/globals.h" #include "nvim/message.h" #include "nvim/eval/typval.h" +#include "nvim/eval/userfunc.h" #include "nvim/ascii.h" #include "nvim/macros.h" @@ -50,6 +51,7 @@ typedef struct { #define LUA_PUSH_STATIC_STRING(lstate, s) \ lua_pushlstring(lstate, s, sizeof(s) - 1) + static LuaTableProps nlua_traverse_table(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -384,6 +386,20 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) nlua_pop_typval_table_processing_end: break; } + case LUA_TFUNCTION: { + LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState)); + + state->lua_callable.func_ref = nlua_ref(lstate, -1); + + char_u *name = register_cfunc( + &nlua_CFunction_func_call, + &nlua_CFunction_func_free, + state); + + cur.tv->v_type = VAR_FUNC; + cur.tv->vval.v_string = vim_strsave(name); + break; + } case LUA_TUSERDATA: { nlua_pushref(lstate, nlua_nil_ref); bool is_nil = lua_rawequal(lstate, -2, -1); diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 542c56ea3e..e74e3fb084 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -9,6 +9,14 @@ #include "nvim/func_attr.h" #include "nvim/eval.h" +typedef struct { + LuaRef func_ref; +} LuaCallable; + +typedef struct { + LuaCallable lua_callable; +} LuaCFunctionState; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/converter.h.generated.h" #endif diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 4b47b34d8a..5e924a9f90 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -35,8 +35,8 @@ #include "nvim/os/os.h" #endif -#include "nvim/lua/executor.h" #include "nvim/lua/converter.h" +#include "nvim/lua/executor.h" #include "nvim/lua/treesitter.h" #include "luv/luv.h" @@ -833,7 +833,7 @@ void executor_free_luaref(LuaRef ref) nlua_unref(lstate, ref); } -/// push a value referenced in the regirstry +/// push a value referenced in the registry void nlua_pushref(lua_State *lstate, LuaRef ref) { lua_rawgeti(lstate, LUA_REGISTRYINDEX, ref); @@ -933,6 +933,33 @@ static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name, } } +/// Call a LuaCallable given some typvals +int typval_exec_lua_callable( + lua_State *lstate, + LuaCallable lua_cb, + int argcount, + typval_T *argvars, + typval_T *rettv +) +{ + LuaRef cb = lua_cb.func_ref; + + nlua_pushref(lstate, cb); + + for (int i = 0; i < argcount; i++) { + nlua_push_typval(lstate, &argvars[i], false); + } + + if (lua_pcall(lstate, argcount, 1, 0)) { + luaL_error(lstate, "nlua_CFunction_func_call failed."); + return ERROR_OTHER; + } + + nlua_pop_typval(lstate, rettv); + + return ERROR_NONE; +} + /// Execute Lua string /// /// Used for nvim_exec_lua(). @@ -1280,3 +1307,31 @@ static int regex_match_line(lua_State *lstate) return nret; } + +int nlua_CFunction_func_call( + int argcount, + typval_T *argvars, + typval_T *rettv, + void *state) +{ + lua_State *const lstate = nlua_enter(); + LuaCFunctionState *funcstate = (LuaCFunctionState *)state; + + return typval_exec_lua_callable( + lstate, + funcstate->lua_callable, + argcount, + argvars, + rettv); +} +/// Required functions for lua c functions as VimL callbacks +void nlua_CFunction_func_free(void *state) +{ + lua_State *const lstate = nlua_enter(); + LuaCFunctionState *funcstate = (LuaCFunctionState *)state; + + nlua_unref(lstate, funcstate->lua_callable.func_ref); + xfree(funcstate); +} + + diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 3259fc0fa1..6599b44584 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -8,6 +8,7 @@ #include "nvim/func_attr.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/lua/converter.h" // Generated by msgpack-gen.lua void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL; diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 18256242e8..820b237c4f 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -272,6 +272,10 @@ vim.fn = setmetatable({}, { end }) +vim.funcref = function(viml_func_name) + return vim.fn[viml_func_name] +end + -- These are for loading runtime modules lazily since they aren't available in -- the nvim binary as specified in executor.c local function __index(t, key) |