Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-view/src/keyboard.rs')
| -rw-r--r-- | helix-view/src/keyboard.rs | 717 |
1 files changed, 152 insertions, 565 deletions
diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs index 53d85889..fd1fe06f 100644 --- a/helix-view/src/keyboard.rs +++ b/helix-view/src/keyboard.rs @@ -1,565 +1,152 @@ -use bitflags::bitflags; - -bitflags! { - /// Represents key modifiers (shift, control, alt). - #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] - pub struct KeyModifiers: u8 { - const SHIFT = 0b0000_0001; - const CONTROL = 0b0000_0010; - const ALT = 0b0000_0100; - const SUPER = 0b0000_1000; - const NONE = 0b0000_0000; - } -} - -#[cfg(feature = "term")] -impl From<KeyModifiers> for termina::event::Modifiers { - fn from(key_modifiers: KeyModifiers) -> Self { - use termina::event::Modifiers as CKeyModifiers; - - let mut result = CKeyModifiers::NONE; - - if key_modifiers.contains(KeyModifiers::SHIFT) { - result.insert(CKeyModifiers::SHIFT); - } - if key_modifiers.contains(KeyModifiers::CONTROL) { - result.insert(CKeyModifiers::CONTROL); - } - if key_modifiers.contains(KeyModifiers::ALT) { - result.insert(CKeyModifiers::ALT); - } - if key_modifiers.contains(KeyModifiers::SUPER) { - result.insert(CKeyModifiers::SUPER); - } - - result - } -} - -#[cfg(feature = "term")] -impl From<termina::event::Modifiers> for KeyModifiers { - fn from(val: termina::event::Modifiers) -> Self { - use termina::event::Modifiers as CKeyModifiers; - - let mut result = KeyModifiers::NONE; - - if val.contains(CKeyModifiers::SHIFT) { - result.insert(KeyModifiers::SHIFT); - } - if val.contains(CKeyModifiers::CONTROL) { - result.insert(KeyModifiers::CONTROL); - } - if val.contains(CKeyModifiers::ALT) { - result.insert(KeyModifiers::ALT); - } - if val.contains(CKeyModifiers::SUPER) { - result.insert(KeyModifiers::SUPER); - } - - result - } -} - -#[cfg(all(feature = "term", windows))] -impl From<KeyModifiers> for crossterm::event::KeyModifiers { - fn from(key_modifiers: KeyModifiers) -> Self { - use crossterm::event::KeyModifiers as CKeyModifiers; - - let mut result = CKeyModifiers::NONE; - - if key_modifiers.contains(KeyModifiers::SHIFT) { - result.insert(CKeyModifiers::SHIFT); - } - if key_modifiers.contains(KeyModifiers::CONTROL) { - result.insert(CKeyModifiers::CONTROL); - } - if key_modifiers.contains(KeyModifiers::ALT) { - result.insert(CKeyModifiers::ALT); - } - if key_modifiers.contains(KeyModifiers::SUPER) { - result.insert(CKeyModifiers::SUPER); - } - - result - } -} - -#[cfg(all(feature = "term", windows))] -impl From<crossterm::event::KeyModifiers> for KeyModifiers { - fn from(val: crossterm::event::KeyModifiers) -> Self { - use crossterm::event::KeyModifiers as CKeyModifiers; - - let mut result = KeyModifiers::NONE; - - if val.contains(CKeyModifiers::SHIFT) { - result.insert(KeyModifiers::SHIFT); - } - if val.contains(CKeyModifiers::CONTROL) { - result.insert(KeyModifiers::CONTROL); - } - if val.contains(CKeyModifiers::ALT) { - result.insert(KeyModifiers::ALT); - } - if val.contains(CKeyModifiers::SUPER) { - result.insert(KeyModifiers::SUPER); - } - - result - } -} -/// Represents a media key (as part of [`KeyCode::Media`]). -#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] -pub enum MediaKeyCode { - /// Play media key. - Play, - /// Pause media key. - Pause, - /// Play/Pause media key. - PlayPause, - /// Reverse media key. - Reverse, - /// Stop media key. - Stop, - /// Fast-forward media key. - FastForward, - /// Rewind media key. - Rewind, - /// Next-track media key. - TrackNext, - /// Previous-track media key. - TrackPrevious, - /// Record media key. - Record, - /// Lower-volume media key. - LowerVolume, - /// Raise-volume media key. - RaiseVolume, - /// Mute media key. - MuteVolume, -} - -#[cfg(feature = "term")] -impl From<MediaKeyCode> for termina::event::MediaKeyCode { - fn from(media_key_code: MediaKeyCode) -> Self { - use termina::event::MediaKeyCode as CMediaKeyCode; - - match media_key_code { - MediaKeyCode::Play => CMediaKeyCode::Play, - MediaKeyCode::Pause => CMediaKeyCode::Pause, - MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause, - MediaKeyCode::Reverse => CMediaKeyCode::Reverse, - MediaKeyCode::Stop => CMediaKeyCode::Stop, - MediaKeyCode::FastForward => CMediaKeyCode::FastForward, - MediaKeyCode::Rewind => CMediaKeyCode::Rewind, - MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext, - MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious, - MediaKeyCode::Record => CMediaKeyCode::Record, - MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume, - MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume, - MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume, - } - } -} - -#[cfg(feature = "term")] -impl From<termina::event::MediaKeyCode> for MediaKeyCode { - fn from(val: termina::event::MediaKeyCode) -> Self { - use termina::event::MediaKeyCode as CMediaKeyCode; - - match val { - CMediaKeyCode::Play => MediaKeyCode::Play, - CMediaKeyCode::Pause => MediaKeyCode::Pause, - CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause, - CMediaKeyCode::Reverse => MediaKeyCode::Reverse, - CMediaKeyCode::Stop => MediaKeyCode::Stop, - CMediaKeyCode::FastForward => MediaKeyCode::FastForward, - CMediaKeyCode::Rewind => MediaKeyCode::Rewind, - CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext, - CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious, - CMediaKeyCode::Record => MediaKeyCode::Record, - CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume, - CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume, - CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume, - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<MediaKeyCode> for crossterm::event::MediaKeyCode { - fn from(media_key_code: MediaKeyCode) -> Self { - use crossterm::event::MediaKeyCode as CMediaKeyCode; - - match media_key_code { - MediaKeyCode::Play => CMediaKeyCode::Play, - MediaKeyCode::Pause => CMediaKeyCode::Pause, - MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause, - MediaKeyCode::Reverse => CMediaKeyCode::Reverse, - MediaKeyCode::Stop => CMediaKeyCode::Stop, - MediaKeyCode::FastForward => CMediaKeyCode::FastForward, - MediaKeyCode::Rewind => CMediaKeyCode::Rewind, - MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext, - MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious, - MediaKeyCode::Record => CMediaKeyCode::Record, - MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume, - MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume, - MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume, - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<crossterm::event::MediaKeyCode> for MediaKeyCode { - fn from(val: crossterm::event::MediaKeyCode) -> Self { - use crossterm::event::MediaKeyCode as CMediaKeyCode; - - match val { - CMediaKeyCode::Play => MediaKeyCode::Play, - CMediaKeyCode::Pause => MediaKeyCode::Pause, - CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause, - CMediaKeyCode::Reverse => MediaKeyCode::Reverse, - CMediaKeyCode::Stop => MediaKeyCode::Stop, - CMediaKeyCode::FastForward => MediaKeyCode::FastForward, - CMediaKeyCode::Rewind => MediaKeyCode::Rewind, - CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext, - CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious, - CMediaKeyCode::Record => MediaKeyCode::Record, - CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume, - CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume, - CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume, - } - } -} -/// Represents a media key (as part of [`KeyCode::Modifier`]). -#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] -pub enum ModifierKeyCode { - /// Left Shift key. - LeftShift, - /// Left Control key. - LeftControl, - /// Left Alt key. - LeftAlt, - /// Left Super key. - LeftSuper, - /// Left Hyper key. - LeftHyper, - /// Left Meta key. - LeftMeta, - /// Right Shift key. - RightShift, - /// Right Control key. - RightControl, - /// Right Alt key. - RightAlt, - /// Right Super key. - RightSuper, - /// Right Hyper key. - RightHyper, - /// Right Meta key. - RightMeta, - /// Iso Level3 Shift key. - IsoLevel3Shift, - /// Iso Level5 Shift key. - IsoLevel5Shift, -} - -#[cfg(feature = "term")] -impl From<ModifierKeyCode> for termina::event::ModifierKeyCode { - fn from(modifier_key_code: ModifierKeyCode) -> Self { - use termina::event::ModifierKeyCode as CModifierKeyCode; - - match modifier_key_code { - ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift, - ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl, - ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt, - ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper, - ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper, - ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta, - ModifierKeyCode::RightShift => CModifierKeyCode::RightShift, - ModifierKeyCode::RightControl => CModifierKeyCode::RightControl, - ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt, - ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper, - ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper, - ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta, - ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift, - ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift, - } - } -} - -#[cfg(feature = "term")] -impl From<termina::event::ModifierKeyCode> for ModifierKeyCode { - fn from(val: termina::event::ModifierKeyCode) -> Self { - use termina::event::ModifierKeyCode as CModifierKeyCode; - - match val { - CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift, - CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl, - CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt, - CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper, - CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper, - CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta, - CModifierKeyCode::RightShift => ModifierKeyCode::RightShift, - CModifierKeyCode::RightControl => ModifierKeyCode::RightControl, - CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt, - CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper, - CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper, - CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta, - CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift, - CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift, - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<ModifierKeyCode> for crossterm::event::ModifierKeyCode { - fn from(modifier_key_code: ModifierKeyCode) -> Self { - use crossterm::event::ModifierKeyCode as CModifierKeyCode; - - match modifier_key_code { - ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift, - ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl, - ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt, - ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper, - ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper, - ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta, - ModifierKeyCode::RightShift => CModifierKeyCode::RightShift, - ModifierKeyCode::RightControl => CModifierKeyCode::RightControl, - ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt, - ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper, - ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper, - ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta, - ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift, - ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift, - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<crossterm::event::ModifierKeyCode> for ModifierKeyCode { - fn from(val: crossterm::event::ModifierKeyCode) -> Self { - use crossterm::event::ModifierKeyCode as CModifierKeyCode; - - match val { - CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift, - CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl, - CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt, - CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper, - CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper, - CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta, - CModifierKeyCode::RightShift => ModifierKeyCode::RightShift, - CModifierKeyCode::RightControl => ModifierKeyCode::RightControl, - CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt, - CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper, - CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper, - CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta, - CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift, - CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift, - } - } -} -/// Represents a key. -#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] -pub enum KeyCode { - /// Backspace key. - Backspace, - /// Enter key. - Enter, - /// Left arrow key. - Left, - /// Right arrow key. - Right, - /// Up arrow key. - Up, - /// Down arrow key. - Down, - /// Home key. - Home, - /// End key. - End, - /// Page up key. - PageUp, - /// Page down key. - PageDown, - /// Tab key. - Tab, - /// Delete key. - Delete, - /// Insert key. - Insert, - /// F key. - /// - /// `KeyCode::F(1)` represents F1 key, etc. - F(u8), - /// A character. - /// - /// `KeyCode::Char('c')` represents `c` character, etc. - Char(char), - /// Null. - Null, - /// Escape key. - Esc, - /// CapsLock key. - CapsLock, - /// ScrollLock key. - ScrollLock, - /// NumLock key. - NumLock, - /// PrintScreen key. - PrintScreen, - /// Pause key. - Pause, - /// Menu key. - Menu, - /// KeypadBegin key. - KeypadBegin, - /// A media key. - Media(MediaKeyCode), - /// A modifier key. - Modifier(ModifierKeyCode), -} - -#[cfg(feature = "term")] -impl From<KeyCode> for termina::event::KeyCode { - fn from(key_code: KeyCode) -> Self { - use termina::event::KeyCode as CKeyCode; - - match key_code { - KeyCode::Backspace => CKeyCode::Backspace, - KeyCode::Enter => CKeyCode::Enter, - KeyCode::Left => CKeyCode::Left, - KeyCode::Right => CKeyCode::Right, - KeyCode::Up => CKeyCode::Up, - KeyCode::Down => CKeyCode::Down, - KeyCode::Home => CKeyCode::Home, - KeyCode::End => CKeyCode::End, - KeyCode::PageUp => CKeyCode::PageUp, - KeyCode::PageDown => CKeyCode::PageDown, - KeyCode::Tab => CKeyCode::Tab, - KeyCode::Delete => CKeyCode::Delete, - KeyCode::Insert => CKeyCode::Insert, - KeyCode::F(f_number) => CKeyCode::Function(f_number), - KeyCode::Char(character) => CKeyCode::Char(character), - KeyCode::Null => CKeyCode::Null, - KeyCode::Esc => CKeyCode::Escape, - KeyCode::CapsLock => CKeyCode::CapsLock, - KeyCode::ScrollLock => CKeyCode::ScrollLock, - KeyCode::NumLock => CKeyCode::NumLock, - KeyCode::PrintScreen => CKeyCode::PrintScreen, - KeyCode::Pause => CKeyCode::Pause, - KeyCode::Menu => CKeyCode::Menu, - KeyCode::KeypadBegin => CKeyCode::KeypadBegin, - KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()), - KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()), - } - } -} - -#[cfg(feature = "term")] -impl From<termina::event::KeyCode> for KeyCode { - fn from(val: termina::event::KeyCode) -> Self { - use termina::event::KeyCode as CKeyCode; - - match val { - CKeyCode::Backspace => KeyCode::Backspace, - CKeyCode::Enter => KeyCode::Enter, - CKeyCode::Left => KeyCode::Left, - CKeyCode::Right => KeyCode::Right, - CKeyCode::Up => KeyCode::Up, - CKeyCode::Down => KeyCode::Down, - CKeyCode::Home => KeyCode::Home, - CKeyCode::End => KeyCode::End, - CKeyCode::PageUp => KeyCode::PageUp, - CKeyCode::PageDown => KeyCode::PageDown, - CKeyCode::Tab => KeyCode::Tab, - CKeyCode::BackTab => unreachable!("BackTab should have been handled on KeyEvent level"), - CKeyCode::Delete => KeyCode::Delete, - CKeyCode::Insert => KeyCode::Insert, - CKeyCode::Function(f_number) => KeyCode::F(f_number), - CKeyCode::Char(character) => KeyCode::Char(character), - CKeyCode::Null => KeyCode::Null, - CKeyCode::Escape => KeyCode::Esc, - CKeyCode::CapsLock => KeyCode::CapsLock, - CKeyCode::ScrollLock => KeyCode::ScrollLock, - CKeyCode::NumLock => KeyCode::NumLock, - CKeyCode::PrintScreen => KeyCode::PrintScreen, - CKeyCode::Pause => KeyCode::Pause, - CKeyCode::Menu => KeyCode::Menu, - CKeyCode::KeypadBegin => KeyCode::KeypadBegin, - CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()), - CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()), - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<KeyCode> for crossterm::event::KeyCode { - fn from(key_code: KeyCode) -> Self { - use crossterm::event::KeyCode as CKeyCode; - - match key_code { - KeyCode::Backspace => CKeyCode::Backspace, - KeyCode::Enter => CKeyCode::Enter, - KeyCode::Left => CKeyCode::Left, - KeyCode::Right => CKeyCode::Right, - KeyCode::Up => CKeyCode::Up, - KeyCode::Down => CKeyCode::Down, - KeyCode::Home => CKeyCode::Home, - KeyCode::End => CKeyCode::End, - KeyCode::PageUp => CKeyCode::PageUp, - KeyCode::PageDown => CKeyCode::PageDown, - KeyCode::Tab => CKeyCode::Tab, - KeyCode::Delete => CKeyCode::Delete, - KeyCode::Insert => CKeyCode::Insert, - KeyCode::F(f_number) => CKeyCode::F(f_number), - KeyCode::Char(character) => CKeyCode::Char(character), - KeyCode::Null => CKeyCode::Null, - KeyCode::Esc => CKeyCode::Esc, - KeyCode::CapsLock => CKeyCode::CapsLock, - KeyCode::ScrollLock => CKeyCode::ScrollLock, - KeyCode::NumLock => CKeyCode::NumLock, - KeyCode::PrintScreen => CKeyCode::PrintScreen, - KeyCode::Pause => CKeyCode::Pause, - KeyCode::Menu => CKeyCode::Menu, - KeyCode::KeypadBegin => CKeyCode::KeypadBegin, - KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()), - KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()), - } - } -} - -#[cfg(all(feature = "term", windows))] -impl From<crossterm::event::KeyCode> for KeyCode { - fn from(val: crossterm::event::KeyCode) -> Self { - use crossterm::event::KeyCode as CKeyCode; - - match val { - CKeyCode::Backspace => KeyCode::Backspace, - CKeyCode::Enter => KeyCode::Enter, - CKeyCode::Left => KeyCode::Left, - CKeyCode::Right => KeyCode::Right, - CKeyCode::Up => KeyCode::Up, - CKeyCode::Down => KeyCode::Down, - CKeyCode::Home => KeyCode::Home, - CKeyCode::End => KeyCode::End, - CKeyCode::PageUp => KeyCode::PageUp, - CKeyCode::PageDown => KeyCode::PageDown, - CKeyCode::Tab => KeyCode::Tab, - CKeyCode::BackTab => unreachable!("BackTab should have been handled on KeyEvent level"), - CKeyCode::Delete => KeyCode::Delete, - CKeyCode::Insert => KeyCode::Insert, - CKeyCode::F(f_number) => KeyCode::F(f_number), - CKeyCode::Char(character) => KeyCode::Char(character), - CKeyCode::Null => KeyCode::Null, - CKeyCode::Esc => KeyCode::Esc, - CKeyCode::CapsLock => KeyCode::CapsLock, - CKeyCode::ScrollLock => KeyCode::ScrollLock, - CKeyCode::NumLock => KeyCode::NumLock, - CKeyCode::PrintScreen => KeyCode::PrintScreen, - CKeyCode::Pause => KeyCode::Pause, - CKeyCode::Menu => KeyCode::Menu, - CKeyCode::KeypadBegin => KeyCode::KeypadBegin, - CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()), - CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()), - } - } -} +use bitflags::bitflags;
+
+bitflags! {
+ /// Represents key modifiers (shift, control, alt).
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+ pub struct KeyModifiers: u8 {
+ const SHIFT = 0b0000_0001;
+ const CONTROL = 0b0000_0010;
+ const ALT = 0b0000_0100;
+ const NONE = 0b0000_0000;
+ }
+}
+
+#[cfg(feature = "term")]
+impl From<KeyModifiers> for crossterm::event::KeyModifiers {
+ fn from(key_modifiers: KeyModifiers) -> Self {
+ use crossterm::event::KeyModifiers as CKeyModifiers;
+
+ let mut result = CKeyModifiers::NONE;
+
+ if key_modifiers.contains(KeyModifiers::SHIFT) {
+ result.insert(CKeyModifiers::SHIFT);
+ }
+ if key_modifiers.contains(KeyModifiers::CONTROL) {
+ result.insert(CKeyModifiers::CONTROL);
+ }
+ if key_modifiers.contains(KeyModifiers::ALT) {
+ result.insert(CKeyModifiers::ALT);
+ }
+
+ result
+ }
+}
+
+#[cfg(feature = "term")]
+impl From<crossterm::event::KeyModifiers> for KeyModifiers {
+ fn from(val: crossterm::event::KeyModifiers) -> Self {
+ use crossterm::event::KeyModifiers as CKeyModifiers;
+
+ let mut result = KeyModifiers::NONE;
+
+ if val.contains(CKeyModifiers::SHIFT) {
+ result.insert(KeyModifiers::SHIFT);
+ }
+ if val.contains(CKeyModifiers::CONTROL) {
+ result.insert(KeyModifiers::CONTROL);
+ }
+ if val.contains(CKeyModifiers::ALT) {
+ result.insert(KeyModifiers::ALT);
+ }
+
+ result
+ }
+}
+
+/// Represents a key.
+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
+pub enum KeyCode {
+ /// Backspace key.
+ Backspace,
+ /// Enter key.
+ Enter,
+ /// Left arrow key.
+ Left,
+ /// Right arrow key.
+ Right,
+ /// Up arrow key.
+ Up,
+ /// Down arrow key.
+ Down,
+ /// Home key.
+ Home,
+ /// End key.
+ End,
+ /// Page up key.
+ PageUp,
+ /// Page down key.
+ PageDown,
+ /// Tab key.
+ Tab,
+ /// Delete key.
+ Delete,
+ /// Insert key.
+ Insert,
+ /// F key.
+ ///
+ /// `KeyCode::F(1)` represents F1 key, etc.
+ F(u8),
+ /// A character.
+ ///
+ /// `KeyCode::Char('c')` represents `c` character, etc.
+ Char(char),
+ /// Null.
+ Null,
+ /// Escape key.
+ Esc,
+}
+
+#[cfg(feature = "term")]
+impl From<KeyCode> for crossterm::event::KeyCode {
+ fn from(key_code: KeyCode) -> Self {
+ use crossterm::event::KeyCode as CKeyCode;
+
+ match key_code {
+ KeyCode::Backspace => CKeyCode::Backspace,
+ KeyCode::Enter => CKeyCode::Enter,
+ KeyCode::Left => CKeyCode::Left,
+ KeyCode::Right => CKeyCode::Right,
+ KeyCode::Up => CKeyCode::Up,
+ KeyCode::Down => CKeyCode::Down,
+ KeyCode::Home => CKeyCode::Home,
+ KeyCode::End => CKeyCode::End,
+ KeyCode::PageUp => CKeyCode::PageUp,
+ KeyCode::PageDown => CKeyCode::PageDown,
+ KeyCode::Tab => CKeyCode::Tab,
+ KeyCode::Delete => CKeyCode::Delete,
+ KeyCode::Insert => CKeyCode::Insert,
+ KeyCode::F(f_number) => CKeyCode::F(f_number),
+ KeyCode::Char(character) => CKeyCode::Char(character),
+ KeyCode::Null => CKeyCode::Null,
+ KeyCode::Esc => CKeyCode::Esc,
+ }
+ }
+}
+
+#[cfg(feature = "term")]
+impl From<crossterm::event::KeyCode> for KeyCode {
+ fn from(val: crossterm::event::KeyCode) -> Self {
+ use crossterm::event::KeyCode as CKeyCode;
+
+ match val {
+ CKeyCode::Backspace => KeyCode::Backspace,
+ CKeyCode::Enter => KeyCode::Enter,
+ CKeyCode::Left => KeyCode::Left,
+ CKeyCode::Right => KeyCode::Right,
+ CKeyCode::Up => KeyCode::Up,
+ CKeyCode::Down => KeyCode::Down,
+ CKeyCode::Home => KeyCode::Home,
+ CKeyCode::End => KeyCode::End,
+ CKeyCode::PageUp => KeyCode::PageUp,
+ CKeyCode::PageDown => KeyCode::PageDown,
+ CKeyCode::Tab => KeyCode::Tab,
+ CKeyCode::BackTab => unreachable!("BackTab should have been handled on KeyEvent level"),
+ CKeyCode::Delete => KeyCode::Delete,
+ CKeyCode::Insert => KeyCode::Insert,
+ CKeyCode::F(f_number) => KeyCode::F(f_number),
+ CKeyCode::Char(character) => KeyCode::Char(character),
+ CKeyCode::Null => KeyCode::Null,
+ CKeyCode::Esc => KeyCode::Esc,
+ }
+ }
+}
|