Currently, when a user command uses -complete=custom or -complete=customlist and the completion function returns a match containing spaces or backslashes, those characters are inserted into the command line as-is and the argument splitter treats them as separate arguments. Plugin authors have had to work around this by parsing getcmdline() themselves to reconstruct the intended single argument, which is fragile and repetitive.
This adds a new -completeopt=escape attribute that escapes spaces and backslashes when the selected match is inserted, while keeping the unescaped form for the popup menu, wildmenu and getcompletion(). ArgLead passed to the completion function is also unescaped, so the function continues to see the logical argument. Plugins that opt in can stop hand-rolling their own quoting/parsing logic.
Tests in Test_command_completeopt_escape cover customlist/custom insertion of spaces and backslashes, the no-escape baseline, getcompletion() returning the unescaped form, ArgLead unescaping, Tab-completion of the attribute value, and E475/E179 errors for invalid/empty values.
https://github.com/vim/vim/pull/20239
(7 files)
—
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.![]()
-nargs=_)v9.2.0494 (merged from #20189 about 15 hours before this PR was opened) already addresses the same underlying problem — "custom/customlist completion cannot return matches with spaces" — via -nargs=_. Could you clarify how this PR is meant to coexist with it?
Specifically:
-nargs=_ solves it by disabling the argument splitter during completion (single argument, no escaping needed). The match is inserted verbatim and <q-args> returns it as-is.-completeopt=escape solves it by keeping the splitter and inserting a backslash-escaped form. <q-args> then returns the unescaped value.From a user's point of view this introduces two attributes that overlap heavily for the most common case (single argument with spaces), and the <q-args> semantics differ between the two — a plugin author now has to know which mechanism a given command was defined with.
Questions:
-nargs=_ and -completeopt=escape? Is the latter only meant for the narrower case of multiple arguments where each may contain spaces?:help :command-completeopt, and to note in :help :command-nargs that -nargs=_ should be preferred for the single-argument case?-nargs=_ cannot handle would help motivate the addition.Without that justification, the simpler path is to keep -nargs=_ as the single mechanism and close this PR.
—
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.![]()
@mattn pushed 1 commit.
—
View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
The two features address different shapes of the problem.
-nargs=_ treats the entire argument area as a single "line" exactly as typed — even if it contains spaces, it is one value. That is the right tool when you want to take the visible line, as-is, as a single argument.
-completeopt=escape is for the multi-argument case (-nargs=+, -nargs=*, etc.) where the splitter must keep working but an individual argument may itself contain spaces. The completion result foo bar is inserted as foo\ bar so the splitter still sees it as one argument, while ArgLead is passed to the completion function as the unescaped foo bar so the function works with the logical value.
Concrete example:
func MyComplete(ArgLead, CmdLine, CursorPos) return ["one value", "two values", "three values"]->matchfuzzy(a:ArgLead) endfunc command -nargs=+ -complete=customlist,MyComplete -completeopt=escape MyCmd echo <f-args>
Completing :MyCmd one va<Tab> two<Tab> produces :MyCmd one\ value two\ values, and <f-args> yields two arguments one value and two values. -nargs=_ cannot express this because it disables splitting entirely.
So the split is: -nargs=_ when the whole line should be taken as one argument as-is, -completeopt=escape for multi-argument commands where arguments may contain spaces. I'm happy to document that boundary in :help :command-completeopt and add a note in :help :command-nargs, and to add a -nargs=+ test case so the multi-argument scenario is covered explicitly (the current tests focus on -nargs=1, which admittedly overlaps with -nargs=_).
—
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.![]()
-nargs=_ and -completeopt=escapeThanks, the example clarifies the intent. After reading it I agree the two features are genuinely orthogonal:
-nargs=_ is an argument-count rule — the splitter is disabled, there is always exactly one argument equal to the whole tail.-completeopt=escape is an insertion rule — the splitter still runs, and individual arguments may carry escaped spaces.These cannot reasonably be folded into a single attribute without awkward composite values like -nargs=+esc, so the two-attribute design is justified.
That said, since v9.2.0494 only landed yesterday, the public surface here is not yet frozen, and I'd like to make sure users do not have to puzzle out the boundary themselves. Three small requests:
Add a short comparison in :help :command-completeopt and a cross-reference from :help :command-nargs, along the lines of:
-nargs=_-nargs=+/* + -completeopt=escapeThis makes it clear that the two attributes target different shapes, not competing solutions for the same shape — which is the question I expect most plugin authors to ask first.
-nargs=_ with -completeopt=escapeThe two have orthogonal purposes, and a command using both is almost certainly a misunderstanding (the escape attribute has no effect when the splitter is already disabled). Emitting an error at command-definition time, e.g.
E???: -nargs=_ cannot be combined with -completeopt=escape
removes one obvious source of confusion at the cheapest possible cost.
-nargs=+ test caseYou already offered this — having an explicit -nargs=+ test next to the existing -nargs=1 ones in Test_command_completeopt_escape would make the multi-argument scenario (which is the case -nargs=_ cannot express) visible in the test suite, and serves as living documentation for the boundary.
If those three are in scope, I have no further concerns about the overlap.
—
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.![]()