diff --git a/Cargo.lock b/Cargo.lock index 3578b15..c989ce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -465,10 +465,8 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-targets 0.52.6", ] @@ -494,6 +492,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.5.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.18" @@ -1484,8 +1491,8 @@ dependencies = [ "actix-web", "anyhow", "biscuit", - "chrono", "clap", + "clap_complete", "colored_json", "comfy-table", "directories", diff --git a/Cargo.toml b/Cargo.toml index 72104ac..370edb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,8 @@ pkg-fmt = "bin" actix-web = { version = "4", features = ["openssl"] } anyhow = "1" biscuit = "0.7" -chrono = "0.4" clap = { version = "4", features = ["derive", "env"] } +clap_complete = "4" colored_json = "5" comfy-table = "7" directories = "5" diff --git a/src/cmd/completion.rs b/src/cmd/completion.rs new file mode 100644 index 0000000..cd4439a --- /dev/null +++ b/src/cmd/completion.rs @@ -0,0 +1,37 @@ +use crate::Cli; +use clap::CommandFactory; +use clap_complete::generate; +use clap_complete::Shell::{Bash, Fish, Zsh}; +use std::path::Path; +use std::{env, io}; + +/// Generate shell completion +#[derive(Debug, clap::Parser)] +#[command(rename_all_env = "SNAKE_CASE")] +pub struct GetCompletion { + /// The shell to generate completions for. Supported values are bash, zsh or fish + pub shell: String, +} + +impl GetCompletion { + pub async fn run(self) -> anyhow::Result<()> { + let shell = self.shell; + let mut cmd = Cli::command(); + let bin_name = env::args() + .next() + .and_then(|path| { + Path::new(&path) + .file_stem() + .map(|name| name.to_string_lossy().into_owned()) + }) + .unwrap(); + + match shell.as_str() { + "bash" => generate(Bash, &mut cmd, &bin_name, &mut io::stdout()), + "zsh" => generate(Zsh, &mut cmd, &bin_name, &mut io::stdout()), + "fish" => generate(Fish, &mut cmd, &bin_name, &mut io::stdout()), + _ => eprintln!("Unsupported shell: {}", shell), + } + Ok(()) + } +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index c19c05f..b8fc39e 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -1,3 +1,4 @@ +mod completion; mod create; mod delete; mod inspect; @@ -13,6 +14,7 @@ pub enum Command { Token(token::GetToken), List(list::List), Inspect(inspect::Inspect), + Completion(completion::GetCompletion), } impl Command { @@ -23,6 +25,7 @@ impl Command { Self::Token(cmd) => cmd.run().await, Self::List(cmd) => cmd.run().await, Self::Inspect(cmd) => cmd.run().await, + Self::Completion(cmd) => cmd.run().await, } .map(|()| ExitCode::SUCCESS) }