From f575eac1dece4a0bdf46c5c58312c9b3f68e1b65 Mon Sep 17 00:00:00 2001 From: gwenn <gtreguier@gmail.com> Date: Sun, 26 Mar 2017 20:23:23 +0200 Subject: [PATCH] Improve kill ring related code --- src/keymap.rs | 10 ++++++++++ src/kill_ring.rs | 6 +++--- src/lib.rs | 37 +++++-------------------------------- 3 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/keymap.rs b/src/keymap.rs index e39db68f..fca6cc7e 100644 --- a/src/keymap.rs +++ b/src/keymap.rs @@ -45,6 +45,16 @@ pub enum Cmd { } impl Cmd { + pub fn should_reset_kill_ring(&self) -> bool { + match *self { + Cmd::Kill(Movement::BackwardChar(_)) | + Cmd::Kill(Movement::ForwardChar(_)) => true, + Cmd::ClearScreen | Cmd::Kill(_) | Cmd::Noop | Cmd::Suspend | Cmd::Yank(_, _) | + Cmd::YankPop => false, + _ => true, + } + } + fn is_repeatable_change(&self) -> bool { match *self { Cmd::Insert(_, _) => true, diff --git a/src/kill_ring.rs b/src/kill_ring.rs index cbbdbfbe..635cb4f5 100644 --- a/src/kill_ring.rs +++ b/src/kill_ring.rs @@ -15,7 +15,9 @@ pub enum Mode { pub struct KillRing { slots: Vec<String>, + // where we are in the kill ring index: usize, + // whether or not the last command was a kill or a yank last_action: Action, } @@ -44,9 +46,7 @@ impl KillRing { } match dir { Mode::Append => self.slots[self.index].push_str(text), - Mode::Prepend => { - self.slots[self.index] = String::from(text) + &self.slots[self.index] - } + Mode::Prepend => self.slots[self.index].insert_str(0, text), }; } _ => { diff --git a/src/lib.rs b/src/lib.rs index 53851a28..db0c4329 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -863,11 +863,14 @@ fn readline_edit<C: Completer>(prompt: &str, let rc = s.next_cmd(&mut rdr); let mut cmd = try!(rc); + if cmd.should_reset_kill_ring() { + editor.reset_kill_ring(); + } + // autocomplete if cmd == Cmd::Complete && completer.is_some() { let next = try!(complete_line(&mut rdr, &mut s, completer.unwrap(), &editor.config)); if next.is_some() { - editor.kill_ring.reset(); cmd = next.unwrap(); } else { continue; @@ -875,11 +878,9 @@ fn readline_edit<C: Completer>(prompt: &str, } if let Cmd::SelfInsert(n, c) = cmd { - editor.kill_ring.reset(); try!(edit_insert(&mut s, c, n)); continue; } else if let Cmd::Insert(n, text) = cmd { - editor.kill_ring.reset(); try!(edit_yank(&mut s, &text, Anchor::Before, n)); continue; } @@ -896,31 +897,25 @@ fn readline_edit<C: Completer>(prompt: &str, match cmd { Cmd::Move(Movement::BeginningOfLine) => { - editor.kill_ring.reset(); // Move to the beginning of line. try!(edit_move_home(&mut s)) } Cmd::Move(Movement::ViFirstPrint) => { - editor.kill_ring.reset(); try!(edit_move_home(&mut s)); try!(edit_move_to_next_word(&mut s, At::Start, Word::Big, 1)) } Cmd::Move(Movement::BackwardChar(n)) => { - editor.kill_ring.reset(); // Move back a character. try!(edit_move_backward(&mut s, n)) } Cmd::Kill(Movement::ForwardChar(n)) => { - editor.kill_ring.reset(); // Delete (forward) one character at point. try!(edit_delete(&mut s, n)) } Cmd::Replace(n, c) => { - editor.kill_ring.reset(); try!(edit_replace_char(&mut s, c, n)); } Cmd::EndOfFile => { - editor.kill_ring.reset(); if !s.edit_state.is_emacs_mode() && !s.line.is_empty() { try!(edit_move_end(&mut s)); break; @@ -931,17 +926,14 @@ fn readline_edit<C: Completer>(prompt: &str, } } Cmd::Move(Movement::EndOfLine) => { - editor.kill_ring.reset(); // Move to the end of line. try!(edit_move_end(&mut s)) } Cmd::Move(Movement::ForwardChar(n)) => { - editor.kill_ring.reset(); // Move forward a character. try!(edit_move_forward(&mut s, n)) } Cmd::Kill(Movement::BackwardChar(n)) => { - editor.kill_ring.reset(); // Delete one character backward. try!(edit_backspace(&mut s, n)) } @@ -963,17 +955,14 @@ fn readline_edit<C: Completer>(prompt: &str, try!(s.refresh_line()) } Cmd::NextHistory => { - editor.kill_ring.reset(); // Fetch the next command from the history list. try!(edit_history_next(&mut s, &editor.history, false)) } Cmd::PreviousHistory => { - editor.kill_ring.reset(); // Fetch the previous command from the history list. try!(edit_history_next(&mut s, &editor.history, true)) } Cmd::TransposeChars => { - editor.kill_ring.reset(); // Exchange the char before cursor with the character at cursor. try!(edit_transpose_chars(&mut s)) } @@ -986,7 +975,6 @@ fn readline_edit<C: Completer>(prompt: &str, #[cfg(unix)] Cmd::QuotedInsert => { // Quoted insert - editor.kill_ring.reset(); let c = try!(rdr.next_char()); try!(edit_insert(&mut s, c, 1)) // FIXME } @@ -997,7 +985,6 @@ fn readline_edit<C: Completer>(prompt: &str, } } Cmd::ViYankTo(mvt) => { - editor.kill_ring.reset(); if let Some(text) = s.line.copy(mvt) { editor.kill_ring.kill(&text, Mode::Append) } @@ -1005,7 +992,6 @@ fn readline_edit<C: Completer>(prompt: &str, // TODO CTRL-_ // undo Cmd::AcceptLine => { // Accept the line regardless of where the cursor is. - editor.kill_ring.reset(); try!(edit_move_end(&mut s)); break; } @@ -1017,22 +1003,18 @@ fn readline_edit<C: Completer>(prompt: &str, } Cmd::BeginningOfHistory => { // move to first entry in history - editor.kill_ring.reset(); try!(edit_history(&mut s, &editor.history, true)) } Cmd::EndOfHistory => { // move to last entry in history - editor.kill_ring.reset(); try!(edit_history(&mut s, &editor.history, false)) } Cmd::Move(Movement::BackwardWord(n, word_def)) => { // move backwards one word - editor.kill_ring.reset(); try!(edit_move_to_prev_word(&mut s, word_def, n)) } Cmd::CapitalizeWord => { // capitalize word after point - editor.kill_ring.reset(); try!(edit_word(&mut s, WordAction::CAPITALIZE)) } Cmd::Kill(Movement::ForwardWord(n, at, word_def)) => { @@ -1043,22 +1025,18 @@ fn readline_edit<C: Completer>(prompt: &str, } Cmd::Move(Movement::ForwardWord(n, at, word_def)) => { // move forwards one word - editor.kill_ring.reset(); try!(edit_move_to_next_word(&mut s, at, word_def, n)) } Cmd::DowncaseWord => { // lowercase word after point - editor.kill_ring.reset(); try!(edit_word(&mut s, WordAction::LOWERCASE)) } Cmd::TransposeWords(n) => { // transpose words - editor.kill_ring.reset(); try!(edit_transpose_words(&mut s, n)) } Cmd::UpcaseWord => { // uppercase word after point - editor.kill_ring.reset(); try!(edit_word(&mut s, WordAction::UPPERCASE)) } Cmd::YankPop => { @@ -1067,17 +1045,13 @@ fn readline_edit<C: Completer>(prompt: &str, try!(edit_yank_pop(&mut s, yank_size, text)) } } - Cmd::Move(Movement::ViCharSearch(n, cs)) => { - editor.kill_ring.reset(); - try!(edit_move_to(&mut s, cs, n)) - } + Cmd::Move(Movement::ViCharSearch(n, cs)) => try!(edit_move_to(&mut s, cs, n)), Cmd::Kill(Movement::ViCharSearch(n, cs)) => { if let Some(text) = try!(edit_delete_to(&mut s, cs, n)) { editor.kill_ring.kill(&text, Mode::Append) } } Cmd::Interrupt => { - editor.kill_ring.reset(); return Err(error::ReadlineError::Interrupted); } #[cfg(unix)] @@ -1090,7 +1064,6 @@ fn readline_edit<C: Completer>(prompt: &str, } Cmd::Noop => {} _ => { - editor.kill_ring.reset(); // Ignore the character typed. } } -- GitLab