use keymap_core::{Key, KeyInput, Keymap, Modifiers};
#[derive(Clone, Debug, PartialEq)]
enum Action {
EnterCommandMode,
Write,
Quit,
WriteQuit,
}
enum Mode {
Normal,
Command(String),
}
fn plain(c: char) -> KeyInput {
KeyInput::new(Key::Char(c), Modifiers::NONE)
}
fn enter() -> KeyInput {
KeyInput::new(Key::Enter, Modifiers::NONE)
}
fn main() {
let mut map = Keymap::new();
map.bind(plain(':'), Action::EnterCommandMode);
let resolve = |name: &str| -> Option<Action> {
match name {
"w" => Some(Action::Write),
"q" => Some(Action::Quit),
"wq" => Some(Action::WriteQuit),
_ => None,
}
};
let stream = [
plain(':'),
plain('w'),
plain('q'),
enter(),
plain(':'),
plain('q'),
enter(),
plain(':'),
plain('z'),
plain('z'),
enter(),
];
let mut mode = Mode::Normal;
for key in stream {
match &mut mode {
Mode::Normal => {
if map.get(&key) == Some(&Action::EnterCommandMode) {
println!(": -> enter command mode");
mode = Mode::Command(String::new());
} else {
}
}
Mode::Command(buf) => match key.key() {
Key::Char(c) => {
buf.push(c);
println!(" :{buf}");
}
Key::Enter => {
let name = std::mem::take(buf);
match resolve(&name) {
Some(action) => println!(" :{name} -> fire {action:?}"),
None => println!(" :{name} -> unknown command, no-op"),
}
mode = Mode::Normal;
}
Key::Esc => {
println!(" esc -> abandon command line");
mode = Mode::Normal;
}
_ => {}
},
}
}
}