clap icon indicating copy to clipboard operation
clap copied to clipboard

fix(complete): CommandWithArguments with previous positional args in zsh

Open pseyfert opened this issue 2 years ago • 0 comments

Iiuc the value hint CommandWithArgs for zsh was incorrect when in a positional argument after the first positional argument.

I updated the clap_complete/tests/common.rs:value_hint_command accordingly to generate a test case. The relevant part is

clap::Command::new(name)
    .trailing_var_arg(true)
    .arg(clap::Arg::new("positional")
        .required(true)
        .possible_values(["stable", "nightly"]),
    )
    .arg(clap::Arg::new("command_with_arg")
        .takes_value(true)
        .multiple_values(true)
        .value_hint(clap::ValueHint::CommandWithArguments),
    )

The resulting section of the completion function is then without my change to zsh.rs

_arguments \
':positional:(stable nightly)' \
'*::command_with_args:_cmdambivalent'

With this function, I don't get any completion past my-app stable TAB. From the zshcompsys man page https://github.com/zsh-users/zsh/blob/master/Doc/Zsh/compsys.yo#L3903= (section on _arguments for the forms *:message:action with one, two, or three colons):

 *:message:action
 *::message:action
 *:::message:action
        This  describes  how  arguments (usually non-option
        arguments, those not beginning with - or +) are  to
        be  completed  when  neither of the first two forms
        was provided.  Any number of arguments can be  com‐
        pleted in this fashion.

        With  two colons before the message, the words spe‐
        cial array and the CURRENT  special  parameter  are
        modified to refer only to the normal arguments when
        the action is executed or  evaluated.   With  three
        colons  before the message they are modified to re‐
        fer only to the normal arguments  covered  by  this
        description.

I.e. the completion now tries to complete a command stable ….

With my change, the third colon gets added, such that _cmdambivalent only "sees" the arguments after the stable/nightly argument:

_arguments \
':positional:(stable nightly)' \
'*:::command_with_args:_cmdambivalent'

As cross check, I tried my-app stable TAB and got tons of suggestions, all seeming like valid commands I have installed. To try further I ran my-app stable git cl<TAB> and got clean and clone suggested.

NB 1: I only focussed on this one test case. The other changes to the test. I haven't looked long at the changes to my-app help TAB I'm questioning here if my-app help TAB should complete more than one subcommand? This is to me less a question about what the desired zsh completion code is but more about this opt in to multiple occurences

NB 2: Obviously my change alters the snapshots for other shells, I blindly updated the snapshot here.

pseyfert avatar May 09 '22 19:05 pseyfert