From a53ec57b668cb1f6944a0f52f852ab8d4efbfda5 Mon Sep 17 00:00:00 2001 From: gwenn Date: Sun, 19 May 2019 10:17:11 +0200 Subject: [PATCH] Improve undo action There is no need to temporarly remove the change listener. Just use `try_borrow_mut`. --- src/lib.rs | 3 --- src/line_buffer.rs | 26 ++++++++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f2dad47d04..5699d8f5b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -515,7 +515,6 @@ fn readline_edit( kill_ring.kill(&text, Mode::Append) } } - // TODO CTRL-_ // undo Cmd::AcceptLine => { #[cfg(test)] { @@ -574,11 +573,9 @@ fn readline_edit( } Cmd::Move(Movement::ViCharSearch(n, cs)) => s.edit_move_to(cs, n)?, Cmd::Undo(n) => { - s.line.remove_change_listener(); if s.changes.borrow_mut().undo(&mut s.line, n) { s.refresh_line()?; } - s.line.set_change_listener(s.changes.clone()); } Cmd::Interrupt => { return Err(error::ReadlineError::Interrupted); diff --git a/src/line_buffer.rs b/src/line_buffer.rs index a45dfffb39..5daeadf3d0 100644 --- a/src/line_buffer.rs +++ b/src/line_buffer.rs @@ -98,10 +98,6 @@ impl LineBuffer { self.cl = Some(dl); } - pub(crate) fn remove_change_listener(&mut self) { - self.cl = None; - } - /// Extracts a string slice containing the entire buffer. pub fn as_str(&self) -> &str { &self.buf @@ -201,7 +197,10 @@ impl LineBuffer { if n == 1 { self.buf.insert(self.pos, ch); for cl in &self.cl { - cl.borrow_mut().insert_char(self.pos, ch); + if let Ok(mut cl) = cl.try_borrow_mut() { + cl.insert_char(self.pos, ch); + } // Ok: while undoing, cl is borrowed. And we want to ignore changes while + // undoing. } } else { let text = iter::repeat(ch).take(n).collect::(); @@ -644,8 +643,10 @@ impl LineBuffer { pub fn replace(&mut self, range: Range, text: &str) { let start = range.start; for cl in &self.cl { - cl.borrow_mut() - .replace(start, self.buf.index(range.clone()), text); + if let Ok(mut cl) = cl.try_borrow_mut() { + cl.replace(start, self.buf.index(range.clone()), text); + } // Ok: while undoing, cl is borrowed. And we want to ignore changes while + // undoing. } self.buf.drain(range); if start == self.buf.len() { @@ -660,7 +661,10 @@ impl LineBuffer { /// Return `true` if the text has been inserted at the end of the line. pub fn insert_str(&mut self, idx: usize, s: &str) -> bool { for cl in &self.cl { - cl.borrow_mut().insert_str(idx, s); + if let Ok(mut cl) = cl.try_borrow_mut() { + cl.insert_str(idx, s); + } // Ok: while undoing, cl is borrowed. And we want to ignore changes while + // undoing. } if idx == self.buf.len() { self.buf.push_str(s); @@ -685,8 +689,10 @@ impl LineBuffer { } } for cl in &self.cl { - cl.borrow_mut() - .delete(range.start, &self.buf[range.start..range.end], dir); + if let Ok(mut cl) = cl.try_borrow_mut() { + cl.delete(range.start, &self.buf[range.start..range.end], dir); + } // Ok: while undoing, cl is borrowed. And we want to ignore changes while + // undoing. } self.buf.drain(range) }