rush_sync_server/input/
keyboard.rs1use crate::core::constants::DOUBLE_ESC_THRESHOLD;
6use crate::core::prelude::*;
7use crossterm::event::KeyModifiers;
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum KeyAction {
11 MoveLeft,
12 MoveRight,
13 MoveToStart,
14 MoveToEnd,
15 InsertChar(char),
16 Backspace,
17 Delete,
18 Submit,
20 Cancel,
21 Quit,
22 ClearLine,
23 CopySelection,
24 PasteBuffer,
25 NoAction,
26 ScrollUp,
27 ScrollDown,
28 PageUp,
29 PageDown,
30}
31
32use lazy_static::lazy_static;
33use std::sync::Mutex;
34
35lazy_static! {
36 static ref LAST_ESC_PRESS: Mutex<Option<Instant>> = Mutex::new(None);
37}
38
39pub struct KeyboardManager {
40 double_press_threshold: Duration,
41}
42
43impl KeyboardManager {
44 pub fn new() -> Self {
45 Self {
46 double_press_threshold: Duration::from_millis(DOUBLE_ESC_THRESHOLD),
47 }
48 }
49
50 pub fn get_action(&mut self, key: &KeyEvent) -> KeyAction {
51 if key.code == KeyCode::Esc {
53 let now = Instant::now();
54 let mut last_press: std::sync::MutexGuard<Option<Instant>> =
55 LAST_ESC_PRESS.lock().unwrap();
56
57 if let Some(prev_press) = *last_press {
58 if now.duration_since(prev_press) <= self.double_press_threshold {
59 *last_press = None;
60 return KeyAction::Quit;
61 }
62 }
63
64 *last_press = Some(now);
65 return KeyAction::NoAction;
66 }
67
68 match (key.code, key.modifiers) {
70 (KeyCode::Left, KeyModifiers::NONE) => KeyAction::MoveLeft,
71 (KeyCode::Right, KeyModifiers::NONE) => KeyAction::MoveRight,
72 (KeyCode::Home, KeyModifiers::NONE) => KeyAction::MoveToStart,
73 (KeyCode::End, KeyModifiers::NONE) => KeyAction::MoveToEnd,
74 (KeyCode::Enter, KeyModifiers::NONE) => KeyAction::Submit,
75 (KeyCode::Up, KeyModifiers::SHIFT) => KeyAction::ScrollUp,
76 (KeyCode::Down, KeyModifiers::SHIFT) => KeyAction::ScrollDown,
77 (KeyCode::PageUp, KeyModifiers::NONE) => KeyAction::PageUp,
78 (KeyCode::PageDown, KeyModifiers::NONE) => KeyAction::PageDown,
79 (KeyCode::Char(c), KeyModifiers::NONE) => KeyAction::InsertChar(c),
80 (KeyCode::Backspace, KeyModifiers::NONE) => KeyAction::Backspace,
81 (KeyCode::Delete, KeyModifiers::NONE) => KeyAction::Delete,
82 _ => KeyAction::NoAction,
85 }
86 }
87}
88
89impl Default for KeyboardManager {
90 fn default() -> Self {
91 Self::new()
92 }
93}