feat: add executed commands to history

This commit is contained in:
iff 2025-04-10 16:39:31 +02:00
parent 7d41d2ba43
commit 3b9b2c662e
8 changed files with 114 additions and 21 deletions

View file

@ -1,4 +1,4 @@
use crate::shell::Data; use crate::shell::{shell_evaluated_commands, Data};
use crate::style::highlight_difference; use crate::style::highlight_difference;
use crate::suggestions; use crate::suggestions;
use crate::suggestions::suggest_candidates; use crate::suggestions::suggest_candidates;
@ -192,7 +192,10 @@ pub fn cnf(data: &mut Data) {
// retry after installing package // retry after installing package
if system::install_package(data, &package_manager, &package) { if system::install_package(data, &package_manager, &package) {
let status = suggestions::run_suggestion(data, &data.command); 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); data.update_error(None);
suggestion(data); suggestion(data);
} }

View file

@ -650,26 +650,96 @@ pub fn shell_syntax(shell: &str, command: &str) -> String {
} }
} }
pub fn shell_evaluated_commands(shell: &str, command: &str) -> Option<String> { pub fn shell_evaluated_commands(shell: &str, command: &str, cd: bool) {
let lines = command let lines = command
.lines() .lines()
.map(|line| line.trim().trim_end_matches(['\\', ';', '|', '&'])) .map(|line| line.trim().trim_end_matches(['\\', ';', '|', '&']))
.collect::<Vec<&str>>(); .collect::<Vec<&str>>();
let mut dirs = Vec::new();
for line in lines { let cd = if cd {
if let Some(dir) = line.strip_prefix("cd ") { let dirs = {
dirs.push(dir.to_string()); 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(""); let print = match shell {
if cd_dir.is_empty() { "bash" => {
return None; let command = command.replace("$", "\\$").replace("`", "\\`");
} let template = BashTemplate {
command: &command,
#[allow(clippy::single_match)] cd: cd.as_deref(),
match shell { };
"nu" => Some(cd_dir), template.render().unwrap()
_ => Some(format!("cd {}", cd_dir)), }
} "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());
} }

View file

@ -148,12 +148,10 @@ pub fn confirm_suggestion(data: &Data) -> Result<(), String> {
let process = run_suggestion(data, command); let process = run_suggestion(data, command);
if process.success() { if process.success() {
let cd = shell_evaluated_commands(shell, command); shell_evaluated_commands(shell, command, true);
if let Some(cd) = cd {
println!("{}", cd);
}
Ok(()) Ok(())
} else { } else {
shell_evaluated_commands(shell, command, false);
if now.elapsed() > Duration::from_secs(3) { if now.elapsed() > Duration::from_secs(3) {
exit(1); exit(1);
} }

5
core/templates/eval.bash Normal file
View file

@ -0,0 +1,5 @@
history -s {{ command }};
{%- if let Some(cd) = self.cd %}
cd {{ cd }}
{% endif %}

6
core/templates/eval.fish Normal file
View file

@ -0,0 +1,6 @@
builtin history append "{{ command }}";
builtin history merge;
{%- if let Some(cd) = self.cd %}
cd {{ cd }}
{% endif %}

3
core/templates/eval.nu Normal file
View file

@ -0,0 +1,3 @@
{%- if let Some(cd) = self.cd %}
{{ cd }}
{% endif %}

3
core/templates/eval.sh Normal file
View file

@ -0,0 +1,3 @@
{%- if let Some(cd) = self.cd %}
cd {{ cd }}
{% endif %}

5
core/templates/eval.zsh Normal file
View file

@ -0,0 +1,5 @@
print -s {{ command }};
{%- if let Some(cd) = self.cd %}
cd {{ cd }}
{% endif %}