diff --git a/Cargo.lock b/Cargo.lock index d6e8d20..7185856 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -630,6 +630,15 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97aeaa95557bd02f23fbb662f981670c3d20c5a26e69f7354b28f57092437fcd" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.4.7" @@ -1522,6 +1531,7 @@ version = "0.1.0" dependencies = [ "card-backend-pcsc", "clap", + "clap_complete", "keyfork-derive-openpgp", "keyfork-derive-util", "keyfork-entropy", diff --git a/keyfork/Cargo.toml b/keyfork/Cargo.toml index b075a57..d68286d 100644 --- a/keyfork/Cargo.toml +++ b/keyfork/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" edition = "2021" license = "AGPL-3.0-only" +[features] +default = ["completion"] +completion = ["dep:clap_complete"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -23,3 +27,4 @@ openpgp-card-sequoia = "0.2.0" openpgp-card = "0.4.1" keyfork-prompt = { version = "0.1.0", path = "../keyfork-prompt" } keyfork-entropy = { version = "0.1.0", path = "../keyfork-entropy" } +clap_complete = { version = "4.4.6", optional = true } diff --git a/keyfork/src/cli/mod.rs b/keyfork/src/cli/mod.rs index 5f3b16c..2a76c04 100644 --- a/keyfork/src/cli/mod.rs +++ b/keyfork/src/cli/mod.rs @@ -1,4 +1,4 @@ -use clap::{Parser, Subcommand}; +use clap::{CommandFactory, Parser, Subcommand}; mod derive; mod mnemonic; @@ -37,6 +37,13 @@ pub enum KeyforkCommands { /// Utilities to automatically manage the setup of Keyfork. Wizard(wizard::Wizard), + + /// Print an autocompletion file to standard output. + #[cfg(feature = "completion")] + Completion { + #[arg(value_enum)] + shell: clap_complete::Shell, + }, } impl KeyforkCommands { @@ -61,6 +68,17 @@ impl KeyforkCommands { KeyforkCommands::Wizard(w) => { w.handle(keyfork)?; } + #[cfg(feature = "completion")] + KeyforkCommands::Completion { shell } => { + let mut command = Keyfork::command(); + let command_name = command.get_name().to_string(); + clap_complete::generate( + *shell, + &mut command, + command_name, + &mut std::io::stdout(), + ); + } } Ok(()) }