From 8d6c6dc2341110fc05ce427ecef6e9a386d557d6 Mon Sep 17 00:00:00 2001
From: Gwenael Treguier <gwen@cas75-5-78-192-41-37.fbxo.proxad.net>
Date: Sun, 23 Aug 2015 18:22:38 +0200
Subject: [PATCH] Fix history example.

---
 examples/history.rs |  6 +++---
 src/error.rs        |  6 +++++-
 src/history.rs      |  4 ++--
 src/lib.rs          | 27 ++++++++++++++++-----------
 4 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/examples/history.rs b/examples/history.rs
index 06fdbe2f..c1ed49c4 100644
--- a/examples/history.rs
+++ b/examples/history.rs
@@ -1,13 +1,12 @@
 extern crate nix;
 extern crate rustyline;
 
-use nix::Error;
-use nix::errno::Errno;
 use rustyline::error::ReadlineError;
 use rustyline::history::History;
 
 fn main() {
     let mut history = Some(History::new());
+    history.as_mut().unwrap().load("history.txt");
     loop {
         let readline = rustyline::readline(">> ", &mut history);
         match readline {
@@ -15,7 +14,7 @@ fn main() {
                 history.as_mut().unwrap().add(&line);
                 println!("Line: {}", line);
             },
-            Err(ReadlineError::Errno(Error::Sys(Errno::EAGAIN))) => {
+            Err(ReadlineError::Interrupted) => {
                 println!("CTRL-C");
                 break
             },
@@ -29,4 +28,5 @@ fn main() {
             }
         }
     }
+    history.as_mut().unwrap().save("history.txt");
 }
diff --git a/src/error.rs b/src/error.rs
index 41e85070..71659cee 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -15,7 +15,9 @@ pub enum ReadlineError {
     /// Chars Error
     Char(io::CharsError),
     /// EOF (Ctrl-d)
-    Eof
+    Eof,
+    /// Ctrl-C
+    Interrupted
 }
 
 impl fmt::Display for ReadlineError {
@@ -25,6 +27,7 @@ impl fmt::Display for ReadlineError {
             ReadlineError::Errno(ref err) => write!(f, "Errno: {}", err.errno().desc()),
             ReadlineError::Char(ref err) => err.fmt(f),
             ReadlineError::Eof => write!(f, "EOF"),
+            ReadlineError::Interrupted => write!(f, "Interrupted"),
         }
     }
 }
@@ -36,6 +39,7 @@ impl error::Error for ReadlineError {
             ReadlineError::Errno(ref err) => err.errno().desc(),
             ReadlineError::Char(ref err) => err.description(),
             ReadlineError::Eof => "EOF",
+            ReadlineError::Interrupted => "Interrupted",
         }
     }
 }
diff --git a/src/history.rs b/src/history.rs
index cbca95eb..da7944bc 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -65,7 +65,7 @@ impl History {
     }
 
     /// Save the history in the specified file.
-    pub fn save<P: AsRef<Path>>(&self, path: &P) -> Result<()> {
+    pub fn save<P: AsRef<Path>+?Sized>(&self, path: &P) -> Result<()> {
         use std::io::{BufWriter, Write};
 
         if self.entries.len() == 0 {
@@ -81,7 +81,7 @@ impl History {
     }
 
     /// Load the history from the specified file.
-    pub fn load<P: AsRef<Path>>(&mut self, path: &P) -> Result<()> {
+    pub fn load<P: AsRef<Path>+?Sized>(&mut self, path: &P) -> Result<()> {
         use std::io::{BufRead, BufReader};
 
         let file = try!(File::open(&path));
diff --git a/src/lib.rs b/src/lib.rs
index 9e5f11b1..aacf93e2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,8 +28,7 @@ pub mod history;
 
 use std::fmt;
 use std::io;
-use std::str;
-use std::io::{Write, Read};
+use std::io::{Read, Write};
 use std::result;
 use nix::errno::Errno;
 use nix::sys::termios;
@@ -67,6 +66,14 @@ impl<'out, 'prompt> State<'out, 'prompt> {
             bytes: [0; 4],
         }
     }
+
+    fn update_buf(&mut self, buf: &str) {
+        self.buf = String::from(buf);
+        if self.buf.capacity() < MAX_LINE {
+            let cap = self.buf.capacity();
+            self.buf.reserve_exact(MAX_LINE - cap);
+        }
+    }
 }
 
 impl<'out, 'prompt> fmt::Debug for State<'out, 'prompt> {
@@ -184,7 +191,7 @@ fn write_and_flush(w: &mut Write, buf: &[u8]) -> Result<()> {
 }
 
 /// Clear the screen. Used to handle ctrl+l
-fn clear_screen(out: &mut Write) -> Result<()> {
+pub fn clear_screen(out: &mut Write) -> Result<()> {
     write_and_flush(out, b"\x1b[H\x1b[2J")
 }
 
@@ -407,15 +414,13 @@ fn edit_history_next(s: &mut State, history: &mut History, prev: bool) -> Result
             s.history_index += 1;
         }
         if s.history_index < history.len() {
-            s.buf = history.get(s.history_index).unwrap().clone();
+            let buf = history.get(s.history_index).unwrap();
+            s.update_buf(buf);
         } else {
-            s.buf = s.history_end.clone(); // TODO how to avoid cloning?
-        }
+            let buf = s.history_end.clone(); // TODO how to avoid cloning?
+            s.update_buf(&buf);
+        };
         s.pos = s.buf.len();
-        if s.buf.capacity() < MAX_LINE {
-            let cap = s.buf.capacity();
-            s.buf.reserve_exact(MAX_LINE - cap);
-        }
         refresh_line(s)
     } else {
         Ok(())
@@ -438,7 +443,7 @@ fn readline_edit(prompt: &str, history: &mut Option<History>) -> Result<String>
             KeyPress::CTRL_A => try!(edit_move_home(&mut s)), // Move to the beginning of line.
             KeyPress::CTRL_B => try!(edit_move_left(&mut s)), // Move back a character.
             KeyPress::CTRL_C => {
-                return Err(from_errno(Errno::EAGAIN))
+                return Err(error::ReadlineError::Interrupted)
             },
             KeyPress::CTRL_D => {
                 if s.buf.len() > 0 { // Delete one character at point.
-- 
GitLab