From bb3759be7f8685fea06cc5f8180a1aa4fe6a1690 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Fri, 21 Mar 2025 08:44:32 -0400 Subject: [PATCH] history wip --- .../nu-command/src/platform/input/input_.rs | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/crates/nu-command/src/platform/input/input_.rs b/crates/nu-command/src/platform/input/input_.rs index 29994cb0c2..4f4ff7c4d8 100644 --- a/crates/nu-command/src/platform/input/input_.rs +++ b/crates/nu-command/src/platform/input/input_.rs @@ -2,7 +2,7 @@ use crate::platform::input::legacy_input::LegacyInput; use crate::platform::input::reedline_prompt::ReedlinePrompt; use nu_engine::command_prelude::*; use nu_protocol::shell_error::io::IoError; -use reedline::{Reedline, Signal}; +use reedline::{FileBackedHistory, Reedline, Signal, HISTORY_SIZE}; #[derive(Clone)] pub struct Input; @@ -45,6 +45,21 @@ impl Command for Input { "default value if no input is provided", Some('d'), ) + .named( + "history", + SyntaxShape::OneOf(vec![ + SyntaxShape::Filepath, + SyntaxShape::List(Box::new(SyntaxShape::String)), + ]), + "path to a file to read/write history or a list of history entries", + None, + ) + .named( + "max-history", + SyntaxShape::Int, + "The maximum number of entries to keep in the history", + None, + ) .switch("suppress-output", "don't print keystroke values", Some('s')) .category(Category::Platform) } @@ -74,6 +89,7 @@ impl Command for Input { let prompt_str: Option = call.opt(engine_state, stack, 0)?; let default_val: Option = call.get_flag(engine_state, stack, "default")?; + let history_val: Option = call.get_flag(engine_state, stack, "history")?; let from_io_error = IoError::factory(call.head, None); @@ -81,6 +97,24 @@ impl Command for Input { (Some(_prompt), Some(val)) => format!("(default: {val}) "), _ => "".to_string(), }; + + // Here we will render the default prompt to the right + let history = match history_val { + None => None, + Some(Value::String { val, .. }) => Some(Box::new( + FileBackedHistory::with_file(HISTORY_SIZE, val.into()) + .expect("Error creating history file"), + )), + Some(h) => { + return Err(ShellError::UnsupportedInput { + msg: "Unsupported history type".to_string(), + input: "value originated from here".to_string(), + msg_span: call.head, + input_span: h.span(), + }) + } // Value::List { vals, .. } => Some(Box::new((usize::MAX, val.into()))), + }; + let prompt = ReedlinePrompt { indicator: default_str, left_prompt: prompt_str.unwrap_or("".to_string()), @@ -88,8 +122,13 @@ impl Command for Input { }; let mut line_editor = Reedline::create(); line_editor = line_editor.with_ansi_colors(false); + line_editor = match history { + Some(h) => line_editor.with_history(h), + None => line_editor, + }; let mut buf = String::new(); + loop { match line_editor.read_line(&prompt) { Ok(Signal::Success(buffer)) => {