1use crate::cli::Cli;
2use clap::CommandFactory;
3use clap_complete::{Shell, generate};
4use colored::*;
5use std::fs;
6use std::io::{Error, ErrorKind};
7
8fn install_bash_completions(cmd: &mut clap::Command) -> Result<(), Error> {
9 println!("Installing bash completions...");
10 let home = dirs::home_dir()
11 .ok_or_else(|| Error::new(ErrorKind::NotFound, "Home directory not found"))?;
12 let completions_dir = home.join(".local/share/bash-completion/completions");
13 fs::create_dir_all(&completions_dir)?;
14 let path = completions_dir.join("zoi");
15 let mut file = fs::File::create(&path)?;
16 generate(Shell::Bash, cmd, "zoi", &mut file);
17 println!("Bash completions installed in: {:?}", path);
18 Ok(())
19}
20
21fn install_zsh_completions(cmd: &mut clap::Command) -> Result<(), Error> {
22 println!("Installing zsh completions...");
23 let home = dirs::home_dir()
24 .ok_or_else(|| Error::new(ErrorKind::NotFound, "Home directory not found"))?;
25 let completions_dir = home.join(".zsh/completions");
26 fs::create_dir_all(&completions_dir)?;
27 let path = completions_dir.join("_zoi");
28 let mut file = fs::File::create(&path)?;
29 generate(Shell::Zsh, cmd, "zoi", &mut file);
30 println!("Zsh completions installed in: {:?}", path);
31 println!("Ensure the directory is in your $fpath. Add this to your .zshrc if it's not:");
32 println!(" fpath=({:?} $fpath)", completions_dir);
33 Ok(())
34}
35
36fn install_fish_completions(cmd: &mut clap::Command) -> Result<(), Error> {
37 println!("Installing fish completions...");
38 let home = dirs::home_dir()
39 .ok_or_else(|| Error::new(ErrorKind::NotFound, "Home directory not found"))?;
40 let completions_dir = home.join(".config/fish/completions");
41 fs::create_dir_all(&completions_dir)?;
42 let path = completions_dir.join("zoi.fish");
43 let mut file = fs::File::create(&path)?;
44 generate(Shell::Fish, cmd, "zoi", &mut file);
45 println!("Fish completions installed in: {:?}", path);
46 Ok(())
47}
48
49fn install_elvish_completions(cmd: &mut clap::Command) -> Result<(), Error> {
50 println!("Installing elvish completions...");
51 let home = dirs::home_dir()
52 .ok_or_else(|| Error::new(ErrorKind::NotFound, "Home directory not found"))?;
53 let completions_dir = home.join(".config/elvish/completions");
54 fs::create_dir_all(&completions_dir)?;
55 let path = completions_dir.join("zoi.elv");
56 let mut file = fs::File::create(&path)?;
57 generate(Shell::Elvish, cmd, "zoi", &mut file);
58 println!("Elvish completions installed in: {:?}", path);
59 Ok(())
60}
61
62#[cfg(windows)]
63fn install_powershell_completions(cmd: &mut clap::Command) -> Result<(), Error> {
64 println!("Installing PowerShell completions...");
65 let home = dirs::home_dir()
66 .ok_or_else(|| Error::new(ErrorKind::NotFound, "Home directory not found"))?;
67 let profile_dir = home.join("Documents/PowerShell");
68 fs::create_dir_all(&profile_dir)?;
69 let profile_path = profile_dir.join("Microsoft.PowerShell_profile.ps1");
70
71 let mut file = fs::OpenOptions::new()
72 .append(true)
73 .create(true)
74 .open(&profile_path)?;
75 use std::io::Write;
76 writeln!(file, "")?;
77
78 let mut script_buf = Vec::new();
79 generate(Shell::PowerShell, cmd, "zoi", &mut script_buf);
80 file.write_all(&script_buf)?;
81
82 println!(
83 "PowerShell completion script appended to your profile: {:?}",
84 profile_path
85 );
86 println!("Please restart your shell or run '. $PROFILE' to activate it.");
87 Ok(())
88}
89
90pub fn run(shell: Shell) {
91 let mut cmd = Cli::command();
92
93 let result = if cfg!(windows) {
94 #[cfg(windows)]
95 {
96 if shell == Shell::PowerShell {
97 install_powershell_completions(&mut cmd)
98 } else {
99 eprintln!("On Windows, only PowerShell completions are supported.");
100 return;
101 }
102 }
103 #[cfg(not(windows))]
104 {
105 Ok(())
106 }
107 } else {
108 match shell {
109 Shell::Bash => install_bash_completions(&mut cmd),
110 Shell::Zsh => install_zsh_completions(&mut cmd),
111 Shell::Fish => install_fish_completions(&mut cmd),
112 Shell::Elvish => install_elvish_completions(&mut cmd),
113 Shell::PowerShell => {
114 eprintln!("PowerShell completions are only for Windows.");
115 return;
116 }
117 _ => {
118 eprintln!(
119 "{}: Automatic installation for '{}' is not yet supported.",
120 "Warning".yellow(),
121 shell
122 );
123 println!(
124 "Please generate them manually: zoi generate-completions {}",
125 shell
126 );
127 return;
128 }
129 }
130 };
131
132 if let Err(e) = result {
133 eprintln!("{}: {}", "Error".red().bold(), e);
134 }
135}