Skip to content

Allow user commands to handle completion argument as a whole (add -nargs=_ command argument)#20189

Open
habamax wants to merge 7 commits into
vim:masterfrom
habamax:nargs_
Open

Allow user commands to handle completion argument as a whole (add -nargs=_ command argument)#20189
habamax wants to merge 7 commits into
vim:masterfrom
habamax:nargs_

Conversation

@habamax
Copy link
Copy Markdown
Contributor

@habamax habamax commented May 11, 2026

Problem: User commands with a single argument can't complete argument with unescaped spaces.

Solution: Add -nargs=_ command argument to not split command argument on white spaces for the completion purposes.

The difference between the -nargs=1 and -nargs=_:

func MyComplete(ArgLead, CmdLine, CursorPos)
  return ["one value", "two values", "three values"]->matchfuzzy(a:ArgLead)
endfunc
:command -nargs=1 -complete=customlist,MyComplete MyCmd1 echo <q-args>
:command -nargs=_ -complete=customlist,MyComplete MyCmd2 echo <q-args>

Completing :MyCmd1 two va<tab> will complete with:

:MyCmd1 two one value

Completing :MyCmd2 two va<tab> will complete with:

:MyCmd2 two values

Relates

It should allow user commands to have a single argument with spaces.

For example given the following Test command and TestComplete function:

vim9script
def TestComplete(A: string, _: string, _: number): list<string>
    var all = ["qqqq", "aaaa", "qq aa"]
    return all->matchfuzzy(A)
enddef
command! -nargs=_ -complete=customlist,TestComplete Test echo <q-args>

`:Test q a<tab>` should successfully complete `qq aa`

Relates vim#20102
habamax added 5 commits May 12, 2026 10:54
to make following test pass

  command! -nargs=_ -complete=arglist DoCmd :
  call assert_equal("\n    Name              Args Address Complete    Definition"
        \        .. "\n    DoCmd             _            arglist     :",
        \           execute('command DoCmd'))
@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 12, 2026

I think this is ready.

@chrisbra @mattn @brianhuster

@habamax habamax marked this pull request as ready for review May 12, 2026 02:18
@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 12, 2026

If this is accepted, @dkearns could you pls handle this in vim's syntax?

image

@dkearns
Copy link
Copy Markdown
Contributor

dkearns commented May 12, 2026

I haven't thought about this enough to come up with a strong option but there's no reason that the -nargs value has to be a single character. I think even something like 1s might be better?

@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 12, 2026

I haven't thought about this enough to come up with a strong option but there's no reason that the -nargs value has to be a single character. I think even something like 1s might be better?

The reason is current implementation -- it expects 1 char throughout the codebase for the -nargs and to make it arbitrary(or 2) length there would need to be quite a bit of code created.

@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 12, 2026

But if 1s would be something that @chrisbra and the team agree on, I will try to make it.

Not too much of the code I guess contrary to my prev message.

len arithmetic here:

case (EX_EXTRA|EX_NEEDARG|EX_ARGSPACE): IObuff[len++] = '_'; break;

and

parsing here

	else if (*val == '_')
		    *argt |= (EX_EXTRA | EX_NEEDARG | EX_ARGSPACE);

Still 1 letter is simpler :)

@chrisbra
Copy link
Copy Markdown
Member

I don't have a strong opinion, all seem to be rather magic :)

@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 12, 2026

Let it be _ then.

@habamax habamax changed the title add -nargs=_ command argument Allow user commands to handle completion argument as a whole (add -nargs=_ command argument) May 12, 2026
Copy link
Copy Markdown
Member

@chrisbra chrisbra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I think we need the EX_NOSPC in the definition for the _ case, otherwise the <f-args> are not correctly parsed (see the new test suggested).

Comment thread src/usercmd.c Outdated
Comment thread src/testdir/test_usercommands.vim
Comment thread runtime/doc/map.txt Outdated
Comment thread src/usercmd.c Outdated
@habamax
Copy link
Copy Markdown
Contributor Author

habamax commented May 16, 2026

@chrisbra done.

Failing test is unrelated to the changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants