mod format;
mod parse;
pub use {crokey_proc_macros::*, format::*, parse::*};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
pub const fn as_letter(key: KeyEvent) -> Option<char> {
match key {
KeyEvent {
code: KeyCode::Char(l),
modifiers: KeyModifiers::NONE,
} => Some(l),
_ => None,
}
}
#[macro_export]
macro_rules! key {
($($tt:tt)*) => {
$crate::__private::key!(($crate) $($tt)*)
};
}
#[doc(hidden)]
pub mod __private {
pub use crokey_proc_macros::key;
pub use crossterm;
use crossterm::event::KeyModifiers;
pub const MODS: KeyModifiers = KeyModifiers::NONE;
pub const MODS_CTRL: KeyModifiers = KeyModifiers::CONTROL;
pub const MODS_ALT: KeyModifiers = KeyModifiers::ALT;
pub const MODS_SHIFT: KeyModifiers = KeyModifiers::SHIFT;
pub const MODS_CTRL_ALT: KeyModifiers = KeyModifiers::CONTROL.union(KeyModifiers::ALT);
pub const MODS_ALT_SHIFT: KeyModifiers = KeyModifiers::ALT.union(KeyModifiers::SHIFT);
pub const MODS_CTRL_SHIFT: KeyModifiers = KeyModifiers::CONTROL.union(KeyModifiers::SHIFT);
pub const MODS_CTRL_ALT_SHIFT: KeyModifiers = KeyModifiers::CONTROL
.union(KeyModifiers::ALT)
.union(KeyModifiers::SHIFT);
}
#[cfg(test)]
mod tests {
use {
crate::key,
crossterm::event::{KeyCode, KeyEvent, KeyModifiers},
};
const _: () = {
key!(x);
key!(ctrl - '{');
key!(alt - '{');
key!(shift - '{');
key!(ctrl - alt - f10);
key!(alt - shift - f10);
key!(ctrl - shift - f10);
key!(ctrl - alt - shift - enter);
};
fn no_mod(code: KeyCode) -> KeyEvent {
KeyEvent::new(code, KeyModifiers::NONE)
}
#[test]
fn key() {
assert_eq!(key!(backspace), no_mod(KeyCode::Backspace));
assert_eq!(key!(bAcKsPaCe), no_mod(KeyCode::Backspace));
assert_eq!(key!(0), no_mod(KeyCode::Char('0')));
assert_eq!(key!(9), no_mod(KeyCode::Char('9')));
assert_eq!(key!('x'), no_mod(KeyCode::Char('x')));
assert_eq!(key!('X'), no_mod(KeyCode::Char('x')));
assert_eq!(key!(']'), no_mod(KeyCode::Char(']')));
assert_eq!(key!('ඞ'), no_mod(KeyCode::Char('ඞ')));
assert_eq!(key!(f), no_mod(KeyCode::Char('f')));
assert_eq!(key!(F), no_mod(KeyCode::Char('f')));
assert_eq!(key!(ඞ), no_mod(KeyCode::Char('ඞ')));
assert_eq!(key!(f10), no_mod(KeyCode::F(10)));
assert_eq!(key!(F10), no_mod(KeyCode::F(10)));
assert_eq!(
key!(ctrl - c),
KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)
);
assert_eq!(
key!(alt - shift - c),
KeyEvent::new(KeyCode::Char('c'), KeyModifiers::ALT | KeyModifiers::SHIFT)
);
assert_eq!(key!(shift - alt - '2'), key!(ALT - SHIFT - 2));
assert_eq!(key!(space), key!(' '));
}
#[test]
fn format() {
let format = crate::KeyEventFormat::default();
assert_eq!(format.to_string(key!(insert)), "Insert");
assert_eq!(format.to_string(key!(space)), "Space");
assert_eq!(format.to_string(key!(alt-Space)), "Alt-Space");
assert_eq!(format.to_string(key!(shift-' ')), "Shift-Space");
}
#[test]
fn key_pattern() {
assert!(matches!(key!(ctrl-alt-shift-c), key!(ctrl-alt-shift-c)));
assert!(!matches!(key!(ctrl-c), key!(ctrl-alt-shift-c)));
assert!(matches!(key!(ctrl-alt-b), key!(ctrl-alt-b)));
assert!(matches!(key!(ctrl-b), key!(ctrl-b)));
assert!(matches!(key!(alt-b), key!(alt-b)));
assert!(!matches!(key!(ctrl-b), key!(alt-b)));
assert!(!matches!(key!(alt-b), key!(ctrl-b)));
assert!(!matches!(key!(alt-b), key!(ctrl-alt-b)));
assert!(!matches!(key!(ctrl-b), key!(ctrl-alt-b)));
assert!(!matches!(key!(ctrl-alt-b), key!(alt-b)));
assert!(!matches!(key!(ctrl-alt-b), key!(ctrl-b)));
}
}