xyz_rust/cli/
completion.rs1use std::fmt::Write as _;
5use std::io::Write;
6
7pub fn print_completion(
8 top_words: &[String],
9 out: &mut dyn Write,
10 err_out: &mut dyn Write,
11 bin: &str,
12 shell: &str,
13) -> i32 {
14 let mut names: Vec<&String> = Vec::new();
15 let mut seen: Vec<&str> = Vec::new();
16 for w in top_words {
17 if !seen.contains(&w.as_str()) {
18 seen.push(w.as_str());
19 names.push(w);
20 }
21 }
22 let mut list: Vec<String> = names.iter().map(|s| s.to_string()).collect();
23 list.extend(
24 [
25 "completion",
26 "help",
27 "serve",
28 "mcp",
29 "-h",
30 "--help",
31 "-v",
32 "--version",
33 ]
34 .iter()
35 .map(|s| s.to_string()),
36 );
37 let words = list.join(" ");
38 let mut buf = String::new();
39 match shell {
40 "bash" => {
41 let _ = write!(
42 buf,
43 "# {bin} completion for bash\n_{bin}_completions() {{\n local cur\n cur=\"${{COMP_WORDS[COMP_CWORD]}}\"\n COMPREPLY=( $(compgen -W \"{words}\" -- \"$cur\") )\n}}\ncomplete -F _{bin}_completions {bin}\n"
44 );
45 }
46 "zsh" => {
47 let _ = write!(
48 buf,
49 "#compdef {bin}\n_{bin}_completions() {{\n local -a cmds\n cmds=({words})\n _describe '{bin}' cmds\n}}\ncompdef _{bin}_completions {bin}\n"
50 );
51 }
52 "fish" => {
53 for n in &list[..list.len().saturating_sub(6)] {
54 let _ = writeln!(buf, "complete -c {bin} -f -a {n}");
55 }
56 let _ = writeln!(buf, "complete -c {bin} -f -a completion");
57 }
58 _ => {
59 let _ = writeln!(err_out, "unknown shell {shell:?} (want bash|zsh|fish)");
60 return 2;
61 }
62 }
63 let _ = write!(out, "{buf}");
64 0
65}