seaplane_cli/cli/cmds/
completion.rs1use clap::{value_parser, ArgMatches, Command};
2use clap_complete::Shell;
3
4use crate::{
5 cli::{CliCommand, Seaplane},
6 error::Result,
7 printer::printer,
8 Ctx,
9};
10
11static COMPLETION_HELP: &str = "DISCUSSION:
17 Enabling shell completion scripts depends on the shell you're using, the
18 operating system (or distribution of operating system), or even your
19 individual setup. Consult your shell or operating system documentation for
20 full details.
21
22 This guide covers several common setups.
23
24 BASH:
25
26 Completion scripts are often stored either system wide in
27 `/etc/bash_completion.d/` or individually by user in
28 `$HOME/.local/share/bash-completion/completions/`. In either case, the file
29 is typically the name of the binary who we are trying to complete, in our
30 case that is `seaplane`.
31
32 e.g. to configure completions for just our user:
33
34 $ mkdir -p ~/.local/share/bash-completion/completions/
35 $ seaplane shell-completion bash > ~/.local/share/bash-completion/completions/seaplane
36
37 Alternative, it is common to eval the completions during shell startup. To
38 do so, one needs only place the following command in their `.bashrc` or
39 similar:
40
41 eval \"$(seaplane shell-completion bash)\"
42
43 Whichever method you choose, you may need to close and re-open your terminal
44 for the changes to take affect.
45
46 ZSH:
47
48 ZSH completions are commonly stored in the directories pointed to by your
49 `$fpath` variable. To use the completions generated by seaplane you must
50 either add the completion script to one of the existing directories, or add
51 your custom directory to the `$fpath` list. A common directory to either
52 create, or use if it exists is `~/.zfunc`
53
54 $ mkdir -p ~/.zfunc
55
56 Then in your `.zshrc` file, either add:
57
58 compinit
59 fpath+=~/.zfunc
60
61 Note, if your `.zshrc` file already had a line `compinit`, just ensure the
62 `fpath+=~/.zfunc` comes afterwards.
63
64 ZSH looks for files beginning with an underscore and the name of the binary
65 to complete, in our case that would be `_seaplane`:
66
67 $ seaplane shell-completion zsh > ~/.zfunc/_seaplane
68
69 Like BASH, you could alternatively use an `eval` command in your `.zshrc`:
70
71 eval \"$(seaplane shell-completion zsh)\"
72
73 Ensure you close and open your terminal to utilize the completions.
74
75 FISH:
76
77 Completion scripts are commonly stored in `$HOME/.config/fish/completions/`
78 using the file name of the binary to complete with a `.fish` extension:
79
80 $ seaplane shell-completion fish > ~/.config/fish/completions/seaplane.fish
81
82 Ensure you close and open your terminal to utilize the completions.
83
84 POWERSHELL:
85
86 These completion scripts require PowerShell v5.0 or newer. Windows 10 and 11
87 already have a new enough version, but on Windows 7 you will need to download
88 and update it manually which is out of scope for this guide.
89
90 The completions are loaded from a 'profile.' You check if a profile already exists using the command:
91
92 PS C:\\> Test-Path $profile
93
94 If this returns `False`, you must first create a profile:
95
96 PS C:\\> New-Item -path $profile -type file -force
97
98 This creates a file at
99 `${env:USERPROFILE}\\Documents\\WindowsPowerShell\\Microsoft.PowerShell_profile.ps1`.
100
101 Inside this profile file, we can either place the completion script inline,
102 or `source` a separate file (our completion script). This guide will demo
103 placing the completion script inline:
104
105 PS C:\\> seaplane shell-completion powershell \\
106 >> ${env:USERPROFILE}\\Documents\\WindowsPowerShell\\Microsoft.PowerShell_profile.ps1
107";
108
109#[derive(Copy, Clone, Debug)]
110pub struct SeaplaneShellCompletion;
111
112impl SeaplaneShellCompletion {
113 pub fn command() -> Command {
114 Command::new("shell-completion")
115 .about("Generate shell completion scripts for the Seaplane CLI")
116 .after_help(COMPLETION_HELP)
117 .arg(
118 arg!(shell ignore_case required)
119 .help("The shell to generate completion scripts for")
120 .value_parser(value_parser!(Shell)),
121 )
122 }
123}
124
125impl CliCommand for SeaplaneShellCompletion {
126 fn run(&self, ctx: &mut Ctx) -> Result<()> {
127 let mut app = Seaplane::command();
128
129 clap_complete::generate(ctx.args.shell.unwrap(), &mut app, "seaplane", &mut *printer());
130
131 Ok(())
132 }
133
134 fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
135 ctx.args.shell = matches.get_one::<Shell>("shell").copied();
137 Ok(())
138 }
139}