ralph_workflow/cli/
completions.rs1use crate::cli::args::Shell;
7use clap::CommandFactory;
8
9trait StdIoWriteCompat {
10 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()>;
11}
12
13impl<T: std::io::Write> StdIoWriteCompat for T {
14 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
15 std::io::Write::write_fmt(self, args)
16 }
17}
18
19#[must_use]
31pub fn handle_generate_completion(shell: Shell) -> bool {
32 let shell_name = shell.name();
33
34 let shell_type = match shell {
36 Shell::Bash => clap_complete::Shell::Bash,
37 Shell::Zsh => clap_complete::Shell::Zsh,
38 Shell::Fish => clap_complete::Shell::Fish,
39 Shell::Elvish => clap_complete::Shell::Elvish,
40 Shell::Pwsh => clap_complete::Shell::PowerShell,
41 };
42
43 clap_complete::generate(
44 shell_type,
45 &mut crate::cli::Args::command(),
46 "ralph",
47 &mut std::io::stdout(),
48 );
49
50 let _ = writeln!(std::io::stderr());
52 let _ = writeln!(
53 std::io::stderr(),
54 "=== Shell completion installation for {shell_name} ==="
55 );
56 let _ = writeln!(std::io::stderr());
57 let _ = writeln!(
58 std::io::stderr(),
59 "To enable completions, add the following to your shell config:"
60 );
61 let _ = writeln!(std::io::stderr());
62
63 match shell {
64 Shell::Bash => {
65 let _ = writeln!(
66 std::io::stderr(),
67 " # Add to ~/.bashrc or ~/.bash_profile:"
68 );
69 let _ = writeln!(
70 std::io::stderr(),
71 " source <(ralph --generate-completion=bash)"
72 );
73 let _ = writeln!(std::io::stderr());
74 let _ = writeln!(std::io::stderr(), " # Or save to a file:");
75 let _ = writeln!(std::io::stderr(), " ralph --generate-completion=bash > ~/.local/share/bash-completion/completions/ralph");
76 }
77 Shell::Zsh => {
78 let _ = writeln!(std::io::stderr(), " # Add to ~/.zshrc:");
79 let _ = writeln!(
80 std::io::stderr(),
81 " source <(ralph --generate-completion=zsh)"
82 );
83 let _ = writeln!(std::io::stderr());
84 let _ = writeln!(std::io::stderr(), " # Or save to a file:");
85 let _ = writeln!(
86 std::io::stderr(),
87 " ralph --generate-completion=zsh > ~/.zsh/completion/_ralph"
88 );
89 let _ = writeln!(std::io::stderr(), " # Then add to ~/.zshrc:");
90 let _ = writeln!(std::io::stderr(), " fpath=(~/.zsh/completion $fpath)");
91 let _ = writeln!(std::io::stderr(), " autoload -U compinit && compinit");
92 }
93 Shell::Fish => {
94 let _ = writeln!(
95 std::io::stderr(),
96 " # Add to ~/.config/fish/completions/ralph.fish:"
97 );
98 let _ = writeln!(
99 std::io::stderr(),
100 " ralph --generate-completion=fish > ~/.config/fish/completions/ralph.fish"
101 );
102 }
103 Shell::Elvish => {
104 let _ = writeln!(std::io::stderr(), " # Add to ~/.elvish/rc.elv:");
105 let _ = writeln!(
106 std::io::stderr(),
107 " ralph --generate-completion=elvish > ~/.config/elvish/lib/ralph.elv"
108 );
109 let _ = writeln!(std::io::stderr(), " # Then add to ~/.elvish/rc.elv:");
110 let _ = writeln!(
111 std::io::stderr(),
112 " put ~/.config/elvish/lib/ralph.elv | slurp"
113 );
114 }
115 Shell::Pwsh => {
116 let _ = writeln!(
117 std::io::stderr(),
118 " # Add to your PowerShell profile ($PROFILE):"
119 );
120 let _ = writeln!(
121 std::io::stderr(),
122 " ralph --generate-completion=pwsh > ralph-completion.ps1"
123 );
124 let _ = writeln!(std::io::stderr(), " # Then add to $PROFILE:");
125 let _ = writeln!(std::io::stderr(), " . ralph-completion.ps1");
126 }
127 }
128
129 let _ = writeln!(std::io::stderr());
130 let _ = writeln!(
131 std::io::stderr(),
132 "Restart your shell or source your config file to apply changes."
133 );
134
135 true
136}
137
138impl Shell {
139 pub const fn name(self) -> &'static str {
141 match self {
142 Self::Bash => "bash",
143 Self::Zsh => "zsh",
144 Self::Fish => "fish",
145 Self::Elvish => "elvish",
146 Self::Pwsh => "powershell",
147 }
148 }
149}