use clap::{CommandFactory, Parser, ValueEnum}; use clap_complete::{Generator, Shell, generate, generate_to}; use clap_complete_nushell::Nushell; use eyre::Result; // clap put nushell completions into a separate package due to the maintainers // being a little less committed to support them. // This means we have to do a tiny bit of legwork to combine these completions // into one command. #[derive(Debug, Clone, ValueEnum)] #[value(rename_all = "lower")] pub enum GenShell { Bash, Elvish, Fish, Nushell, PowerShell, Zsh, } impl Generator for GenShell { fn file_name(&self, name: &str) -> String { match self { // clap_complete Self::Bash => Shell::Bash.file_name(name), Self::Elvish => Shell::Elvish.file_name(name), Self::Fish => Shell::Fish.file_name(name), Self::PowerShell => Shell::PowerShell.file_name(name), Self::Zsh => Shell::Zsh.file_name(name), // clap_complete_nushell Self::Nushell => Nushell.file_name(name), } } fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::prelude::Write) { match self { // clap_complete Self::Bash => Shell::Bash.generate(cmd, buf), Self::Elvish => Shell::Elvish.generate(cmd, buf), Self::Fish => Shell::Fish.generate(cmd, buf), Self::PowerShell => Shell::PowerShell.generate(cmd, buf), Self::Zsh => Shell::Zsh.generate(cmd, buf), // clap_complete_nushell Self::Nushell => Nushell.generate(cmd, buf), } } } #[derive(Debug, Parser)] pub struct Cmd { /// Set the shell for generating completions #[arg(long, short)] shell: GenShell, /// Set the output directory #[arg(long, short)] out_dir: Option, } impl Cmd { pub fn run(self) -> Result<()> { let Cmd { shell, out_dir } = self; let mut cli = crate::Atuin::command(); match out_dir { Some(out_dir) => { generate_to(shell, &mut cli, env!("CARGO_PKG_NAME"), &out_dir)?; } None => { generate( shell, &mut cli, env!("CARGO_PKG_NAME"), &mut std::io::stdout(), ); } } Ok(()) } }