aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua/executor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r--src/nvim/lua/executor.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 0009420281..3ba4d0d70c 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -40,6 +40,7 @@
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/vim.h"
+#include "nvim/window.h"
static int in_fast_callback = 0;
@@ -1839,11 +1840,12 @@ cleanup:
xfree(info);
}
-void nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap)
+/// @param preview Invoke the callback as a |:command-preview| handler.
+int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview)
{
lua_State *const lstate = global_lstate;
- nlua_pushref(lstate, cmd->uc_luaref);
+ nlua_pushref(lstate, preview ? cmd->uc_preview_luaref : cmd->uc_luaref);
lua_newtable(lstate);
lua_pushboolean(lstate, eap->forceit == 1);
@@ -1913,7 +1915,87 @@ void nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap)
lua_pushstring(lstate, buf);
lua_setfield(lstate, -2, "mods");
- if (nlua_pcall(lstate, 1, 0)) {
+ lua_newtable(lstate); // smods table
+
+ lua_pushinteger(lstate, cmdmod.tab);
+ lua_setfield(lstate, -2, "tab");
+
+ lua_pushinteger(lstate, eap->verbose_save != -1 ? p_verbose : -1);
+ lua_setfield(lstate, -2, "verbose");
+
+ if (cmdmod.split & WSP_ABOVE) {
+ lua_pushstring(lstate, "aboveleft");
+ } else if (cmdmod.split & WSP_BELOW) {
+ lua_pushstring(lstate, "belowright");
+ } else if (cmdmod.split & WSP_TOP) {
+ lua_pushstring(lstate, "topleft");
+ } else if (cmdmod.split & WSP_BOT) {
+ lua_pushstring(lstate, "botright");
+ } else {
+ lua_pushstring(lstate, "");
+ }
+ lua_setfield(lstate, -2, "split");
+
+ lua_pushboolean(lstate, cmdmod.split & WSP_VERT);
+ lua_setfield(lstate, -2, "vertical");
+ lua_pushboolean(lstate, eap->save_msg_silent != -1 ? (msg_silent != 0) : 0);
+ lua_setfield(lstate, -2, "silent");
+ lua_pushboolean(lstate, eap->did_esilent);
+ lua_setfield(lstate, -2, "emsg_silent");
+ lua_pushboolean(lstate, eap->did_sandbox);
+ lua_setfield(lstate, -2, "sandbox");
+ lua_pushboolean(lstate, cmdmod.save_ei != NULL);
+ lua_setfield(lstate, -2, "noautocmd");
+
+ typedef struct {
+ bool *set;
+ char *name;
+ } mod_entry_T;
+ static mod_entry_T mod_entries[] = {
+ { &cmdmod.browse, "browse" },
+ { &cmdmod.confirm, "confirm" },
+ { &cmdmod.hide, "hide" },
+ { &cmdmod.keepalt, "keepalt" },
+ { &cmdmod.keepjumps, "keepjumps" },
+ { &cmdmod.keepmarks, "keepmarks" },
+ { &cmdmod.keeppatterns, "keeppatterns" },
+ { &cmdmod.lockmarks, "lockmarks" },
+ { &cmdmod.noswapfile, "noswapfile" }
+ };
+
+ // The modifiers that are simple flags
+ for (size_t i = 0; i < ARRAY_SIZE(mod_entries); i++) {
+ lua_pushboolean(lstate, *mod_entries[i].set);
+ lua_setfield(lstate, -2, mod_entries[i].name);
+ }
+
+ lua_setfield(lstate, -2, "smods");
+
+ if (preview) {
+ lua_pushinteger(lstate, cmdpreview_get_ns());
+
+ handle_T cmdpreview_bufnr = cmdpreview_get_bufnr();
+ if (cmdpreview_bufnr != 0) {
+ lua_pushinteger(lstate, cmdpreview_bufnr);
+ } else {
+ lua_pushnil(lstate);
+ }
+ }
+
+ if (nlua_pcall(lstate, preview ? 3 : 1, preview ? 1 : 0)) {
nlua_error(lstate, _("Error executing Lua callback: %.*s"));
+ return 0;
}
+
+ int retv = 0;
+
+ if (preview) {
+ if (lua_isnumber(lstate, -1) && (retv = (int)lua_tointeger(lstate, -1)) >= 0 && retv <= 2) {
+ lua_pop(lstate, 1);
+ } else {
+ retv = 0;
+ }
+ }
+
+ return retv;
}