diff --git a/src/edit.rs b/src/edit.rs index e6881eb44..2a2ca6c0e 100644 --- a/src/edit.rs +++ b/src/edit.rs @@ -636,6 +636,7 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> { if history.is_empty() { return Ok(()); } + self.ctx.recall(!prev && self.line.is_empty()); if self.ctx.history_index == history.len() { if prev { // Save the current edited line before overwriting it @@ -762,7 +763,7 @@ pub fn init_state<'out, H: Helper>( byte_buffer: [0; 4], changes: Changeset::new(), helper, - ctx: Context::new(history), + ctx: Context::new(history, None), hint: Some(Box::new("hint".to_owned())), highlight_char: false, forced_refresh: false, diff --git a/src/hint.rs b/src/hint.rs index 1b4f88ab0..93f5433e1 100644 --- a/src/hint.rs +++ b/src/hint.rs @@ -95,7 +95,7 @@ mod test { #[test] pub fn empty_history() { let history = DefaultHistory::new(); - let ctx = Context::new(&history); + let ctx = Context::new(&history, None); let hinter = HistoryHinter {}; let hint = hinter.hint("test", 4, &ctx); assert_eq!(None, hint); diff --git a/src/history.rs b/src/history.rs index 23dc2376f..7fffde26a 100644 --- a/src/history.rs +++ b/src/history.rs @@ -172,7 +172,7 @@ pub trait History { */ /// recently used index - fn recent_index(&self) -> Option; + fn recent_index(&mut self) -> Option; /// Update recently used index fn set_recent_index(&mut self, entry: Option<(usize, &str)>); } @@ -427,8 +427,8 @@ impl History for MemHistory { } } - fn recent_index(&self) -> Option { - self.recent + fn recent_index(&mut self) -> Option { + self.recent.take() } fn set_recent_index(&mut self, entry: Option<(usize, &str)>) { @@ -813,7 +813,7 @@ impl History for FileHistory { self.mem.starts_with(term, start, dir) } - fn recent_index(&self) -> Option { + fn recent_index(&mut self) -> Option { self.mem.recent_index() } diff --git a/src/lib.rs b/src/lib.rs index bfe4b1262..67fd40a60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -557,15 +557,17 @@ impl<'h, H: ?Sized + Helper> Helper for &'h H {} pub struct Context<'h> { history: &'h dyn History, history_index: usize, + recent_index: Option, } impl<'h> Context<'h> { /// Constructor. Visible for testing. #[must_use] - pub fn new(history: &'h dyn History) -> Self { + pub fn new(history: &'h dyn History, recent_index: Option) -> Self { Context { history, - history_index: history.recent_index().unwrap_or(history.len()), + history_index: history.len(), + recent_index, } } @@ -580,6 +582,14 @@ impl<'h> Context<'h> { pub fn history_index(&self) -> usize { self.history_index } + + pub(crate) fn recall(&mut self, next_and_empty: bool) { + if let Some(idx) = self.recent_index.take() { + if next_and_empty { + self.history_index = idx; + } + } + } } /// Line editor @@ -694,7 +704,8 @@ impl Editor { let mut stdout = self.term.create_writer(); self.kill_ring.reset(); // TODO recreate a new kill ring vs reset - let ctx = Context::new(&self.history); + let recent_index = self.history.recent_index(); + let ctx = Context::new(&self.history, recent_index); let mut s = State::new(&mut stdout, prompt, self.helper.as_ref(), ctx); let mut input_state = InputState::new(&self.config, &self.custom_bindings); diff --git a/src/sqlite_history.rs b/src/sqlite_history.rs index f0889cc32..46eea72a6 100644 --- a/src/sqlite_history.rs +++ b/src/sqlite_history.rs @@ -411,7 +411,7 @@ PRAGMA incremental_vacuum; self.search_match(term, start, dir, true) } - fn recent_index(&self) -> Option { + fn recent_index(&mut self) -> Option { None // TODO }