history wip

This commit is contained in:
Florent Vilmart 2025-03-21 08:44:32 -04:00
parent 6e78f36075
commit bb3759be7f

View File

@ -2,7 +2,7 @@ use crate::platform::input::legacy_input::LegacyInput;
use crate::platform::input::reedline_prompt::ReedlinePrompt; use crate::platform::input::reedline_prompt::ReedlinePrompt;
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use nu_protocol::shell_error::io::IoError; use nu_protocol::shell_error::io::IoError;
use reedline::{Reedline, Signal}; use reedline::{FileBackedHistory, Reedline, Signal, HISTORY_SIZE};
#[derive(Clone)] #[derive(Clone)]
pub struct Input; pub struct Input;
@ -45,6 +45,21 @@ impl Command for Input {
"default value if no input is provided", "default value if no input is provided",
Some('d'), 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')) .switch("suppress-output", "don't print keystroke values", Some('s'))
.category(Category::Platform) .category(Category::Platform)
} }
@ -74,6 +89,7 @@ impl Command for Input {
let prompt_str: Option<String> = call.opt(engine_state, stack, 0)?; let prompt_str: Option<String> = call.opt(engine_state, stack, 0)?;
let default_val: Option<String> = call.get_flag(engine_state, stack, "default")?; let default_val: Option<String> = call.get_flag(engine_state, stack, "default")?;
let history_val: Option<Value> = call.get_flag(engine_state, stack, "history")?;
let from_io_error = IoError::factory(call.head, None); let from_io_error = IoError::factory(call.head, None);
@ -81,6 +97,24 @@ impl Command for Input {
(Some(_prompt), Some(val)) => format!("(default: {val}) "), (Some(_prompt), Some(val)) => format!("(default: {val}) "),
_ => "".to_string(), _ => "".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 { let prompt = ReedlinePrompt {
indicator: default_str, indicator: default_str,
left_prompt: prompt_str.unwrap_or("".to_string()), left_prompt: prompt_str.unwrap_or("".to_string()),
@ -88,8 +122,13 @@ impl Command for Input {
}; };
let mut line_editor = Reedline::create(); let mut line_editor = Reedline::create();
line_editor = line_editor.with_ansi_colors(false); 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(); let mut buf = String::new();
loop { loop {
match line_editor.read_line(&prompt) { match line_editor.read_line(&prompt) {
Ok(Signal::Success(buffer)) => { Ok(Signal::Success(buffer)) => {