use crate::{
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
EditCommand, Keybindings, PromptEditMode, ReedlineEvent,
};
use crossterm::event::KeyCode;
use std::fmt::{Display, Formatter};
use strum::IntoEnumIterator;
struct ReedLineCrossTermKeyCode(crossterm::event::KeyCode);
impl ReedLineCrossTermKeyCode {
fn iterator() -> std::slice::Iter<'static, ReedLineCrossTermKeyCode> {
static KEYCODE: [ReedLineCrossTermKeyCode; 19] = [
ReedLineCrossTermKeyCode(KeyCode::Backspace),
ReedLineCrossTermKeyCode(KeyCode::Enter),
ReedLineCrossTermKeyCode(KeyCode::Left),
ReedLineCrossTermKeyCode(KeyCode::Right),
ReedLineCrossTermKeyCode(KeyCode::Up),
ReedLineCrossTermKeyCode(KeyCode::Down),
ReedLineCrossTermKeyCode(KeyCode::Home),
ReedLineCrossTermKeyCode(KeyCode::End),
ReedLineCrossTermKeyCode(KeyCode::PageUp),
ReedLineCrossTermKeyCode(KeyCode::PageDown),
ReedLineCrossTermKeyCode(KeyCode::Tab),
ReedLineCrossTermKeyCode(KeyCode::BackTab),
ReedLineCrossTermKeyCode(KeyCode::Delete),
ReedLineCrossTermKeyCode(KeyCode::Insert),
ReedLineCrossTermKeyCode(KeyCode::F(1)),
ReedLineCrossTermKeyCode(KeyCode::Char(' ')),
ReedLineCrossTermKeyCode(KeyCode::Char('a')),
ReedLineCrossTermKeyCode(KeyCode::Null),
ReedLineCrossTermKeyCode(KeyCode::Esc),
];
KEYCODE.iter()
}
}
impl Display for ReedLineCrossTermKeyCode {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self {
ReedLineCrossTermKeyCode(kc) => match kc {
KeyCode::Backspace => write!(f, "Backspace"),
KeyCode::Enter => write!(f, "Enter"),
KeyCode::Left => write!(f, "Left"),
KeyCode::Right => write!(f, "Right"),
KeyCode::Up => write!(f, "Up"),
KeyCode::Down => write!(f, "Down"),
KeyCode::Home => write!(f, "Home"),
KeyCode::End => write!(f, "End"),
KeyCode::PageUp => write!(f, "PageUp"),
KeyCode::PageDown => write!(f, "PageDown"),
KeyCode::Tab => write!(f, "Tab"),
KeyCode::BackTab => write!(f, "BackTab"),
KeyCode::Delete => write!(f, "Delete"),
KeyCode::Insert => write!(f, "Insert"),
KeyCode::F(_) => write!(f, "F<number>"),
KeyCode::Char(' ') => write!(f, "Space"),
KeyCode::Char(_) => write!(f, "Char_<letter>"),
KeyCode::Null => write!(f, "Null"),
KeyCode::Esc => write!(f, "Esc"),
KeyCode::CapsLock => write!(f, "CapsLock"),
KeyCode::ScrollLock => write!(f, "ScrollLock"),
KeyCode::NumLock => write!(f, "NumLock"),
KeyCode::PrintScreen => write!(f, "PrintScreen"),
KeyCode::Pause => write!(f, "Pause"),
KeyCode::Menu => write!(f, "Menu"),
KeyCode::KeypadBegin => write!(f, "KeypadBegin"),
KeyCode::Media(_) => write!(f, "Media<media>"),
KeyCode::Modifier(_) => write!(f, "Modifier<modifier>"),
},
}
}
}
pub fn get_reedline_keybinding_modifiers() -> Vec<String> {
vec![
"Alt".to_string(),
"Control".to_string(),
"Shift".to_string(),
"None".to_string(),
"Shift_Alt".to_string(),
"Alt_Shift".to_string(),
"Control_Shift".to_string(),
"Shift_Control".to_string(),
"Control_Alt".to_string(),
"Alt_Control".to_string(),
"Control_Alt_Shift".to_string(),
"Control_Shift_Alt".to_string(),
]
}
pub fn get_reedline_prompt_edit_modes() -> Vec<String> {
PromptEditMode::iter().map(|em| em.to_string()).collect()
}
pub fn get_reedline_keycodes() -> Vec<String> {
ReedLineCrossTermKeyCode::iterator()
.map(|kc| format!("{kc}"))
.collect()
}
pub fn get_reedline_reedline_events() -> Vec<String> {
ReedlineEvent::iter().map(|rle| rle.to_string()).collect()
}
pub fn get_reedline_edit_commands() -> Vec<String> {
EditCommand::iter().map(|edit| edit.to_string()).collect()
}
pub fn get_reedline_default_keybindings() -> Vec<(String, String, String, String)> {
let options = vec![
("emacs", default_emacs_keybindings()),
("vi_normal", default_vi_normal_keybindings()),
("vi_insert", default_vi_insert_keybindings()),
];
options
.into_iter()
.flat_map(|(mode, keybindings)| get_keybinding_strings(mode, &keybindings))
.collect()
}
fn get_keybinding_strings(
mode: &str,
keybindings: &Keybindings,
) -> Vec<(String, String, String, String)> {
let mut data: Vec<(String, String, String, String)> = keybindings
.get_keybindings()
.iter()
.map(|(combination, event)| {
(
mode.to_string(),
format!("{:?}", combination.modifier),
format!("{:?}", combination.key_code),
format!("{event:?}"),
)
})
.collect();
data.sort();
data
}