Skip to main content

rgx/input/
mod.rs

1pub mod editor;
2pub mod handler;
3pub mod vim;
4
5use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
6
7// `#[non_exhaustive]` so future additive variants (e.g. new key actions) are
8// non-breaking under semver. Without it, each `Action` variant addition forces
9// a minor bump because downstream `match` expressions would no longer be
10// exhaustive. Adding this attribute is itself a one-time breaking change.
11#[non_exhaustive]
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum Action {
14    InsertChar(char),
15    InsertNewline,
16    DeleteBack,
17    DeleteForward,
18    DeleteCharAtCursor,
19    DeleteLine,
20    ChangeLine,
21    OpenLineBelow,
22    OpenLineAbove,
23    MoveToFirstNonBlank,
24    MoveToFirstLine,
25    MoveToLastLine,
26    MoveCursorLeft,
27    MoveCursorRight,
28    MoveCursorHome,
29    MoveCursorEnd,
30    MoveCursorWordLeft,
31    MoveCursorWordRight,
32    MoveCursorWordForwardEnd,
33    ScrollUp,
34    ScrollDown,
35    SwitchPanel,
36    SwitchPanelBack,
37    SwitchEngine,
38    ToggleCaseInsensitive,
39    ToggleMultiLine,
40    ToggleDotAll,
41    ToggleUnicode,
42    ToggleExtended,
43    ShowHelp,
44    Undo,
45    Redo,
46    HistoryPrev,
47    HistoryNext,
48    CopyMatch,
49    PasteClipboard,
50    ToggleWhitespace,
51    ToggleQuickref,
52    ScrollQuickrefUp,
53    ScrollQuickrefDown,
54    OutputAndQuit,
55    SaveWorkspace,
56    OpenRecipes,
57    OpenGrex,
58    Benchmark,
59    ExportRegex101,
60    GenerateCode,
61    EnterInsertMode,
62    EnterInsertModeAppend,
63    EnterInsertModeLineStart,
64    EnterInsertModeLineEnd,
65    EnterNormalMode,
66    ToggleDebugger,
67    Quit,
68    None,
69}
70
71pub fn key_to_action(key: KeyEvent) -> Action {
72    match key.code {
73        KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::Quit,
74        KeyCode::Char('q') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::Quit,
75        KeyCode::Esc => Action::Quit,
76        KeyCode::Tab => Action::SwitchPanel,
77        KeyCode::BackTab => Action::SwitchPanelBack,
78        KeyCode::Char('e') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::SwitchEngine,
79        KeyCode::Char('z') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::Undo,
80        KeyCode::Char('Z')
81            if key
82                .modifiers
83                .contains(KeyModifiers::CONTROL | KeyModifiers::SHIFT) =>
84        {
85            Action::Redo
86        }
87        KeyCode::Char('y') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::CopyMatch,
88        KeyCode::Char('w') if key.modifiers.contains(KeyModifiers::CONTROL) => {
89            Action::ToggleWhitespace
90        }
91        KeyCode::Char('o') if key.modifiers.contains(KeyModifiers::CONTROL) => {
92            Action::OutputAndQuit
93        }
94        KeyCode::Char('s') if key.modifiers.contains(KeyModifiers::CONTROL) => {
95            Action::SaveWorkspace
96        }
97        KeyCode::Char('r') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::OpenRecipes,
98        KeyCode::Char('x') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::OpenGrex,
99        KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::Benchmark,
100        KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => {
101            Action::ExportRegex101
102        }
103        KeyCode::Char('g') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::GenerateCode,
104        KeyCode::Char('d') if key.modifiers.contains(KeyModifiers::CONTROL) => {
105            Action::ToggleDebugger
106        }
107        KeyCode::Char('i') if key.modifiers.contains(KeyModifiers::ALT) => {
108            Action::ToggleCaseInsensitive
109        }
110        KeyCode::Char('m') if key.modifiers.contains(KeyModifiers::ALT) => Action::ToggleMultiLine,
111        KeyCode::Char('s') if key.modifiers.contains(KeyModifiers::ALT) => Action::ToggleDotAll,
112        KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::ALT) => Action::ToggleUnicode,
113        KeyCode::Char('x') if key.modifiers.contains(KeyModifiers::ALT) => Action::ToggleExtended,
114        KeyCode::Up if key.modifiers.contains(KeyModifiers::ALT) => Action::HistoryPrev,
115        KeyCode::Down if key.modifiers.contains(KeyModifiers::ALT) => Action::HistoryNext,
116        KeyCode::F(1) => Action::ShowHelp,
117        KeyCode::F(3) => Action::ToggleQuickref,
118        KeyCode::PageUp => Action::ScrollQuickrefUp,
119        KeyCode::PageDown => Action::ScrollQuickrefDown,
120        KeyCode::Char(c) => Action::InsertChar(c),
121        KeyCode::Enter => Action::InsertNewline,
122        KeyCode::Backspace => Action::DeleteBack,
123        KeyCode::Delete => Action::DeleteForward,
124        KeyCode::Left if key.modifiers.contains(KeyModifiers::CONTROL) => {
125            Action::MoveCursorWordLeft
126        }
127        KeyCode::Right if key.modifiers.contains(KeyModifiers::CONTROL) => {
128            Action::MoveCursorWordRight
129        }
130        KeyCode::Left => Action::MoveCursorLeft,
131        KeyCode::Right => Action::MoveCursorRight,
132        KeyCode::Up => Action::ScrollUp,
133        KeyCode::Down => Action::ScrollDown,
134        KeyCode::Home => Action::MoveCursorHome,
135        KeyCode::End => Action::MoveCursorEnd,
136        _ => Action::None,
137    }
138}