apple / swift-argument-parser

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

`CompletionKind` should support multiple options #566

Open MaxDesiatov opened 1 year ago

MaxDesiatov commented 1 year ago

The completion parameter of @Argument property wrapper only allows specifying a single CompletionKind value which is not flexible enough. In some cases a command can take either a file or a directory, but only one of these kinds can be currently specified.

natecook1000 commented 1 year ago

This might just be a documentation issue — IIRC .file will also autocomplete directories, since the file you want might live in a directory. Since files can't contain anything else, the .directory setting is essentially a subset of what .file offers.

(The documentation for CompletionKind is definitely thin, apologies.)

natikgadzhi commented 1 year ago

I tried the example below to see if .file works for directories:

import ArgumentParser

@main
struct Repeat: ParsableCommand {

    @Argument(help: "The file path to test completion", completion: .file())
    var testFilePath: String

    mutating func run() throws {
        print("testFilePath: \(testFilePath)")
    }
}

Good news:

Bad news:

❯ .build/debug/example --generate-completion-script zsh
#compdef repeat
local context state state_descr line
_repeat_commandname=$words[1]
typeset -A opt_args

_repeat() {
    integer ret=1
    local -a args
    args+=(
        ':test-file-path:_files'
        '(-h --help)'{-h,--help}'[Show help information.]'
    )
    _arguments -w -s -S $args[@] && ret=0

    return ret
}

_custom_completion() {
    local completions=("${(@f)$($*)}")
    _describe '' completions
}

_repeat

The documentation here has an example generating completions for example that is then piped into _example.

Based on that, perhaps we should:

  1. Reword the documentation to mention that completion: .file() without extension will offer directories in completions. That should close this issue.
  2. Consider adding an alias CompletionKind.path that would be identical to .file in behavior so that the name clarifies the intent? (Not sure about that, bloating the API surface is probably not such a great idea?)
  3. I would be happy to try and work on #570 — seems doable and rewarding to fix a few bugs with one PR.

@natecook1000, how does that sound?