diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc0679..793dc42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # unreleased - Fix memory allocation bug when terminal width is less than 10, see #244 (@selfup) +- Add command line argument to generate shell completion, see #155 (@friedz) ## Features diff --git a/Cargo.lock b/Cargo.lock index f24672e..3e7307a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,6 +128,15 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.18" @@ -222,6 +231,7 @@ dependencies = [ "anyhow", "assert_cmd", "clap", + "clap_complete", "const_format", "libc", "owo-colors", diff --git a/Cargo.toml b/Cargo.toml index 6e7f655..8a247b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ owo-colors = "4" supports-color = "3" thiserror = "1.0" terminal_size = "0.4" +clap_complete = "4" [dependencies.clap] version = "4" diff --git a/src/main.rs b/src/main.rs index ef9227e..8ae912c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,8 @@ use std::num::{NonZeroI64, NonZeroU64}; use std::path::PathBuf; use clap::builder::ArgPredicate; -use clap::{ArgAction, Parser, ValueEnum}; +use clap::{ArgAction, CommandFactory, Parser, ValueEnum}; +use clap_complete::aot::{generate, Shell}; use anyhow::{anyhow, bail, Context, Result}; @@ -192,6 +193,10 @@ struct Opt { /// Print a table showing how different types of bytes are colored. #[arg(long)] print_color_table: bool, + + /// Show shell completion for a certain shell + #[arg(long, value_name("SHELL"))] + completion: Option, } #[derive(Clone, Debug, Default, ValueEnum)] @@ -248,6 +253,13 @@ fn run() -> Result<()> { return print_color_table().map_err(|e| anyhow!(e)); } + if let Some(sh) = opt.completion { + let mut cmd = Opt::command(); + let name = cmd.get_name().to_string(); + generate(sh, &mut cmd, name, &mut io::stdout()); + return Ok(()); + } + let stdin = io::stdin(); let mut reader = match opt.file {