Function clap_complete::aot::generate_to
source · pub fn generate_to<G, S, T>(
gen: G,
cmd: &mut Command,
bin_name: S,
out_dir: T,
) -> Result<PathBuf, Error>
Expand description
Generate a completions file for a specified shell at compile-time.
NOTE: to generate the file at compile time you must use a build.rs
“Build Script” or a
cargo-xtask
§Examples
The following example generates a bash completion script via a build.rs
script. In this
simple example, we’ll demo a very small application with only a single subcommand and two
args. Real applications could be many multiple levels deep in subcommands, and have tens or
potentially hundreds of arguments.
First, it helps if we separate out our Command
definition into a separate file. Whether you
do this as a function, or bare Command definition is a matter of personal preference.
// src/cli.rs
pub fn build_cli() -> Command {
Command::new("compl")
.about("Tests completions")
.arg(Arg::new("file")
.help("some input file"))
.subcommand(Command::new("test")
.about("tests things")
.arg(Arg::new("case")
.long("case")
.action(ArgAction::Set)
.help("the case to test")))
}
In our regular code, we can simply call this build_cli()
function, then call
get_matches()
, or any of the other normal methods directly after. For example:
// src/main.rs
mod cli;
fn main() {
let _m = cli::build_cli().get_matches();
// normal logic continues...
}
Next, we set up our Cargo.toml
to use a build.rs
build script.
# Cargo.toml
build = "build.rs"
[dependencies]
clap = "*"
[build-dependencies]
clap = "*"
clap_complete = "*"
Next, we place a build.rs
in our project root.
use clap_complete::{generate_to, shells::Bash};
use std::env;
use std::io::Error;
include!("src/cli.rs");
fn main() -> Result<(), Error> {
let outdir = match env::var_os("OUT_DIR") {
None => return Ok(()),
Some(outdir) => outdir,
};
let mut cmd = build_cli();
let path = generate_to(
Bash,
&mut cmd, // We need to specify what generator to use
"myapp", // We need to specify the bin name manually
outdir, // We need to specify where to write to
)?;
println!("cargo:warning=completion file is generated: {path:?}");
Ok(())
}
Now, once we compile there will be a {bin_name}.bash
file in the directory.
Assuming we compiled with debug mode, it would be somewhere similar to
<project>/target/debug/build/myapp-<hash>/out/myapp.bash
.
NOTE: Please look at the individual shells to see the name of the files generated.
Using ValueEnum::value_variants()
you can easily loop over
all the supported shell variants to generate all the completions at once too.
use clap::ValueEnum;
use clap_complete::{generate_to, Shell};
use std::env;
use std::io::Error;
include!("src/cli.rs");
fn main() -> Result<(), Error> {
let outdir = match env::var_os("OUT_DIR") {
None => return Ok(()),
Some(outdir) => outdir,
};
let mut cmd = build_cli();
for &shell in Shell::value_variants() {
generate_to(shell, &mut cmd, "myapp", outdir)?;
}
Ok(())
}