diff --git a/Cargo.lock b/Cargo.lock index 6c05f1d..1c2ec5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,15 @@ dependencies = [ "log", ] +[[package]] +name = "clap_complete" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "3.1.7" @@ -626,6 +635,7 @@ version = "0.4.0" dependencies = [ "clap", "clap-verbosity-flag", + "clap_complete", "clap_mangen", "env_logger", "exitcode", diff --git a/Cargo.toml b/Cargo.toml index 64e0f3a..72f1278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,4 @@ clap = { version = "3.1.9", features = ["derive", "env", "wrap_help"] } clap-verbosity-flag = "1.0.0" clap_mangen = "0.1.3" +clap_complete = "3.1.1" diff --git a/build.rs b/build.rs index 2db22e5..395bc19 100644 --- a/build.rs +++ b/build.rs @@ -11,8 +11,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::cli::Cli; use clap::CommandFactory; -use std::{env, fs, io, path}; +use clap_complete::{generate_to, Shell}; +use clap_mangen::Man; +use std::path::Path; +use std::{env, fs, io, path::PathBuf}; #[path = "src/cli.rs"] mod cli; @@ -22,14 +26,34 @@ mod cli; fn main() -> io::Result<()> { println!("cargo:rerun-if-changed=src/cli.rs"); - let out_dir = path::PathBuf::from(env::var_os("OUT_DIR").ok_or(io::ErrorKind::NotFound)?); - let cmd = cli::Cli::command(); + let out_dir = PathBuf::from(env::var_os("OUT_DIR").ok_or(io::ErrorKind::NotFound)?); - let man = clap_mangen::Man::new(cmd); + generate_man(&out_dir)?; + generate_completion(&out_dir)?; + + Ok(()) +} + +fn generate_completion(out_dir: &Path) -> io::Result<()> { + // We generate Elvish shell completion for anyone who wants to manually install it, + // but Homebrew is unable to install Elvish shell completion. + let shells = &[Shell::Bash, Shell::Elvish, Shell::Fish, Shell::Zsh]; + + for shell in shells { + let mut cmd = Cli::command(); + generate_to(*shell, &mut cmd, "xshe", out_dir)?; + } + Ok(()) +} + +fn generate_man(out_dir: &Path) -> io::Result<()> { + let cmd = Cli::command(); + + // Generate Man File + let man = Man::new(cmd); let mut buffer: Vec = Default::default(); man.render(&mut buffer)?; fs::write(out_dir.join("xshe.1"), buffer)?; - Ok(()) }