summaryrefslogtreecommitdiff
path: root/src/watch/terminal_event.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/watch/terminal_event.rs')
-rw-r--r--src/watch/terminal_event.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/watch/terminal_event.rs b/src/watch/terminal_event.rs
new file mode 100644
index 0000000..7c85b5b
--- /dev/null
+++ b/src/watch/terminal_event.rs
@@ -0,0 +1,65 @@
+use crossterm::event::{self, Event, KeyCode, KeyEventKind};
+use std::sync::mpsc::Sender;
+
+use super::WatchEvent;
+
+pub enum InputEvent {
+ Hint,
+ List,
+ Quit,
+ Unrecognized(String),
+}
+
+pub fn terminal_event_handler(tx: Sender<WatchEvent>) {
+ let mut input = String::with_capacity(8);
+
+ 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 => continue,
+ KeyEventKind::Press | KeyEventKind::Repeat => (),
+ }
+
+ match key.code {
+ KeyCode::Enter => {
+ let input_event = match input.trim() {
+ "h" | "hint" => InputEvent::Hint,
+ "l" | "list" => break InputEvent::List,
+ "q" | "quit" => break InputEvent::Quit,
+ _ => InputEvent::Unrecognized(input.clone()),
+ };
+
+ if tx.send(WatchEvent::Input(input_event)).is_err() {
+ return;
+ }
+
+ input.clear();
+ }
+ KeyCode::Char(c) => {
+ input.push(c);
+ }
+ _ => (),
+ }
+ }
+ 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));
+}