From 076a5711726c9ca985a821d6314f54bbbfc8ade8 Mon Sep 17 00:00:00 2001
From: gwenn <gtreguier@gmail.com>
Date: Tue, 18 Apr 2017 16:11:22 +0200
Subject: [PATCH] Fix undos

---
 src/lib.rs  | 14 +++++++++-----
 src/undo.rs | 34 +++++++++-------------------------
 2 files changed, 18 insertions(+), 30 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index d17ecda3..ddfbaa5e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -625,7 +625,7 @@ fn complete_line<R: RawReader>(rdr: &mut R,
         try!(beep());
         Ok(None)
     } else if CompletionType::Circular == config.completion_type() {
-        s.changes.borrow_mut().begin();
+        let mark = s.changes.borrow_mut().begin();
         // Save the current edited line before overwriting it
         let backup = s.line.as_str().to_owned();
         let backup_pos = s.line.pos();
@@ -656,7 +656,7 @@ fn complete_line<R: RawReader>(rdr: &mut R,
                         s.line.update(&backup, backup_pos);
                         try!(s.refresh_line());
                     }
-                    s.changes.borrow_mut().cancel();
+                    s.changes.borrow_mut().truncate(mark);
                     return Ok(None);
                 }
                 _ => {
@@ -795,8 +795,10 @@ fn reverse_incremental_search<R: RawReader>(rdr: &mut R,
     if history.is_empty() {
         return Ok(None);
     }
-    // Save the current edited line (and cursor position) before to overwrite it
-    s.snapshot();
+    let mark = s.changes.borrow_mut().begin();
+    // Save the current edited line (and cursor position) before overwriting it
+    let backup = s.line.as_str().to_owned();
+    let backup_pos = s.line.pos();
 
     let mut search_buf = String::new();
     let mut history_idx = history.len() - 1;
@@ -842,8 +844,9 @@ fn reverse_incremental_search<R: RawReader>(rdr: &mut R,
                 }
                 Cmd::Abort => {
                     // Restore current edited line (before search)
-                    s.snapshot();
+                    s.line.update(&backup, backup_pos);
                     try!(s.refresh_line());
+                    s.changes.borrow_mut().truncate(mark);
                     return Ok(None);
                 }
                 _ => break,
@@ -860,6 +863,7 @@ fn reverse_incremental_search<R: RawReader>(rdr: &mut R,
             _ => false,
         };
     }
+    s.changes.borrow_mut().end();
     Ok(Some(cmd))
 }
 
diff --git a/src/undo.rs b/src/undo.rs
index 5fe4d250..0afe419f 100644
--- a/src/undo.rs
+++ b/src/undo.rs
@@ -81,10 +81,12 @@ impl Changeset {
         }
     }
 
-    pub fn begin(&mut self) {
+    pub fn begin(&mut self) -> usize {
         debug!(target: "rustyline", "Changeset::begin");
         self.redos.clear();
+        let mark = self.undos.len();
         self.undos.push(Change::Begin);
+        mark
     }
 
     pub fn end(&mut self) {
@@ -108,7 +110,7 @@ impl Changeset {
     }
 
     pub fn insert(&mut self, idx: usize, c: char) {
-        debug!(target: "rustyline", "Changeset::insert({:?}, {:?})", idx, c);
+        debug!(target: "rustyline", "Changeset::insert({}, {:?})", idx, c);
         self.redos.clear();
         if !c.is_alphanumeric() {
             self.undos.push(Self::insert_char(idx, c));
@@ -138,7 +140,7 @@ impl Changeset {
     }
 
     pub fn insert_str<S: Into<String> + Debug>(&mut self, idx: usize, string: S) {
-        debug!(target: "rustyline", "Changeset::insert_str({:?}, {:?})", idx, string);
+        debug!(target: "rustyline", "Changeset::insert_str({}, {:?})", idx, string);
         self.redos.clear();
         self.undos
             .push(Change::Insert {
@@ -148,7 +150,7 @@ impl Changeset {
     }
 
     pub fn delete<S: AsRef<str> + Into<String> + Debug>(&mut self, indx: usize, string: S) {
-        debug!(target: "rustyline", "Changeset::delete({:?}, {:?})", indx, string);
+        debug!(target: "rustyline", "Changeset::delete({}, {:?})", indx, string);
         self.redos.clear();
 
         if !Self::single_char(string.as_ref()) {
@@ -244,27 +246,9 @@ impl Changeset {
         undone
     }
 
-    pub fn cancel(&mut self) {
-        debug!(target: "rustyline", "Changeset::cancel");
-        let mut waiting_for_begin = 1;
-        loop {
-            if let Some(change) = self.undos.pop() {
-                match change {
-                    Change::Begin => {
-                        waiting_for_begin -= 1;
-                    }
-                    Change::End => {
-                        waiting_for_begin += 1;
-                    }
-                    _ => {}
-                };
-            } else {
-                break;
-            }
-            if waiting_for_begin <= 0 {
-                break;
-            }
-        }
+    pub fn truncate(&mut self, len: usize) {
+        debug!(target: "rustyline", "Changeset::truncate({})", len);
+        self.undos.truncate(len);
     }
 
     #[cfg(test)]
-- 
GitLab