diff --git a/src/cli.rs b/src/cli.rs index e88ee054fe..d52a55e267 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -306,6 +306,7 @@ pub async fn cli() -> Result<(), Box> { whole_stream_command(SkipWhile), per_item_command(Enter), per_item_command(Help), + per_item_command(History), whole_stream_command(Exit), whole_stream_command(Autoview), whole_stream_command(Pivot), @@ -413,6 +414,7 @@ pub async fn cli() -> Result<(), Box> { match process_line(readline, &mut context).await { LineResult::Success(line) => { rl.add_history_entry(line.clone()); + let _ = rl.save_history(&History::path()); } LineResult::CtrlC => { @@ -440,6 +442,7 @@ pub async fn cli() -> Result<(), Box> { LineResult::Error(line, err) => { rl.add_history_entry(line.clone()); + let _ = rl.save_history(&History::path()); context.with_host(|host| { print_err(err, host, &Text::from(line)); diff --git a/src/commands.rs b/src/commands.rs index 7f0fa0a25a..c75ca81192 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -32,6 +32,7 @@ pub(crate) mod from_yaml; pub(crate) mod get; pub(crate) mod group_by; pub(crate) mod help; +pub(crate) mod history; pub(crate) mod last; pub(crate) mod lines; pub(crate) mod ls; @@ -106,6 +107,7 @@ pub(crate) use from_yaml::FromYML; pub(crate) use get::Get; pub(crate) use group_by::GroupBy; pub(crate) use help::Help; +pub(crate) use history::History; pub(crate) use last::Last; pub(crate) use lines::Lines; pub(crate) use ls::LS; diff --git a/src/commands/history.rs b/src/commands/history.rs new file mode 100644 index 0000000000..fdc6d655a2 --- /dev/null +++ b/src/commands/history.rs @@ -0,0 +1,49 @@ +use crate::cli::History as HistoryFile; +use crate::commands::PerItemCommand; +use crate::errors::ShellError; +use crate::parser::registry::{self}; +use crate::prelude::*; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +pub struct History; + +impl PerItemCommand for History { + fn name(&self) -> &str { + "history" + } + + fn signature(&self) -> registry::Signature { + Signature::build("history") + } + + fn usage(&self) -> &str { + "Display command history." + } + + fn run( + &self, + call_info: &CallInfo, + _registry: &CommandRegistry, + _raw_args: &RawCommandArgs, + _input: Tagged, + ) -> Result { + let tag = call_info.name_tag.clone(); + + let stream = async_stream! { + let history_path = HistoryFile::path(); + let file = File::open(history_path); + if let Ok(file) = file { + let reader = BufReader::new(file); + for line in reader.lines() { + if let Ok(line) = line { + yield ReturnSuccess::value(Value::string(line).tagged(tag.clone())); + } + } + } else { + yield Err(ShellError::labeled_error("Could not open history", "history file could not be opened", tag.clone())); + } + }; + Ok(stream.to_output_stream()) + } +}