diff options
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r-- | src/nvim/lua/executor.c | 88 |
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; } |