[vim/vim] User command completion: allow spaces in a single argument command (Issue #20102)

18 views
Skip to first unread message

Maxim Kim

unread,
Apr 30, 2026, 2:57:37 AM (11 days ago) Apr 30
to vim/vim, Subscribed
habamax created an issue (vim/vim#20102)

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.

There is no way to setup user command completion that work with an argument containing spaces.

def TestComplete(_, _, _): string
    return "hello world\nanother world"
enddef

command! -nargs=1 -complete=custom,TestComplete Test echo <q-args>

In this example, there is no way to filter out candidates using argument with spaces:

https://asciinema.org/a/gjn2FeJhpsEM3xFd

:Test he world shows 2 candidates instead of a single hello world

Describe the solution you'd like

It would be nice if a command has a single argument (-nargs=1) to let it complete against whole arg string, akin to what <q-args> has.

Describe alternatives you've considered
none.

Additional context
Completion with :find and findfunc works fine with argument and spaces but my user commands that provide similar things (recent files, projects, buffer names etc) do not allow this.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102@github.com>

Maxim Kim

unread,
Apr 30, 2026, 3:07:27 AM (11 days ago) Apr 30
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

Real world example with custom :Unicode command and PLUS SIGN WITH DOT BELOW -- I might remember partial words but not the order of the words. Usually fuzzy matching can take care of it but it is impossible to feed it the whole argument with spaces:

https://asciinema.org/a/JukrGDkRVN3G9ppw


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4350366329@github.com>

mattn

unread,
May 10, 2026, 9:18:19 AM (yesterday) May 10
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

Hi @habamax — I think the premise of this issue is slightly off.

1. With -nargs=1, the whole argument (spaces and all) is already passed to the completion function as ArgLead. In your example, a:ArgLead is "he world", not "world" — you can verify with echom a:ArgLead inside TestComplete.

2. The "2 candidates" result is the correct fuzzy behavior. With 'wildoptions' containing fuzzy, matching he world is effectively h.*e.* .*w.*o.*r.*l.*d, and another world does contain those characters in that order (a-n-o-t-[h]-[e]-r-[ ]-[w]-[o]-[r]-[l]-[d]). So matching both is exactly what fuzzy is defined to do.

3. If you want stricter filtering, use -complete=customlist instead. Unlike custom, it does not post-filter the returned list, so you can implement whatever match logic you like:

def TestComplete(A: string, _: string, _: number): list<string>
    var all = ["hello world", "another world"]
    return all->filter((_, v) => v =~ '\V' .. escape(A, '\'))
enddef
command! -nargs=1 -complete=customlist,TestComplete Test echo <q-args>

This already covers the asciinema use case, so I think this can be closed.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4415380169@github.com>

Christian Brabandt

unread,
May 10, 2026, 11:30:07 AM (yesterday) May 10
to vim/vim, Subscribed

Closed #20102 as completed.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/20102/issue_event/25355129210@github.com>

Christian Brabandt

unread,
May 10, 2026, 11:30:12 AM (yesterday) May 10
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#20102)

thanks, closing therefore


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4415651658@github.com>

Maxim Kim

unread,
May 10, 2026, 5:04:04 PM (19 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

The issue is not about what argument command gets, but what is completed. Completion is restarted after space is pressed.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4416341070@github.com>

Maxim Kim

unread,
May 10, 2026, 7:10:34 PM (17 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

@mattn, the issue is that command completion not the command argument received by a command.

Let's simplify the example you provided, giving 2 values to complete from qqqq and aaaa:

def TestComplete(A: string, _: string, _: number): list<string>
    var all = ["qqqq", "aaaa"]
    return all->filter((_, v) => v =~ '\V' .. escape(A, '\'))
enddef
command! -nargs=1 -complete=customlist,TestComplete Test echo <q-args>

Now if you do :Test q a<TAB> you'll have aaaa in completion menu instead of nothing as q a is not in the completion candidates list.

image.png (view on web)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4416587303@github.com>

Maxim Kim

unread,
May 10, 2026, 7:27:12 PM (17 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

Now if we wrap the same complete function into findfunc we get desired outcome:

def TestComplete(A: string, _): list<string>
    var all = ["qqqq", "aaaa"]
    return all->filter((_, v) => v =~ '\V' .. escape(A, '\'))
enddef
set findfunc=TestComplete
  • :find q a<tab> -- no completion menu as expected
image.png (view on web)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4416618326@github.com>

mattn

unread,
May 10, 2026, 10:02:41 PM (14 hours ago) May 10
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

The completion layer always splits on unescaped whitespace and passes only the last token as ArgLead, regardless of the -nargs value. -nargs only controls how many arguments the command accepts at invocation time (and how <args> / <q-args> expand) — it does not change how ArgLead is sliced.

If you want to keep a space inside a single argument, escape it on the command line — :Test q\ a<Tab> — the same convention as filename completion (:edit foo\ bar.txt). Then ArgLead becomes q\ a as a whole and your filter works as expected.

findfunc behaves differently because it is dedicated to taking a single file path and uses a different code path, not because of -nargs semantics.

Does this cover your use case, or is there something else you would like to see changed?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417032523@github.com>

Maxim Kim

unread,
May 10, 2026, 10:34:37 PM (13 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

Yes I understand the difference with findfunc (which worked the same in linux until we have removed SPACE_IN_FILENAME) and the request was about making user command to work the same if it only accepts a single argument. So that if I have command -nargs=1 ... it would not treat a space as an argument separation by default just because there is only 1 argument accepted anyways.

I was looking into:

https://github.com/vim/vim/blob/master/src/usercmd.c#L348-L356

I wonder if there is a way to detect there that a user command accepts a single argument.

If you want to keep a space inside a single argument, escape it on the command line — :Test q\ a

Indeed, however it would be way more convenient not to escape a space for a user command that only accepts a single argument.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417131042@github.com>

mattn

unread,
May 10, 2026, 11:06:49 PM (13 hours ago) May 10
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

For reference, Vim already provides a way to pass a space-containing string as a single ArgLead regardless of the -nargs value — escaping with \ (:Test he\ wo<Tab> passes he\ wo as ArgLead). Changing the behavior of -nargs=1 to drop this splitting would break that established convention and any existing custom completions that rely on it. Instead, introducing a separate identifier such as -nargs=_, meaning "the command takes the entire rest of the line as one argument," would give you the behavior you're after without breaking the existing contract — users who want it can opt in explicitly.

Separately, the fact that customlist items containing spaces are inserted into the cmdline without escaping is its own issue. That's better solved with a different opt-in mechanism (e.g. a third field like -complete=customlist,Func,escape) and tracked as a separate item.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417259796@github.com>

Maxim Kim

unread,
May 10, 2026, 11:26:13 PM (13 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

Instead, introducing a separate identifier such as -nargs=_, meaning "the command takes the entire rest of the line as one argument," would give you the behavior you're after without breaking the existing contract — users who want it can opt in explicitly.

Yes, this explicit -nargs=_ would be better.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417323866@github.com>

mattn

unread,
May 10, 2026, 11:44:28 PM (12 hours ago) May 10
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

@chrisbra what's your preference here — should the space-escaping be the default behavior for customlist insertion (matching file completion), or opt-in via a third field like -complete=customlist,Func,escape? Making it the default is cleaner for new users, though it could in theory double-escape if any existing customlist function already returns \-escaped strings (I'm not sure if such users actually exist). Opt-in keeps full backward compatibility either way at the cost of one extra step.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417443353@github.com>

Maxim Kim

unread,
May 10, 2026, 11:51:42 PM (12 hours ago) May 10
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

Could you check #20189 if the approach with -nargs=_ would be OK?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4417480434@github.com>

K.Takata

unread,
12:39 AM (11 hours ago) 12:39 AM
to vim/vim, Subscribed

Reopened #20102.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/20102/issue_event/25365864573@github.com>

Christian Brabandt

unread,
3:57 AM (8 hours ago) 3:57 AM
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#20102)

-nargs=_ is a bit obscure, isn't it? But I cannot think of something better right now, so it must be good documented.

Regarding this:

@chrisbra what's your preference here — should the space-escaping be the default behavior for customlist insertion (matching file completion), or opt-in via a third field like -complete=customlist,Func,escape? Making it the default is cleaner for new users, though it could in theory double-escape if any existing customlist function already returns -escaped strings (I'm not sure if such users actually exist). Opt-in keeps full backward compatibility either way at the cost of one extra step.

I think the -complete=customlist,Func,escape makes more sense while giving the users the flexibility they need.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4418611863@github.com>

Maxim Kim

unread,
4:23 AM (8 hours ago) 4:23 AM
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

@chrisbra what's your preference here — should the space-escaping be the default behavior for customlist insertion (matching file completion),

Let’s keep current space insertion for customlist please. Opt-in is fine and backward compatible.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4418787312@github.com>

Phạm Bình An

unread,
4:53 AM (7 hours ago) 4:53 AM
to vim/vim, Subscribed
brianhuster left a comment (vim/vim#20102)

Related: #19294


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4418989090@github.com>

mattn

unread,
5:49 AM (6 hours ago) 5:49 AM
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

Currently, I'm implementing -completeopt=escape. Maybe this fix your problems.

https://github.com/user-attachments/assets/48c77c79-d433-435e-8a43-a6874d280998


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4419415211@github.com>

Maxim Kim

unread,
6:52 AM (5 hours ago) 6:52 AM
to vim/vim, Subscribed
habamax left a comment (vim/vim#20102)

No it wouldn’t, unfortunately.

The specific need is to be able to leverage fuzzy algorithm that works with patterns separated with spaces in user command completions.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4419957446@github.com>

mattn

unread,
7:35 AM (4 hours ago) 7:35 AM
to vim/vim, Subscribed
mattn left a comment (vim/vim#20102)

I don't understand what you need. Could you please expain?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/20102/4420296028@github.com>

Reply all
Reply to author
Forward
0 new messages