clap-rs / clap

A full featured, fast Command Line Argument Parser for Rust
docs.rs/clap
Apache License 2.0
13.64k stars 1.02k forks source link

Provide an attribute that implements a common `--completions <SHELL>` convention without boilerplate #5504

Open lgarron opened 1 month ago

lgarron commented 1 month ago

Please complete the following tasks

Clap Version

N/A

Describe your use case

A lot of programs now implement one of the following:

I loooove clap and clap_complete, and would love for this to be so simple to configure that I can configure it for a project (or contribute it to another project using clap) in minimal code.

While it would be nice to support both the flag and command version, I think command version is more fraught[^1], so I will focus on a proposal for the flag version.

[^1]: If you want to figure out whether a program supports something, I think a flag is generally much safer to try than a command. For example, rm --completions fish is basically safe to run, while rm completions fish is a recipe for a bad time.

Describe the solution you'd like

I'd love to get full completions functionality with syntax like this:

use clap_complete::{Shell};

// …
struct ProgramArgs {
    #[clap(completions)]
    completions: Option<Shell>,
}
Print completions for the given shell. When this flag is passed, any other input is ignored and the program will terminate immediately after printing the completions.

Completions can be loaded and stored permanently by package managers, or they can be loaded into a given shell as follows:

source <(<COMMAND_NAME> --completions bash) # bash
source <(<COMMAND_NAME> --completions zsh) # zsh
<COMMAND_NAME> --completions fish | source # fish
… # …

Alternatives, if applicable

The main alternative is to leave this for each program to implement individually.

However, I think this is not ideal in the long term:

I'd also love for this to serve as the basis for a standard convention for discoverable completions that can be used by package managers and shells. Hence my emphasis on consistent behaviour with consistent invocation syntax.

For example, Homebrew makes it a one-liner to support completions for a given program, but you don't get them for a given program if someone didn't add that line manually.[^2] I can imagine a package manager that automatically invokes --completions and loads them automatically, or at least introduces a linter for package definitions that highlights when completions seem to be available (but are not explicitly marked as supported/unsupported). This kind of functionality could also integrate with something like cargo install or shells directly.

[^2]: In fact, I was motivated to file this issue after I found that Homebrew was missing completions for tailscale. They were super quick to accept my PR to add support. But that means everyone is only getting these completions going forward, when they were actually already available!

Additional Context

I know I'm probably not thinking of some details (e.g. how to avoid pulling in the standard library, how to have a program signal support for this convention without complications for legacy programs), but I think at an implementation level this should be a fairly moderate amount of code? But I know I'm asking for kind of bold stance on paving the path for a kind of hardcoded convention, when clap and clap_complete are all about versatility and flexibility in general.

I'd be glad to contribute a PR if maintainers are on board and can give me a few pointers.

epage commented 1 month ago

We are offering this with our newer, in-work completion system. See CompleteCommand.

lgarron commented 1 month ago

Oh, that is fabulous to see! 🤩