diff options
Diffstat (limited to 'src/watch/terminal_event.rs')
| -rw-r--r-- | src/watch/terminal_event.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/watch/terminal_event.rs b/src/watch/terminal_event.rs new file mode 100644 index 0000000..f54af17 --- /dev/null +++ b/src/watch/terminal_event.rs @@ -0,0 +1,86 @@ +use crossterm::event::{self, Event, KeyCode, KeyEventKind, KeyModifiers}; +use std::sync::mpsc::Sender; + +use super::WatchEvent; + +pub enum InputEvent { + Run, + Next, + Hint, + List, + Quit, + Unrecognized, +} + +pub fn terminal_event_handler(tx: Sender<WatchEvent>, manual_run: bool) { + // Only send `Unrecognized` on ENTER if the last input wasn't valid. + let mut last_input_valid = false; + + let last_input_event = loop { + let terminal_event = match event::read() { + Ok(v) => v, + Err(e) => { + // If `send` returns an error, then the receiver is dropped and + // a shutdown has been already initialized. + let _ = tx.send(WatchEvent::TerminalEventErr(e)); + return; + } + }; + + match terminal_event { + Event::Key(key) => { + match key.kind { + KeyEventKind::Release | KeyEventKind::Repeat => continue, + KeyEventKind::Press => (), + } + + if key.modifiers != KeyModifiers::NONE { + last_input_valid = false; + continue; + } + + let input_event = match key.code { + KeyCode::Enter => { + if last_input_valid { + continue; + } + + InputEvent::Unrecognized + } + KeyCode::Char(c) => { + let input_event = match c { + 'n' => InputEvent::Next, + 'h' => InputEvent::Hint, + 'l' => break InputEvent::List, + 'q' => break InputEvent::Quit, + 'r' if manual_run => InputEvent::Run, + _ => { + last_input_valid = false; + continue; + } + }; + + last_input_valid = true; + input_event + } + _ => { + last_input_valid = false; + continue; + } + }; + + if tx.send(WatchEvent::Input(input_event)).is_err() { + return; + } + } + Event::Resize(_, _) => { + if tx.send(WatchEvent::TerminalResize).is_err() { + return; + } + } + Event::FocusGained | Event::FocusLost | Event::Mouse(_) | Event::Paste(_) => continue, + } + }; + + let _ = tx.send(WatchEvent::Input(last_input_event)); +} |
