novel_cli/cmd/
completions.rs

1use std::io;
2
3use clap::{Args, CommandFactory, ValueEnum};
4use clap_complete::Generator;
5use color_eyre::eyre::Result;
6use fluent_templates::Loader;
7use novel_api::Timing;
8
9use crate::config::Config;
10use crate::{LANG_ID, LOCALES};
11
12#[must_use]
13#[derive(Clone, ValueEnum)]
14pub enum Shell {
15    Bash,
16    Elvish,
17    Fish,
18    PowerShell,
19    Zsh,
20    Nushell,
21}
22
23impl Shell {
24    fn to_clap_type(&self) -> Box<dyn Generator> {
25        match self {
26            Self::Bash => Box::new(clap_complete::Shell::Bash),
27            Self::Elvish => Box::new(clap_complete::Shell::Elvish),
28            Self::Fish => Box::new(clap_complete::Shell::Fish),
29            Self::PowerShell => Box::new(clap_complete::Shell::PowerShell),
30            Self::Zsh => Box::new(clap_complete::Shell::Zsh),
31            Self::Nushell => Box::new(clap_complete_nushell::Nushell),
32        }
33    }
34}
35
36#[must_use]
37#[derive(Args)]
38#[command(arg_required_else_help = true,
39    about = LOCALES.lookup(&LANG_ID, "completions_command"))]
40pub struct Completions {
41    #[arg(value_enum,
42        help = LOCALES.lookup(&LANG_ID, "shell"))]
43    pub shell: Shell,
44}
45
46pub fn execute(config: Completions) -> Result<()> {
47    let mut timing = Timing::new();
48
49    let mut cmd = Config::command();
50    let bin_name = cmd.get_name().to_string();
51
52    cmd.set_bin_name(bin_name);
53    cmd.build();
54
55    config
56        .shell
57        .to_clap_type()
58        .generate(&cmd, &mut io::stdout());
59
60    tracing::debug!("Time spent on `completions`: {}", timing.elapsed()?);
61
62    Ok(())
63}