aboutsummaryrefslogtreecommitdiff
path: root/helix-view/src/keyboard.rs
diff options
context:
space:
mode:
authorMichael Davis2022-11-29 16:15:55 +0000
committerGitHub2022-11-29 16:15:55 +0000
commit607c74efde40812caa6379a05fcb28f259ea2c8e (patch)
treefc0eee7ed956c9e4512b5c2c3309f9252dd3a6c3 /helix-view/src/keyboard.rs
parent260341ed801a894141db2fd4e66c7159d06b665e (diff)
Handle disambiguated keycodes (#4887)
Media keys are sent despite `DISAMBIGUATE_ESCAPE_CODES` being unset. Previously we panicked on these. This change translates the disambiguated keys from crossterm so that they do not cause a panic.
Diffstat (limited to 'helix-view/src/keyboard.rs')
-rw-r--r--helix-view/src/keyboard.rs205
1 files changed, 194 insertions, 11 deletions
diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs
index 84cfebf1..cf673e11 100644
--- a/helix-view/src/keyboard.rs
+++ b/helix-view/src/keyboard.rs
@@ -53,6 +53,164 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers {
}
}
+/// 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 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(feature = "term")]
+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 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(feature = "term")]
+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 {
@@ -94,6 +252,24 @@ pub enum KeyCode {
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")]
@@ -119,6 +295,15 @@ impl From<KeyCode> for crossterm::event::KeyCode {
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()),
}
}
}
@@ -147,17 +332,15 @@ impl From<crossterm::event::KeyCode> for KeyCode {
CKeyCode::Char(character) => KeyCode::Char(character),
CKeyCode::Null => KeyCode::Null,
CKeyCode::Esc => KeyCode::Esc,
- CKeyCode::CapsLock
- | CKeyCode::ScrollLock
- | CKeyCode::NumLock
- | CKeyCode::PrintScreen
- | CKeyCode::Pause
- | CKeyCode::Menu
- | CKeyCode::KeypadBegin
- | CKeyCode::Media(_)
- | CKeyCode::Modifier(_) => unreachable!(
- "Shouldn't get this key without enabling DISAMBIGUATE_ESCAPE_CODES in crossterm"
- ),
+ 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()),
}
}
}