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