aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua')
-rw-r--r--src/nvim/lua/converter.c7
-rw-r--r--src/nvim/lua/executor.c87
-rw-r--r--src/nvim/lua/executor.h1
-rw-r--r--src/nvim/lua/spell.c2
-rw-r--r--src/nvim/lua/vim.lua5
5 files changed, 99 insertions, 3 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index b6792a5a97..8a702ddd60 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -1242,7 +1242,12 @@ LuaRef nlua_pop_LuaRef(lua_State *const lstate, Error *err)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
{ \
type ret; \
- ret = (type)lua_tonumber(lstate, -1); \
+ if (lua_type(lstate, -1) != LUA_TNUMBER) { \
+ api_set_error(err, kErrorTypeValidation, "Expected Lua number"); \
+ ret = (type)-1; \
+ } else { \
+ ret = (type)lua_tonumber(lstate, -1); \
+ } \
lua_pop(lstate, 1); \
return ret; \
}
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 107ff22913..c814974fe7 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -18,6 +18,7 @@
#include "nvim/event/loop.h"
#include "nvim/event/time.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/extmark.h"
#include "nvim/func_attr.h"
@@ -433,6 +434,15 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
// [package, loaded, module]
lua_setfield(lstate, -2, "vim.F"); // [package, loaded]
+ code = (char *)&lua_filetype_module[0];
+ if (luaL_loadbuffer(lstate, code, sizeof(lua_filetype_module) - 1, "@vim/filetype.lua")
+ || nlua_pcall(lstate, 0, 1)) {
+ nlua_error(lstate, _("E5106: Error while creating vim.filetype module: %.*s"));
+ return 1;
+ }
+ // [package, loaded, module]
+ lua_setfield(lstate, -2, "vim.filetype"); // [package, loaded]
+
lua_pop(lstate, 2); // []
}
@@ -914,6 +924,24 @@ void nlua_typval_call(const char *str, size_t len, typval_T *const args, int arg
}
}
+void nlua_call_user_expand_func(expand_T *xp, typval_T *ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_State *const lstate = global_lstate;
+
+ nlua_pushref(lstate, xp->xp_luaref);
+ lua_pushstring(lstate, (char *)xp->xp_pattern);
+ lua_pushstring(lstate, (char *)xp->xp_line);
+ lua_pushinteger(lstate, xp->xp_col);
+
+ if (nlua_pcall(lstate, 3, 1)) {
+ nlua_error(lstate, _("E5108: Error executing Lua function: %.*s"));
+ return;
+ }
+
+ nlua_pop_typval(lstate, ret_tv);
+}
+
static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name,
typval_T *const args, int argcount, bool special, typval_T *ret_tv)
{
@@ -1096,11 +1124,23 @@ void ex_lua(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
size_t len;
- char *const code = script_get(eap, &len);
+ char *code = script_get(eap, &len);
if (eap->skip) {
xfree(code);
return;
}
+ // When =expr is used transform it to print(vim.inspect(expr))
+ if (code[0] == '=') {
+ len += sizeof("print(vim.inspect())") - sizeof("=");
+ // code_buf needs to be 1 char larger then len for null byte in the end.
+ // lua nlua_typval_exec doesn't expect null terminated string so len
+ // needs to end before null byte.
+ char *code_buf = xmallocz(len);
+ vim_snprintf(code_buf, len+1, "print(vim.inspect(%s))", code+1);
+ xfree(code);
+ code = code_buf;
+ }
+
nlua_typval_exec(code, len, ":lua", NULL, 0, false, NULL);
xfree(code);
@@ -1432,3 +1472,48 @@ void nlua_execute_on_key(int c)
#endif
}
+void nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap)
+{
+ lua_State *const lstate = global_lstate;
+
+ nlua_pushref(lstate, cmd->uc_luaref);
+
+ lua_newtable(lstate);
+ lua_pushboolean(lstate, eap->forceit == 1);
+ lua_setfield(lstate, -2, "bang");
+
+ lua_pushinteger(lstate, eap->line1);
+ lua_setfield(lstate, -2, "line1");
+
+ lua_pushinteger(lstate, eap->line2);
+ lua_setfield(lstate, -2, "line2");
+
+ lua_pushstring(lstate, (const char *)eap->arg);
+ lua_setfield(lstate, -2, "args");
+
+ lua_pushstring(lstate, (const char *)&eap->regname);
+ lua_setfield(lstate, -2, "reg");
+
+ lua_pushinteger(lstate, eap->addr_count);
+ lua_setfield(lstate, -2, "range");
+
+ if (eap->addr_count > 0) {
+ lua_pushinteger(lstate, eap->line2);
+ } else {
+ lua_pushinteger(lstate, cmd->uc_def);
+ }
+ lua_setfield(lstate, -2, "count");
+
+ // The size of this buffer is chosen empirically to be large enough to hold
+ // every possible modifier (with room to spare). If the list of possible
+ // modifiers grows this may need to be updated.
+ char buf[200] = { 0 };
+ (void)uc_mods(buf);
+ lua_pushstring(lstate, buf);
+ lua_setfield(lstate, -2, "mods");
+
+ if (nlua_pcall(lstate, 1, 0)) {
+ nlua_error(lstate, _("Error executing Lua callback: %.*s"));
+ }
+}
+
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index a1f66bd02b..bf78f7ec5e 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -7,6 +7,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds_defs.h"
+#include "nvim/ex_docmd.h"
#include "nvim/func_attr.h"
#include "nvim/lua/converter.h"
diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c
index b84124bc19..3a63f61200 100644
--- a/src/nvim/lua/spell.c
+++ b/src/nvim/lua/spell.c
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <lua.h>
#include <lauxlib.h>
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index c1a1e7f162..6ef46ee844 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -40,6 +40,9 @@ assert(vim)
vim.inspect = package.loaded['vim.inspect']
assert(vim.inspect)
+vim.filetype = package.loaded['vim.filetype']
+assert(vim.filetype)
+
local pathtrails = {}
vim._so_trails = {}
for s in (package.cpath..';'):gmatch('[^;]*;') do
@@ -424,7 +427,7 @@ end
--- Without a runtime, writes to :Messages
---@see :help nvim_notify
---@param msg string Content of the notification to show to the user
----@param log_level number|nil enum from vim.log.levels
+---@param log_level number|nil enum from |vim.log.levels|
---@param opts table|nil additional options (timeout, etc)
function vim.notify(msg, log_level, opts) -- luacheck: no unused
if log_level == vim.log.levels.ERROR then