commit dde90f0ca4e394667afe39c18f4a4dabdd8a6666
parent 5928d5c2f11754e1d2cc383a1568c3664a38207d
Author: Javier Lopez <graulopezjavier@gmail.com>
Date: Sun, 21 Aug 2022 08:19:29 -0500
fix(api/command): fargs behavior when no arguments are passed (#19862)
Problem: A command defined with `nargs="?"` returns `fargs={""}` to
a Lua callback when executed with no arguments, which is inconsistent
with how`nargs="*"` behaves.
Solution: Pass `fargs={}` for no argument with `nargs="?"` as well.
Diffstat:
2 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
@@ -1940,8 +1940,13 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview)
// Split args by unescaped whitespace |<f-args>| (nargs dependent)
if (cmd->uc_argt & EX_NOSPC) {
- // Commands where nargs = 1 or "?" fargs is the same as args
- lua_rawseti(lstate, -2, 1);
+ if ((cmd->uc_argt & EX_NEEDARG) || STRLEN(eap->arg)) {
+ // For commands where nargs is 1 or "?" and argument is passed, fargs = { args }
+ lua_rawseti(lstate, -2, 1);
+ } else {
+ // if nargs = "?" and no argument is passed, fargs = {}
+ lua_pop(lstate, 1); // Pop the reference of opts.args
+ }
} else if (eap->args == NULL) {
// For commands with more than one possible argument, split if argument list isn't available.
lua_pop(lstate, 1); // Pop the reference of opts.args
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
@@ -326,7 +326,7 @@ describe('nvim_create_user_command', function()
-- f-args doesn't split when command nargs is 1 or "?"
exec_lua [[
result = {}
- vim.api.nvim_create_user_command('CommandWithOneArg', function(opts)
+ vim.api.nvim_create_user_command('CommandWithOneOrNoArg', function(opts)
result = opts
end, {
nargs = "?",
@@ -366,7 +366,89 @@ describe('nvim_create_user_command', function()
count = 2,
reg = "",
}, exec_lua [[
- vim.api.nvim_command('CommandWithOneArg hello I\'m one argument')
+ vim.api.nvim_command('CommandWithOneOrNoArg hello I\'m one argument')
+ return result
+ ]])
+
+ -- f-args is an empty table if no args were passed
+ eq({
+ args = "",
+ fargs = {},
+ bang = false,
+ line1 = 1,
+ line2 = 1,
+ mods = "",
+ smods = {
+ browse = false,
+ confirm = false,
+ emsg_silent = false,
+ hide = false,
+ keepalt = false,
+ keepjumps = false,
+ keepmarks = false,
+ keeppatterns = false,
+ lockmarks = false,
+ noautocmd = false,
+ noswapfile = false,
+ sandbox = false,
+ silent = false,
+ split = "",
+ tab = 0,
+ unsilent = false,
+ verbose = -1,
+ vertical = false,
+ },
+ range = 0,
+ count = 2,
+ reg = "",
+ }, exec_lua [[
+ vim.api.nvim_command('CommandWithOneOrNoArg')
+ return result
+ ]])
+
+ -- f-args is an empty table when the command nargs=0
+ exec_lua [[
+ result = {}
+ vim.api.nvim_create_user_command('CommandWithNoArgs', function(opts)
+ result = opts
+ end, {
+ nargs = 0,
+ bang = true,
+ count = 2,
+ })
+ ]]
+ eq({
+ args = "",
+ fargs = {},
+ bang = false,
+ line1 = 1,
+ line2 = 1,
+ mods = "",
+ smods = {
+ browse = false,
+ confirm = false,
+ emsg_silent = false,
+ hide = false,
+ keepalt = false,
+ keepjumps = false,
+ keepmarks = false,
+ keeppatterns = false,
+ lockmarks = false,
+ noautocmd = false,
+ noswapfile = false,
+ sandbox = false,
+ silent = false,
+ split = "",
+ tab = 0,
+ unsilent = false,
+ verbose = -1,
+ vertical = false,
+ },
+ range = 0,
+ count = 2,
+ reg = "",
+ }, exec_lua [[
+ vim.cmd('CommandWithNoArgs')
return result
]])