aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua')
-rw-r--r--src/nvim/lua/converter.c16
-rw-r--r--src/nvim/lua/converter.h8
-rw-r--r--src/nvim/lua/executor.c59
-rw-r--r--src/nvim/lua/executor.h1
-rw-r--r--src/nvim/lua/vim.lua4
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)