diff --git a/core/src/modes.rs b/core/src/modes.rs index 1a8c0c1..d5e9a41 100644 --- a/core/src/modes.rs +++ b/core/src/modes.rs @@ -1,4 +1,4 @@ -use crate::shell::Data; +use crate::shell::{shell_evaluated_commands, Data}; use crate::style::highlight_difference; use crate::suggestions; use crate::suggestions::suggest_candidates; @@ -192,7 +192,10 @@ pub fn cnf(data: &mut Data) { // retry after installing package if system::install_package(data, &package_manager, &package) { let status = suggestions::run_suggestion(data, &data.command); - if !status.success() { + if status.success() { + shell_evaluated_commands(&shell, &data.command, true); + } else { + shell_evaluated_commands(&shell, &data.command, false); data.update_error(None); suggestion(data); } diff --git a/core/src/shell.rs b/core/src/shell.rs index 247bd31..05e55fe 100644 --- a/core/src/shell.rs +++ b/core/src/shell.rs @@ -650,26 +650,96 @@ pub fn shell_syntax(shell: &str, command: &str) -> String { } } -pub fn shell_evaluated_commands(shell: &str, command: &str) -> Option { +pub fn shell_evaluated_commands(shell: &str, command: &str, cd: bool) { let lines = command .lines() .map(|line| line.trim().trim_end_matches(['\\', ';', '|', '&'])) .collect::>(); - let mut dirs = Vec::new(); - for line in lines { - if let Some(dir) = line.strip_prefix("cd ") { - dirs.push(dir.to_string()); + + let cd = if cd { + let dirs = { + let mut dirs = Vec::new(); + for line in lines { + if let Some(dir) = line.strip_prefix("cd ") { + dirs.push(dir.to_string()); + } + } + dirs.join("") + }; + if dirs.is_empty() { + None + } else { + Some(dirs.to_string()) } + } else { + None + }; + + #[derive(Template)] + #[template(path = "eval.bash", escape = "none")] + struct BashTemplate<'a> { + command: &'a str, + cd: Option<&'a str>, + } + #[derive(Template)] + #[template(path = "eval.zsh", escape = "none")] + struct ZshTemplate<'a> { + command: &'a str, + cd: Option<&'a str>, + } + #[derive(Template)] + #[template(path = "eval.fish", escape = "none")] + struct FishTemplate<'a> { + command: &'a str, + cd: Option<&'a str>, + } + #[derive(Template)] + #[template(path = "eval.nu", escape = "none")] + struct NuTemplate<'a> { + cd: Option<&'a str>, + } + #[derive(Template)] + #[template(path = "eval.sh", escape = "none")] + struct GenericTemplate<'a> { + cd: Option<&'a str>, } - let cd_dir = dirs.join(""); - if cd_dir.is_empty() { - return None; - } - - #[allow(clippy::single_match)] - match shell { - "nu" => Some(cd_dir), - _ => Some(format!("cd {}", cd_dir)), - } + let print = match shell { + "bash" => { + let command = command.replace("$", "\\$").replace("`", "\\`"); + let template = BashTemplate { + command: &command, + cd: cd.as_deref(), + }; + template.render().unwrap() + } + "zsh" => { + let command = command.replace("$", "\\$").replace("`", "\\`"); + let template = ZshTemplate { + command: &command, + cd: cd.as_deref(), + }; + template.render().unwrap() + } + "fish" => { + let command = command + .replace("$", "\\$") + .replace("`", "\\`") + .replace("\"", "\\\""); + let template = FishTemplate { + command: &command, + cd: cd.as_deref(), + }; + template.render().unwrap() + } + "nu" => { + let template = NuTemplate { cd: cd.as_deref() }; + template.render().unwrap() + } + _ => { + let template = GenericTemplate { cd: cd.as_deref() }; + template.render().unwrap() + } + }; + println!("{}", print.trim()); } diff --git a/core/src/suggestions.rs b/core/src/suggestions.rs index 5a3c4c5..c510c4d 100644 --- a/core/src/suggestions.rs +++ b/core/src/suggestions.rs @@ -148,12 +148,10 @@ pub fn confirm_suggestion(data: &Data) -> Result<(), String> { let process = run_suggestion(data, command); if process.success() { - let cd = shell_evaluated_commands(shell, command); - if let Some(cd) = cd { - println!("{}", cd); - } + shell_evaluated_commands(shell, command, true); Ok(()) } else { + shell_evaluated_commands(shell, command, false); if now.elapsed() > Duration::from_secs(3) { exit(1); } diff --git a/core/templates/eval.bash b/core/templates/eval.bash new file mode 100644 index 0000000..e3a3ad6 --- /dev/null +++ b/core/templates/eval.bash @@ -0,0 +1,5 @@ +history -s {{ command }}; + +{%- if let Some(cd) = self.cd %} +cd {{ cd }} +{% endif %} diff --git a/core/templates/eval.fish b/core/templates/eval.fish new file mode 100644 index 0000000..8d46055 --- /dev/null +++ b/core/templates/eval.fish @@ -0,0 +1,6 @@ +builtin history append "{{ command }}"; +builtin history merge; + +{%- if let Some(cd) = self.cd %} +cd {{ cd }} +{% endif %} diff --git a/core/templates/eval.nu b/core/templates/eval.nu new file mode 100644 index 0000000..c43e2ab --- /dev/null +++ b/core/templates/eval.nu @@ -0,0 +1,3 @@ +{%- if let Some(cd) = self.cd %} +{{ cd }} +{% endif %} diff --git a/core/templates/eval.sh b/core/templates/eval.sh new file mode 100644 index 0000000..eb1afdf --- /dev/null +++ b/core/templates/eval.sh @@ -0,0 +1,3 @@ +{%- if let Some(cd) = self.cd %} +cd {{ cd }} +{% endif %} diff --git a/core/templates/eval.zsh b/core/templates/eval.zsh new file mode 100644 index 0000000..19dd3e1 --- /dev/null +++ b/core/templates/eval.zsh @@ -0,0 +1,5 @@ +print -s {{ command }}; + +{%- if let Some(cd) = self.cd %} +cd {{ cd }} +{% endif %}