ralph_workflow/cli/
completions.rs

1//! Shell completion generation handlers.
2//!
3//! This module handles the `--generate-completion` flag for generating
4//! shell completion scripts for bash, zsh, fish, elvish, and powershell.
5
6use crate::cli::args::Shell;
7use clap::CommandFactory;
8
9/// Handle the `--generate-completion` flag.
10///
11/// Generates a shell completion script for the specified shell and writes it to stdout.
12///
13/// # Arguments
14///
15/// * `shell` - The shell type to generate completions for
16///
17/// # Returns
18///
19/// Returns `true` if the flag was handled (program should exit after).
20pub fn handle_generate_completion(shell: Shell) -> bool {
21    let mut stdout = std::io::stdout();
22    let shell_name = shell.name();
23
24    // Get the command from Args
25    let mut command = crate::cli::Args::command();
26
27    // Generate the completion script using clap_complete
28    let shell_type = match shell {
29        Shell::Bash => clap_complete::Shell::Bash,
30        Shell::Zsh => clap_complete::Shell::Zsh,
31        Shell::Fish => clap_complete::Shell::Fish,
32        Shell::Elvish => clap_complete::Shell::Elvish,
33        Shell::Pwsh => clap_complete::Shell::PowerShell,
34    };
35
36    clap_complete::generate(shell_type, &mut command, "ralph", &mut stdout);
37
38    // Print installation instructions
39    eprintln!();
40    eprintln!("=== Shell completion installation for {shell_name} ===");
41    eprintln!();
42    eprintln!("To enable completions, add the following to your shell config:");
43    eprintln!();
44
45    match shell {
46        Shell::Bash => {
47            eprintln!("  # Add to ~/.bashrc or ~/.bash_profile:");
48            eprintln!("  source <(ralph --generate-completion=bash)");
49            eprintln!();
50            eprintln!("  # Or save to a file:");
51            eprintln!("  ralph --generate-completion=bash > ~/.local/share/bash-completion/completions/ralph");
52        }
53        Shell::Zsh => {
54            eprintln!("  # Add to ~/.zshrc:");
55            eprintln!("  source <(ralph --generate-completion=zsh)");
56            eprintln!();
57            eprintln!("  # Or save to a file:");
58            eprintln!("  ralph --generate-completion=zsh > ~/.zsh/completion/_ralph");
59            eprintln!("  # Then add to ~/.zshrc:");
60            eprintln!("  fpath=(~/.zsh/completion $fpath)");
61            eprintln!("  autoload -U compinit && compinit");
62        }
63        Shell::Fish => {
64            eprintln!("  # Add to ~/.config/fish/completions/ralph.fish:");
65            eprintln!("  ralph --generate-completion=fish > ~/.config/fish/completions/ralph.fish");
66        }
67        Shell::Elvish => {
68            eprintln!("  # Add to ~/.elvish/rc.elv:");
69            eprintln!("  ralph --generate-completion=elvish > ~/.config/elvish/lib/ralph.elv");
70            eprintln!("  # Then add to ~/.elvish/rc.elv:");
71            eprintln!("  put ~/.config/elvish/lib/ralph.elv | slurp");
72        }
73        Shell::Pwsh => {
74            eprintln!("  # Add to your PowerShell profile ($PROFILE):");
75            eprintln!("  ralph --generate-completion=pwsh > ralph-completion.ps1");
76            eprintln!("  # Then add to $PROFILE:");
77            eprintln!("  . ralph-completion.ps1");
78        }
79    }
80
81    eprintln!();
82    eprintln!("Restart your shell or source your config file to apply changes.");
83
84    true
85}
86
87impl Shell {
88    /// Returns the name of the shell as a string.
89    pub const fn name(self) -> &'static str {
90        match self {
91            Self::Bash => "bash",
92            Self::Zsh => "zsh",
93            Self::Fish => "fish",
94            Self::Elvish => "elvish",
95            Self::Pwsh => "powershell",
96        }
97    }
98}