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
11pub 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
122pub 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}