cic/
input.rs

1use crossterm::event::{self, Event, KeyModifiers, KeyCode};
2use crate::Mode;
3use crate::PromptType;
4
5#[derive(Clone, Copy, Debug)]
6pub enum Dir {
7    Up, Down, Left, Right,
8    Top, Bottom, Start, End
9}
10
11/// Actions are unique and have the same
12/// behavior no matter the current mode.
13pub enum Action {
14    MoveCursor(Dir),
15
16    EnterPrompt(PromptType),
17    Prompt(PromptType, PromptAction),
18
19    EnterMode(Mode),
20
21    Append(char),
22    Pop,
23
24    CarriageReturn,
25
26    ClearCell,
27
28    AddRowAbove,
29    AddRowBelow,
30    DeleteRow,
31
32    AddColLeft,
33    AddColRight,
34    DeleteCol,
35
36    Save,
37    Quit,
38}
39
40pub enum PromptAction {
41    Push(char),
42    Backspace,
43    Submit,
44    Exit,
45}
46
47pub fn get_actions(mode: Mode) -> Vec<Action> {
48    match mode {
49        Mode::Table => table_mode_actions(),
50        Mode::Prompt(p) => prompt_mode_actions(p),
51        Mode::Insert => insert_mode_actions(),
52        _ => Vec::new(),
53    }
54}
55
56pub fn prompt_mode_actions(p: PromptType) -> Vec<Action> {
57    use Action::*;
58    use PromptAction::*;
59    match event::read().unwrap() {
60        Event::Key(keyevent) => match keyevent.code {
61            KeyCode::Esc => vec![Prompt(p, Exit)],
62            KeyCode::Enter => vec![Prompt(p, Submit)],
63            KeyCode::Backspace => vec![Prompt(p, Backspace)],
64            KeyCode::Char(c) => vec![Prompt(p, Push(c))],
65            _ => Vec::new(),
66        }
67        _ => Vec::new(),
68    }
69}
70
71pub fn insert_mode_actions() -> Vec<Action> {
72    use Action::*;
73    match event::read().unwrap() {
74        Event::Key(keyevent) => match (keyevent.code, keyevent.modifiers.contains(KeyModifiers::SHIFT)) {
75            (KeyCode::Up, _) => vec![MoveCursor(Dir::Up)],
76            (KeyCode::Down, _) => vec![MoveCursor(Dir::Down)],
77            (KeyCode::Left, _) => vec![MoveCursor(Dir::Left)],
78            (KeyCode::Right, _) => vec![MoveCursor(Dir::Right)],
79
80            (KeyCode::Esc, _) => vec![EnterMode(Mode::Table)],
81            (KeyCode::Backspace, _) => vec![Pop],
82            (KeyCode::Tab, _) => vec![MoveCursor(Dir::Right)],
83            (KeyCode::BackTab, _) => vec![MoveCursor(Dir::Left)],
84            (KeyCode::Enter, _) => vec![CarriageReturn],
85            (KeyCode::Char(c), _) => vec![Append(c)],
86            _ => Vec::new(),
87        }
88        _ => Vec::new(),
89    }
90}
91
92pub fn table_mode_actions() -> Vec<Action> {
93    use Action::*;
94    match event::read().unwrap() {
95        Event::Key(keyevent) => match keyevent.code {
96            KeyCode::Char('k') | KeyCode::Up => vec![MoveCursor(Dir::Up)],
97            KeyCode::Char('j') | KeyCode::Down => vec![MoveCursor(Dir::Down)],
98            KeyCode::Char('h') | KeyCode::Left => vec![MoveCursor(Dir::Left)],
99            KeyCode::Char('l') | KeyCode::Right => vec![MoveCursor(Dir::Right)],
100            KeyCode::Char('g') => vec![MoveCursor(Dir::Top)],
101            KeyCode::Char('G') => vec![MoveCursor(Dir::Bottom)],
102            KeyCode::Char('0') => vec![MoveCursor(Dir::Start)],
103            KeyCode::Char('$') => vec![MoveCursor(Dir::End)],
104
105            KeyCode::Esc => vec![Quit],
106            KeyCode::Char('S') => vec![ClearCell],
107            KeyCode::Char('o') => vec![AddRowBelow],
108            KeyCode::Char('O') => vec![AddRowAbove],
109            KeyCode::Char('D') => vec![DeleteRow],
110
111            KeyCode::Char('I') => vec![EnterMode(Mode::Insert)],
112
113            KeyCode::Char('r') => vec![EnterPrompt(PromptType::EditReplace)],
114            KeyCode::Char('a') => vec![EnterPrompt(PromptType::EditAppend)],
115            KeyCode::Char(':') => vec![EnterPrompt(PromptType::Command)],
116            _ => Vec::new(),
117        }
118        _ => Vec::new(),
119    }
120}
121
122/// Returns a Command from a string typed at the command prompt
123pub fn from_prompt(s: String) -> Vec<Action> {
124    use Action::*;
125    match s.to_lowercase().as_str() {
126        "w" | "write" => vec![Save],
127        "q" | "quit" => vec![Quit],
128        "addcol" => vec![AddColRight],
129        "delcol" => vec![DeleteCol],
130        _ => Vec::new(),
131    }
132}