logo

Function clap_complete::generate_to[][src]

pub fn generate_to<G, S, T>(
    gen: G,
    app: &mut App<'_>,
    bin_name: S,
    out_dir: T
) -> Result<PathBuf, Error> where
    G: Generator,
    S: Into<String>,
    T: Into<OsString>, 
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 App definition into a separate file. Whether you do this as a function, or bare App definition is a matter of personal preference.

// src/cli.rs

use clap::{App, Arg};

pub fn build_cli() -> App<'static> {
    App::new("compl")
        .about("Tests completions")
        .arg(Arg::new("file")
            .help("some input file"))
        .subcommand(App::new("test")
            .about("tests things")
            .arg(Arg::new("case")
                .long("case")
                .takes_value(true)
                .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.

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, generators::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 app = build_cli();
    let path = generate_to(
        Bash,
        &mut app, // 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 generators to see the name of the files generated.