1use crate::{
2 default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
3 EditCommand, Keybindings, PromptEditMode, ReedlineEvent,
4};
5use crossterm::event::KeyCode;
6use std::fmt::{Display, Formatter};
7use strum::IntoEnumIterator;
8
9struct ReedLineCrossTermKeyCode(crossterm::event::KeyCode);
10impl ReedLineCrossTermKeyCode {
11 fn iterator() -> std::slice::Iter<'static, ReedLineCrossTermKeyCode> {
12 static KEYCODE: [ReedLineCrossTermKeyCode; 19] = [
13 ReedLineCrossTermKeyCode(KeyCode::Backspace),
14 ReedLineCrossTermKeyCode(KeyCode::Enter),
15 ReedLineCrossTermKeyCode(KeyCode::Left),
16 ReedLineCrossTermKeyCode(KeyCode::Right),
17 ReedLineCrossTermKeyCode(KeyCode::Up),
18 ReedLineCrossTermKeyCode(KeyCode::Down),
19 ReedLineCrossTermKeyCode(KeyCode::Home),
20 ReedLineCrossTermKeyCode(KeyCode::End),
21 ReedLineCrossTermKeyCode(KeyCode::PageUp),
22 ReedLineCrossTermKeyCode(KeyCode::PageDown),
23 ReedLineCrossTermKeyCode(KeyCode::Tab),
24 ReedLineCrossTermKeyCode(KeyCode::BackTab),
25 ReedLineCrossTermKeyCode(KeyCode::Delete),
26 ReedLineCrossTermKeyCode(KeyCode::Insert),
27 ReedLineCrossTermKeyCode(KeyCode::F(1)),
28 ReedLineCrossTermKeyCode(KeyCode::Char(' ')),
29 ReedLineCrossTermKeyCode(KeyCode::Char('a')),
30 ReedLineCrossTermKeyCode(KeyCode::Null),
31 ReedLineCrossTermKeyCode(KeyCode::Esc),
32 ];
33 KEYCODE.iter()
34 }
35}
36
37impl Display for ReedLineCrossTermKeyCode {
38 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
39 match self {
40 ReedLineCrossTermKeyCode(kc) => match kc {
41 KeyCode::Backspace => write!(f, "Backspace"),
42 KeyCode::Enter => write!(f, "Enter"),
43 KeyCode::Left => write!(f, "Left"),
44 KeyCode::Right => write!(f, "Right"),
45 KeyCode::Up => write!(f, "Up"),
46 KeyCode::Down => write!(f, "Down"),
47 KeyCode::Home => write!(f, "Home"),
48 KeyCode::End => write!(f, "End"),
49 KeyCode::PageUp => write!(f, "PageUp"),
50 KeyCode::PageDown => write!(f, "PageDown"),
51 KeyCode::Tab => write!(f, "Tab"),
52 KeyCode::BackTab => write!(f, "BackTab"),
53 KeyCode::Delete => write!(f, "Delete"),
54 KeyCode::Insert => write!(f, "Insert"),
55 KeyCode::F(_) => write!(f, "F<number>"),
56 KeyCode::Char(' ') => write!(f, "Space"),
57 KeyCode::Char(_) => write!(f, "Char_<letter>"),
58 KeyCode::Null => write!(f, "Null"),
59 KeyCode::Esc => write!(f, "Esc"),
60 KeyCode::CapsLock => write!(f, "CapsLock"),
61 KeyCode::ScrollLock => write!(f, "ScrollLock"),
62 KeyCode::NumLock => write!(f, "NumLock"),
63 KeyCode::PrintScreen => write!(f, "PrintScreen"),
64 KeyCode::Pause => write!(f, "Pause"),
65 KeyCode::Menu => write!(f, "Menu"),
66 KeyCode::KeypadBegin => write!(f, "KeypadBegin"),
67 KeyCode::Media(_) => write!(f, "Media<media>"),
68 KeyCode::Modifier(_) => write!(f, "Modifier<modifier>"),
69 },
70 }
71 }
72}
73
74pub fn get_reedline_keybinding_modifiers() -> Vec<String> {
76 vec![
77 "Alt".to_string(),
78 "Control".to_string(),
79 "Shift".to_string(),
80 "None".to_string(),
81 "Shift_Alt".to_string(),
82 "Alt_Shift".to_string(),
83 "Control_Shift".to_string(),
84 "Shift_Control".to_string(),
85 "Control_Alt".to_string(),
86 "Alt_Control".to_string(),
87 "Control_Alt_Shift".to_string(),
88 "Control_Shift_Alt".to_string(),
89 ]
90}
91
92pub fn get_reedline_prompt_edit_modes() -> Vec<String> {
94 PromptEditMode::iter().map(|em| em.to_string()).collect()
95}
96
97pub fn get_reedline_keycodes() -> Vec<String> {
99 ReedLineCrossTermKeyCode::iterator()
100 .map(|kc| format!("{kc}"))
101 .collect()
102}
103
104pub fn get_reedline_reedline_events() -> Vec<String> {
106 ReedlineEvent::iter().map(|rle| rle.to_string()).collect()
107}
108
109pub fn get_reedline_edit_commands() -> Vec<String> {
111 EditCommand::iter().map(|edit| edit.to_string()).collect()
112}
113
114pub fn get_reedline_default_keybindings() -> Vec<(String, String, String, String)> {
118 let options = vec![
119 ("emacs", default_emacs_keybindings()),
120 ("vi_normal", default_vi_normal_keybindings()),
121 ("vi_insert", default_vi_insert_keybindings()),
122 ];
123
124 options
125 .into_iter()
126 .flat_map(|(mode, keybindings)| get_keybinding_strings(mode, &keybindings))
127 .collect()
128}
129
130fn get_keybinding_strings(
131 mode: &str,
132 keybindings: &Keybindings,
133) -> Vec<(String, String, String, String)> {
134 let mut data: Vec<(String, String, String, String)> = keybindings
135 .get_keybindings()
136 .iter()
137 .map(|(combination, event)| {
138 (
139 mode.to_string(),
140 format!("{:?}", combination.modifier),
141 format!("{:?}", combination.key_code),
142 format!("{event:?}"),
143 )
144 })
145 .collect();
146
147 data.sort();
148
149 data
150}