mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 06:28:35 +00:00
lua: Add ability to pass lua functions directly to vimL
This commit is contained in:
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user