Skip to main content

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).
20#[must_use]
21pub fn handle_generate_completion(shell: Shell) -> bool {
22    let mut stdout = std::io::stdout();
23    let shell_name = shell.name();
24
25    // Get the command from Args
26    let mut command = crate::cli::Args::command();
27
28    // Generate the completion script using clap_complete
29    let shell_type = match shell {
30        Shell::Bash => clap_complete::Shell::Bash,
31        Shell::Zsh => clap_complete::Shell::Zsh,
32        Shell::Fish => clap_complete::Shell::Fish,
33        Shell::Elvish => clap_complete::Shell::Elvish,
34        Shell::Pwsh => clap_complete::Shell::PowerShell,
35    };
36
37    clap_complete::generate(shell_type, &mut command, "ralph", &mut stdout);
38
39    // Print installation instructions
40    eprintln!();
41    eprintln!("=== Shell completion installation for {shell_name} ===");
42    eprintln!();
43    eprintln!("To enable completions, add the following to your shell config:");
44    eprintln!();
45
46    match shell {
47        Shell::Bash => {
48            eprintln!("  # Add to ~/.bashrc or ~/.bash_profile:");
49            eprintln!("  source <(ralph --generate-completion=bash)");
50            eprintln!();
51            eprintln!("  # Or save to a file:");
52            eprintln!("  ralph --generate-completion=bash > ~/.local/share/bash-completion/completions/ralph");
53        }
54        Shell::Zsh => {
55            eprintln!("  # Add to ~/.zshrc:");
56            eprintln!("  source <(ralph --generate-completion=zsh)");
57            eprintln!();
58            eprintln!("  # Or save to a file:");
59            eprintln!("  ralph --generate-completion=zsh > ~/.zsh/completion/_ralph");
60            eprintln!("  # Then add to ~/.zshrc:");
61            eprintln!("  fpath=(~/.zsh/completion $fpath)");
62            eprintln!("  autoload -U compinit && compinit");
63        }
64        Shell::Fish => {
65            eprintln!("  # Add to ~/.config/fish/completions/ralph.fish:");
66            eprintln!("  ralph --generate-completion=fish > ~/.config/fish/completions/ralph.fish");
67        }
68        Shell::Elvish => {
69            eprintln!("  # Add to ~/.elvish/rc.elv:");
70            eprintln!("  ralph --generate-completion=elvish > ~/.config/elvish/lib/ralph.elv");
71            eprintln!("  # Then add to ~/.elvish/rc.elv:");
72            eprintln!("  put ~/.config/elvish/lib/ralph.elv | slurp");
73        }
74        Shell::Pwsh => {
75            eprintln!("  # Add to your PowerShell profile ($PROFILE):");
76            eprintln!("  ralph --generate-completion=pwsh > ralph-completion.ps1");
77            eprintln!("  # Then add to $PROFILE:");
78            eprintln!("  . ralph-completion.ps1");
79        }
80    }
81
82    eprintln!();
83    eprintln!("Restart your shell or source your config file to apply changes.");
84
85    true
86}
87
88impl Shell {
89    /// Returns the name of the shell as a string.
90    pub const fn name(self) -> &'static str {
91        match self {
92            Self::Bash => "bash",
93            Self::Zsh => "zsh",
94            Self::Fish => "fish",
95            Self::Elvish => "elvish",
96            Self::Pwsh => "powershell",
97        }
98    }
99}