apple / swift-argument-parser

Straightforward, type-safe argument parsing for Swift
Apache License 2.0
3.31k stars 311 forks source link

Zsh completion script only shows a completion for the first time in an array. #564

Closed CraigSiemens closed 6 months ago

CraigSiemens commented 1 year ago

If a command has either an option or argument with an array type and completion set to anything, the completions will only be used for the first item typed into the terminal. Any following items wont get any completions.

In the case of an option with parsing set to one of the single value options, the option and value will only be suggested the first time. Afterwards the option will no longer be given as a completion.

ArgumentParser version: 1.2.2 Swift version: Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51) Target: arm64-apple-macosx13.0

Checklist

Steps to Reproduce

import ArgumentParser

@main
struct PhoneticAlphabet: ParsableCommand {
    @Option(completion: .list(words))
    var option: [String]

    @Argument(completion: .list(words))
    var argument: [String]

    func run() throws {
        print("options:", option)
        print("arguments:", argument)
    }
}

private extension PhoneticAlphabet {
    static var words: [String] {
        ["alfa", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliett", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform", "victor", "whiskey", "xray", "yankee", "zulu"]
    }
}
  1. Build the above command
  2. Install the zsh completions for it using {Command name} --generate-completion-script zsh and putting the completions in the correct location for your terminal setup. For me it's ~/.oh-my-zsh/completions.
  3. Start typing the command using completions for the option
    1. Type {Command name} --o then press tab to complete the option name
    2. Type a then tab to complete the word alfa
    3. Type --o then press tab again
  4. Or, start typing the command using completions for the argument
    1. Type {Command name} a then press tab to complete the word alfa
    2. Type a then press tab again

Expected behavior

For step 3, it should complete --option again since it can be passed multiple times to the command to build the option array.

For step 4, it should complete alfa again since it be passed multiple strings to build the argument array.

Actual behavior

After pressing tab the expected word is not completed. Either nothing is completed or possibly a different flag/option/argument is completed depending on what letter is typed, ie. it might complete --help depending on the terminal's completion settings.