theater_cli/commands/
completion.rs1use clap::{CommandFactory, Parser};
2use clap_complete::{generate, Shell};
3use std::io;
4use tracing::debug;
5
6use crate::error::{CliError, CliResult};
7use crate::CommandContext;
8
9#[derive(Debug, Parser)]
10pub struct CompletionArgs {
11 #[arg(value_enum)]
13 pub shell: Shell,
14
15 #[arg(short, long)]
17 pub output: Option<std::path::PathBuf>,
18}
19
20pub async fn execute_async(args: &CompletionArgs, ctx: &CommandContext) -> CliResult<()> {
22 debug!("Generating shell completion for: {:?}", args.shell);
23
24 let mut app = crate::Cli::command();
25 let app_name = app.get_name().to_string();
26
27 match &args.output {
28 Some(output_path) => {
29 debug!("Writing completion to file: {:?}", output_path);
30
31 let mut file = std::fs::File::create(output_path).map_err(|e| CliError::IoError {
32 operation: format!("create completion file: {}", output_path.display()),
33 source: e,
34 })?;
35
36 generate(args.shell, &mut app, &app_name, &mut file);
37
38 ctx.output.success(&format!(
39 "Shell completion for {} written to: {}",
40 args.shell,
41 output_path.display()
42 ))?;
43 }
44 None => {
45 debug!("Writing completion to stdout");
46 generate(args.shell, &mut app, &app_name, &mut io::stdout());
47 }
48 }
49
50 if args.output.is_some() && !ctx.json {
53 show_installation_instructions(args.shell, ctx)?;
54 }
55
56 Ok(())
57}
58
59fn show_installation_instructions(shell: Shell, ctx: &CommandContext) -> CliResult<()> {
61 let instructions = match shell {
62 Shell::Bash => {
63 r#"
64To install bash completions:
65
661. Save the completion script:
67 theater completion bash > ~/.local/share/bash-completion/completions/theater
68
692. Or add to your ~/.bashrc:
70 eval "$(theater completion bash)"
71
723. Restart your shell or run:
73 source ~/.bashrc
74"#
75 }
76 Shell::Zsh => {
77 r#"
78To install zsh completions:
79
801. Save the completion script to a directory in your $fpath:
81 theater completion zsh > ~/.local/share/zsh/site-functions/_theater
82
832. Or add to your ~/.zshrc:
84 eval "$(theater completion zsh)"
85
863. Restart your shell or run:
87 source ~/.zshrc
88"#
89 }
90 Shell::Fish => {
91 r#"
92To install fish completions:
93
941. Save the completion script:
95 theater completion fish > ~/.config/fish/completions/theater.fish
96
972. Or add to your fish config:
98 theater completion fish | source
99
1003. Restart your shell
101"#
102 }
103 Shell::PowerShell => {
104 r#"
105To install PowerShell completions:
106
1071. Add to your PowerShell profile:
108 theater completion powershell | Out-String | Invoke-Expression
109
1102. Or save to a file and dot-source it in your profile:
111 theater completion powershell > theater_completion.ps1
112 . .\theater_completion.ps1
113"#
114 }
115 Shell::Elvish => {
116 r#"
117To install Elvish completions:
118
1191. Add to your ~/.config/elvish/rc.elv:
120 eval (theater completion elvish | slurp)
121"#
122 }
123 _ => "Please refer to your shell's documentation for completion installation.",
124 };
125
126 ctx.output.info(instructions)?;
127 Ok(())
128}