Clap stands for Command Line Argument Parser, and put simply, it's a great library for making command-line stuff with Rust. Even Cargo, Rust's package manager, depends on it (*Cargo/cargo.toml at master*), and it's been downloaded over 300 million times (*Clap - Crates.io: Rust package registry*).
That's all you need to know to use `clap` at a very basic level; for more details, check out the docs (*clap Documentation*). But, you probably don't want to have to type in the entire command automatically, autocomplete would be nice. So I'll also go over how to use `clap_complete` as well.
Searching through the documentation (*Clap_complete Documentation*), you'll notice that the docs don't cover how to use it with clap's derive at all. Instead, after some Googling, I found an example script in *clap*'s repository (*completion-derive.rs at master*), which I then adapted and played around with a bit until I got it figured out.
Anyways, again, we need to install `clap_complete` first:
```sh
cargo add clap_complete
```
Then, add the relevant imports. We'll just being doing it for the fish shell since that's what I use, so we'll only import `Fish`; Bash, Zsh, PowerShell, and Elvish are also supported.
```rust
use clap_complete::aot::{generate, Fish};
```
Then, we need to add a command to generate the completion:
```rust
#[derive(Subcommand)]
pub enum Commands {
///Run this thing
Run,
///Delete the stuff that thing does
Delete,
///Generate fish completions
FishCompletions,
}
```
Next, we actually generate the completion, adding it like it's another command:
```rust
match cli.command {
Commands::Run {
run();
}
Commands::Delete {
delete();
}
Commands::GenerateFishCompletions => {
generate(
Fish,
&mut Cli::command(),
"example-program",
&mut stdout(),
);
}
}
```
To explain the options for `generate()`:
-`Fish`: The shell we're using.
-`&mut Cli::command()`: I don't actually know what this does, but understanding ths library fully this is beyond my pay grade, especially given the somewhat lacking docs.
-`"example-program"`: The name of our program
-`&mut stdout()`: `stdout`, so that it can print the completions. Why does it do it this way? I don't know, it doesn't make sense to me. Why doesn't it just return it as a String? I don't know. But it works, I suppose.
As an example of all this, here's my `disk-read-benchmark` program, running using all this. The commands have formatting I can't do, so it looks even better than I can even show here.