From 003ac7116550833212cf0c9bf33d98ac8edfa01d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 9 Jun 2019 08:58:34 -0400 Subject: fix multiple input events becoming available at once --- src/readline.rs | 39 +++++++++++++++++++++++++-------------- src/repl.rs | 3 ++- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/readline.rs b/src/readline.rs index ef4fcae..ab1c7fd 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -8,11 +8,16 @@ pub enum Error { pub struct Readline { reader: Option, - buffer: String, + state: ReadlineState, + _raw_screen: crossterm::RawScreen, +} + +struct ReadlineState { prompt: String, - wrote_prompt: bool, echo: bool, - _raw_screen: crossterm::RawScreen, + + buffer: String, + wrote_prompt: bool, } impl Readline { @@ -21,14 +26,18 @@ impl Readline { Readline { reader: None, - buffer: String::new(), - prompt: prompt.to_string(), - wrote_prompt: false, - echo, + state: ReadlineState { + prompt: prompt.to_string(), + echo, + buffer: String::new(), + wrote_prompt: false, + }, _raw_screen: screen, } } +} +impl ReadlineState { fn process_event( &mut self, event: crossterm::InputEvent, @@ -105,19 +114,21 @@ impl futures::future::Future for Readline { type Error = Error; fn poll(&mut self) -> futures::Poll { - if !self.wrote_prompt { - self.prompt().map_err(|e| Error::IOError(e))?; - self.wrote_prompt = true; + if !self.state.wrote_prompt { + self.state.prompt().map_err(|e| Error::IOError(e))?; + self.state.wrote_prompt = true; } let reader = self .reader .get_or_insert_with(|| KeyReader::new(futures::task::current())); - if let Some(event) = reader.poll() { - self.process_event(event) - } else { - Ok(futures::Async::NotReady) + while let Some(event) = reader.poll() { + let a = self.state.process_event(event)?; + if a.is_ready() { + return Ok(a); + } } + Ok(futures::Async::NotReady) } } diff --git a/src/repl.rs b/src/repl.rs index c6d8b07..e05624e 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -16,6 +16,7 @@ pub fn repl() { } let repl = read().and_then(|line| { + eprint!("running '{}'\r\n", line); eval(&line).fold(None, |acc, event| match event { crate::process::ProcessEvent::Output(out) => { match print(&out) { @@ -46,7 +47,7 @@ pub fn repl() { let mut stderr = stderr.lock(); write!(stderr, "error: {:?}\r\n", e).unwrap(); stderr.flush().unwrap(); - return Err(()); + return Ok((done, false)); } })) }); -- cgit v1.2.3-54-g00ecf