Skip to main content

lux_cli/
completion.rs

1use std::env;
2use std::path::PathBuf;
3use std::str::FromStr;
4
5use clap::Args;
6use clap::CommandFactory;
7use clap_complete::generate as clap_generate;
8use clap_complete::Shell;
9use eyre::eyre;
10use eyre::Result;
11
12use crate::Cli;
13
14#[derive(Args)]
15pub struct Completion {
16    /// The shell to generate the completion script for.{n}
17    /// If not set, Lux will try to detect the current shell.{n}
18    /// Possible values: "bash", "elvish", "fish", "powershell", "zsh"{n}
19    #[arg(value_enum)]
20    shell: Option<Shell>,
21}
22
23pub async fn completion(args: Completion) -> Result<()> {
24    let shell = match args.shell {
25        Some(shell) => shell,
26        None => {
27            let shell_var: PathBuf = env::var("SHELL")
28                .map_err(|_| {
29                    eyre!(
30                        r#"could not auto-detect the shell
31Please make sure the SHELL environment variable is set
32or specify the shell for which to generate completions.
33
34Example: `lx completion zsh`
35
36Supported shells: "bash", "elvish", "fish", "powershell", "zsh"
37"#
38                    )
39                })?
40                .into();
41            let shell_name = shell_var
42                .file_name()
43                .unwrap_or_else(|| shell_var.as_os_str())
44                .to_string_lossy();
45            Shell::from_str(&shell_name).map_err(|_| {
46                eyre!(
47                    r#"unsupported shell: {}.
48Please specify the shell for which to generate completions.
49
50Example: `lx completion zsh`
51
52Supported shells: "bash", "elvish", "fish", "powershell", "zsh"
53"#,
54                    &shell_name
55                )
56            })?
57        }
58    };
59    clap_generate(shell, &mut Cli::command(), "lx", &mut std::io::stdout());
60    Ok(())
61}