aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-06-09 08:58:34 -0400
committerJesse Luehrs <doy@tozt.net>2019-06-09 08:58:34 -0400
commit003ac7116550833212cf0c9bf33d98ac8edfa01d (patch)
treedc090458481df857d71036d8faf1b66436fc6151
parent5cf20a142ef667b9664dd2a2dc3bb26c7562c9a0 (diff)
downloadnbsh-old-003ac7116550833212cf0c9bf33d98ac8edfa01d.tar.gz
nbsh-old-003ac7116550833212cf0c9bf33d98ac8edfa01d.zip
fix multiple input events becoming available at once
-rw-r--r--src/readline.rs39
-rw-r--r--src/repl.rs3
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<KeyReader>,
- 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<Self::Item, Self::Error> {
- 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));
}
}))
});