use anyhow::Result;
use async_trait::async_trait;
use clap::{Args, CommandFactory};
use clap_complete::{
generate,
shells::{Bash, Elvish, Fish, PowerShell, Zsh},
};
use std::io;
use tokio::task;
use crate::{
commands::{Runnable, RunnableInvokeRules},
context::AppContext,
};
#[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum, Debug)]
pub enum Shell {
Bash,
Zsh,
Fish,
Elvish,
PowerShell,
}
#[derive(Args, Debug)]
pub struct CompletionCmd {
#[arg(value_enum)]
shell: Shell,
}
#[async_trait]
impl Runnable for CompletionCmd {
fn get_invoke_rules(&self) -> RunnableInvokeRules {
RunnableInvokeRules {
do_config_autosync: false,
require_sudo: false,
respect_lock: false,
}
}
async fn run(&self, _: &AppContext) -> Result<()> {
let shell = self.shell;
task::spawn_blocking(move || -> Result<()> {
let mut cmd = crate::cli::Args::command();
let name = cmd.get_name().to_string();
match shell {
Shell::Bash => generate(Bash, &mut cmd, name, &mut io::stdout()),
Shell::Zsh => generate(Zsh, &mut cmd, name, &mut io::stdout()),
Shell::Fish => generate(Fish, &mut cmd, name, &mut io::stdout()),
Shell::PowerShell => generate(PowerShell, &mut cmd, name, &mut io::stdout()),
Shell::Elvish => generate(Elvish, &mut cmd, name, &mut io::stdout()),
}
Ok(())
})
.await??;
Ok(())
}
}