on master help sign in
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.

commit607c74efde40812caa6379a05fcb28f259ea2c8e authorMichael Davis <mcarsondavis@gmail.com> dateTue 29 Nov 2022, 10:15 (4 years ago) parent260341e
2 files changed+335−12
helix-view/src/input.rs+141−1 helix-view/src/keyboard.rs+194−11
helix-view/src/input.rs+141−1
@@ -4,7 +4,7 @@ use helix_core::unicode::{segmentation::UnicodeSegmentation, width::UnicodeWidth
44use serde::de::{self, Deserialize, Deserializer};
55use std::fmt;
66
7−pub use crate::keyboard::{KeyCode, KeyModifiers};
7+pub use crate::keyboard::{KeyCode, KeyModifiers, MediaKeyCode, ModifierKeyCode};
88
99#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]
1010pub enum Event {
@@ -119,6 +119,40 @@ pub(crate) mod keys {
119119 pub(crate) const MINUS: &str = "minus";
120120 pub(crate) const LESS_THAN: &str = "lt";
121121 pub(crate) const GREATER_THAN: &str = "gt";
122+ pub(crate) const CAPS_LOCK: &str = "capslock";
123+ pub(crate) const SCROLL_LOCK: &str = "scrolllock";
124+ pub(crate) const NUM_LOCK: &str = "numlock";
125+ pub(crate) const PRINT_SCREEN: &str = "printscreen";
126+ pub(crate) const PAUSE: &str = "pause";
127+ pub(crate) const MENU: &str = "menu";
128+ pub(crate) const KEYPAD_BEGIN: &str = "keypadbegin";
129+ pub(crate) const PLAY: &str = "play";
130+ pub(crate) const PAUSE_MEDIA: &str = "pausemedia";
131+ pub(crate) const PLAY_PAUSE: &str = "playpause";
132+ pub(crate) const REVERSE: &str = "reverse";
133+ pub(crate) const STOP: &str = "stop";
134+ pub(crate) const FAST_FORWARD: &str = "fastforward";
135+ pub(crate) const REWIND: &str = "rewind";
136+ pub(crate) const TRACK_NEXT: &str = "tracknext";
137+ pub(crate) const TRACK_PREVIOUS: &str = "trackprevious";
138+ pub(crate) const RECORD: &str = "record";
139+ pub(crate) const LOWER_VOLUME: &str = "lowervolume";
140+ pub(crate) const RAISE_VOLUME: &str = "raisevolume";
141+ pub(crate) const MUTE_VOLUME: &str = "mutevolume";
142+ pub(crate) const LEFT_SHIFT: &str = "leftshift";
143+ pub(crate) const LEFT_CONTROL: &str = "leftcontrol";
144+ pub(crate) const LEFT_ALT: &str = "leftalt";
145+ pub(crate) const LEFT_SUPER: &str = "leftsuper";
146+ pub(crate) const LEFT_HYPER: &str = "lefthyper";
147+ pub(crate) const LEFT_META: &str = "leftmeta";
148+ pub(crate) const RIGHT_SHIFT: &str = "rightshift";
149+ pub(crate) const RIGHT_CONTROL: &str = "rightcontrol";
150+ pub(crate) const RIGHT_ALT: &str = "rightalt";
151+ pub(crate) const RIGHT_SUPER: &str = "rightsuper";
152+ pub(crate) const RIGHT_HYPER: &str = "righthyper";
153+ pub(crate) const RIGHT_META: &str = "rightmeta";
154+ pub(crate) const ISO_LEVEL_3_SHIFT: &str = "isolevel3shift";
155+ pub(crate) const ISO_LEVEL_5_SHIFT: &str = "isolevel5shift";
122156}
123157
124158impl fmt::Display for KeyEvent {
@@ -163,6 +197,44 @@ impl fmt::Display for KeyEvent {
163197 KeyCode::Char('>') => f.write_str(keys::GREATER_THAN)?,
164198 KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?,
165199 KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?,
200+ KeyCode::CapsLock => f.write_str(keys::CAPS_LOCK)?,
201+ KeyCode::ScrollLock => f.write_str(keys::SCROLL_LOCK)?,
202+ KeyCode::NumLock => f.write_str(keys::NUM_LOCK)?,
203+ KeyCode::PrintScreen => f.write_str(keys::PRINT_SCREEN)?,
204+ KeyCode::Pause => f.write_str(keys::PAUSE)?,
205+ KeyCode::Menu => f.write_str(keys::MENU)?,
206+ KeyCode::KeypadBegin => f.write_str(keys::KEYPAD_BEGIN)?,
207+ KeyCode::Media(MediaKeyCode::Play) => f.write_str(keys::PLAY)?,
208+ KeyCode::Media(MediaKeyCode::Pause) => f.write_str(keys::PAUSE_MEDIA)?,
209+ KeyCode::Media(MediaKeyCode::PlayPause) => f.write_str(keys::PLAY_PAUSE)?,
210+ KeyCode::Media(MediaKeyCode::Stop) => f.write_str(keys::STOP)?,
211+ KeyCode::Media(MediaKeyCode::Reverse) => f.write_str(keys::REVERSE)?,
212+ KeyCode::Media(MediaKeyCode::FastForward) => f.write_str(keys::FAST_FORWARD)?,
213+ KeyCode::Media(MediaKeyCode::Rewind) => f.write_str(keys::REWIND)?,
214+ KeyCode::Media(MediaKeyCode::TrackNext) => f.write_str(keys::TRACK_NEXT)?,
215+ KeyCode::Media(MediaKeyCode::TrackPrevious) => f.write_str(keys::TRACK_PREVIOUS)?,
216+ KeyCode::Media(MediaKeyCode::Record) => f.write_str(keys::RECORD)?,
217+ KeyCode::Media(MediaKeyCode::LowerVolume) => f.write_str(keys::LOWER_VOLUME)?,
218+ KeyCode::Media(MediaKeyCode::RaiseVolume) => f.write_str(keys::RAISE_VOLUME)?,
219+ KeyCode::Media(MediaKeyCode::MuteVolume) => f.write_str(keys::MUTE_VOLUME)?,
220+ KeyCode::Modifier(ModifierKeyCode::LeftShift) => f.write_str(keys::LEFT_SHIFT)?,
221+ KeyCode::Modifier(ModifierKeyCode::LeftControl) => f.write_str(keys::LEFT_CONTROL)?,
222+ KeyCode::Modifier(ModifierKeyCode::LeftAlt) => f.write_str(keys::LEFT_ALT)?,
223+ KeyCode::Modifier(ModifierKeyCode::LeftSuper) => f.write_str(keys::LEFT_SUPER)?,
224+ KeyCode::Modifier(ModifierKeyCode::LeftHyper) => f.write_str(keys::LEFT_HYPER)?,
225+ KeyCode::Modifier(ModifierKeyCode::LeftMeta) => f.write_str(keys::LEFT_META)?,
226+ KeyCode::Modifier(ModifierKeyCode::RightShift) => f.write_str(keys::RIGHT_SHIFT)?,
227+ KeyCode::Modifier(ModifierKeyCode::RightControl) => f.write_str(keys::RIGHT_CONTROL)?,
228+ KeyCode::Modifier(ModifierKeyCode::RightAlt) => f.write_str(keys::RIGHT_ALT)?,
229+ KeyCode::Modifier(ModifierKeyCode::RightSuper) => f.write_str(keys::RIGHT_SUPER)?,
230+ KeyCode::Modifier(ModifierKeyCode::RightHyper) => f.write_str(keys::RIGHT_HYPER)?,
231+ KeyCode::Modifier(ModifierKeyCode::RightMeta) => f.write_str(keys::RIGHT_META)?,
232+ KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => {
233+ f.write_str(keys::ISO_LEVEL_3_SHIFT)?
234+ }
235+ KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => {
236+ f.write_str(keys::ISO_LEVEL_5_SHIFT)?
237+ }
166238 };
167239 Ok(())
168240 }
@@ -192,6 +264,40 @@ impl UnicodeWidthStr for KeyEvent {
192264 KeyCode::F(1..=9) => 2,
193265 KeyCode::F(_) => 3,
194266 KeyCode::Char(c) => c.width().unwrap_or(0),
267+ KeyCode::CapsLock => keys::CAPS_LOCK.len(),
268+ KeyCode::ScrollLock => keys::SCROLL_LOCK.len(),
269+ KeyCode::NumLock => keys::NUM_LOCK.len(),
270+ KeyCode::PrintScreen => keys::PRINT_SCREEN.len(),
271+ KeyCode::Pause => keys::PAUSE.len(),
272+ KeyCode::Menu => keys::MENU.len(),
273+ KeyCode::KeypadBegin => keys::KEYPAD_BEGIN.len(),
274+ KeyCode::Media(MediaKeyCode::Play) => keys::PLAY.len(),
275+ KeyCode::Media(MediaKeyCode::Pause) => keys::PAUSE_MEDIA.len(),
276+ KeyCode::Media(MediaKeyCode::PlayPause) => keys::PLAY_PAUSE.len(),
277+ KeyCode::Media(MediaKeyCode::Stop) => keys::STOP.len(),
278+ KeyCode::Media(MediaKeyCode::Reverse) => keys::REVERSE.len(),
279+ KeyCode::Media(MediaKeyCode::FastForward) => keys::FAST_FORWARD.len(),
280+ KeyCode::Media(MediaKeyCode::Rewind) => keys::REWIND.len(),
281+ KeyCode::Media(MediaKeyCode::TrackNext) => keys::TRACK_NEXT.len(),
282+ KeyCode::Media(MediaKeyCode::TrackPrevious) => keys::TRACK_PREVIOUS.len(),
283+ KeyCode::Media(MediaKeyCode::Record) => keys::RECORD.len(),
284+ KeyCode::Media(MediaKeyCode::LowerVolume) => keys::LOWER_VOLUME.len(),
285+ KeyCode::Media(MediaKeyCode::RaiseVolume) => keys::RAISE_VOLUME.len(),
286+ KeyCode::Media(MediaKeyCode::MuteVolume) => keys::MUTE_VOLUME.len(),
287+ KeyCode::Modifier(ModifierKeyCode::LeftShift) => keys::LEFT_SHIFT.len(),
288+ KeyCode::Modifier(ModifierKeyCode::LeftControl) => keys::LEFT_CONTROL.len(),
289+ KeyCode::Modifier(ModifierKeyCode::LeftAlt) => keys::LEFT_ALT.len(),
290+ KeyCode::Modifier(ModifierKeyCode::LeftSuper) => keys::LEFT_SUPER.len(),
291+ KeyCode::Modifier(ModifierKeyCode::LeftHyper) => keys::LEFT_HYPER.len(),
292+ KeyCode::Modifier(ModifierKeyCode::LeftMeta) => keys::LEFT_META.len(),
293+ KeyCode::Modifier(ModifierKeyCode::RightShift) => keys::RIGHT_SHIFT.len(),
294+ KeyCode::Modifier(ModifierKeyCode::RightControl) => keys::RIGHT_CONTROL.len(),
295+ KeyCode::Modifier(ModifierKeyCode::RightAlt) => keys::RIGHT_ALT.len(),
296+ KeyCode::Modifier(ModifierKeyCode::RightSuper) => keys::RIGHT_SUPER.len(),
297+ KeyCode::Modifier(ModifierKeyCode::RightHyper) => keys::RIGHT_HYPER.len(),
298+ KeyCode::Modifier(ModifierKeyCode::RightMeta) => keys::RIGHT_META.len(),
299+ KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => keys::ISO_LEVEL_3_SHIFT.len(),
300+ KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => keys::ISO_LEVEL_5_SHIFT.len(),
195301 };
196302 if self.modifiers.contains(KeyModifiers::SHIFT) {
197303 width += 2;
@@ -235,6 +341,40 @@ impl std::str::FromStr for KeyEvent {
235341 keys::MINUS => KeyCode::Char('-'),
236342 keys::LESS_THAN => KeyCode::Char('<'),
237343 keys::GREATER_THAN => KeyCode::Char('>'),
344+ keys::CAPS_LOCK => KeyCode::CapsLock,
345+ keys::SCROLL_LOCK => KeyCode::ScrollLock,
346+ keys::NUM_LOCK => KeyCode::NumLock,
347+ keys::PRINT_SCREEN => KeyCode::PrintScreen,
348+ keys::PAUSE => KeyCode::Pause,
349+ keys::MENU => KeyCode::Menu,
350+ keys::KEYPAD_BEGIN => KeyCode::KeypadBegin,
351+ keys::PLAY => KeyCode::Media(MediaKeyCode::Play),
352+ keys::PAUSE_MEDIA => KeyCode::Media(MediaKeyCode::Pause),
353+ keys::PLAY_PAUSE => KeyCode::Media(MediaKeyCode::PlayPause),
354+ keys::STOP => KeyCode::Media(MediaKeyCode::Stop),
355+ keys::REVERSE => KeyCode::Media(MediaKeyCode::Reverse),
356+ keys::FAST_FORWARD => KeyCode::Media(MediaKeyCode::FastForward),
357+ keys::REWIND => KeyCode::Media(MediaKeyCode::Rewind),
358+ keys::TRACK_NEXT => KeyCode::Media(MediaKeyCode::TrackNext),
359+ keys::TRACK_PREVIOUS => KeyCode::Media(MediaKeyCode::TrackPrevious),
360+ keys::RECORD => KeyCode::Media(MediaKeyCode::Record),
361+ keys::LOWER_VOLUME => KeyCode::Media(MediaKeyCode::LowerVolume),
362+ keys::RAISE_VOLUME => KeyCode::Media(MediaKeyCode::RaiseVolume),
363+ keys::MUTE_VOLUME => KeyCode::Media(MediaKeyCode::MuteVolume),
364+ keys::LEFT_SHIFT => KeyCode::Modifier(ModifierKeyCode::LeftShift),
365+ keys::LEFT_CONTROL => KeyCode::Modifier(ModifierKeyCode::LeftControl),
366+ keys::LEFT_ALT => KeyCode::Modifier(ModifierKeyCode::LeftAlt),
367+ keys::LEFT_SUPER => KeyCode::Modifier(ModifierKeyCode::LeftSuper),
368+ keys::LEFT_HYPER => KeyCode::Modifier(ModifierKeyCode::LeftHyper),
369+ keys::LEFT_META => KeyCode::Modifier(ModifierKeyCode::LeftMeta),
370+ keys::RIGHT_SHIFT => KeyCode::Modifier(ModifierKeyCode::RightShift),
371+ keys::RIGHT_CONTROL => KeyCode::Modifier(ModifierKeyCode::RightControl),
372+ keys::RIGHT_ALT => KeyCode::Modifier(ModifierKeyCode::RightAlt),
373+ keys::RIGHT_SUPER => KeyCode::Modifier(ModifierKeyCode::RightSuper),
374+ keys::RIGHT_HYPER => KeyCode::Modifier(ModifierKeyCode::RightHyper),
375+ keys::RIGHT_META => KeyCode::Modifier(ModifierKeyCode::RightMeta),
376+ keys::ISO_LEVEL_3_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift),
377+ keys::ISO_LEVEL_5_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift),
238378 single if single.chars().count() == 1 => KeyCode::Char(single.chars().next().unwrap()),
239379 function if function.len() > 1 && function.starts_with('F') => {
240380 let function: String = function.chars().skip(1).collect();
helix-view/src/keyboard.rs+194−11
@@ -53,6 +53,164 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers {
5353 }
5454}
5555
56+/// Represents a media key (as part of [`KeyCode::Media`]).
57+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
58+pub enum MediaKeyCode {
59+ /// Play media key.
60+ Play,
61+ /// Pause media key.
62+ Pause,
63+ /// Play/Pause media key.
64+ PlayPause,
65+ /// Reverse media key.
66+ Reverse,
67+ /// Stop media key.
68+ Stop,
69+ /// Fast-forward media key.
70+ FastForward,
71+ /// Rewind media key.
72+ Rewind,
73+ /// Next-track media key.
74+ TrackNext,
75+ /// Previous-track media key.
76+ TrackPrevious,
77+ /// Record media key.
78+ Record,
79+ /// Lower-volume media key.
80+ LowerVolume,
81+ /// Raise-volume media key.
82+ RaiseVolume,
83+ /// Mute media key.
84+ MuteVolume,
85+}
86+
87+#[cfg(feature = "term")]
88+impl From<MediaKeyCode> for crossterm::event::MediaKeyCode {
89+ fn from(media_key_code: MediaKeyCode) -> Self {
90+ use crossterm::event::MediaKeyCode as CMediaKeyCode;
91+
92+ match media_key_code {
93+ MediaKeyCode::Play => CMediaKeyCode::Play,
94+ MediaKeyCode::Pause => CMediaKeyCode::Pause,
95+ MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause,
96+ MediaKeyCode::Reverse => CMediaKeyCode::Reverse,
97+ MediaKeyCode::Stop => CMediaKeyCode::Stop,
98+ MediaKeyCode::FastForward => CMediaKeyCode::FastForward,
99+ MediaKeyCode::Rewind => CMediaKeyCode::Rewind,
100+ MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext,
101+ MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious,
102+ MediaKeyCode::Record => CMediaKeyCode::Record,
103+ MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume,
104+ MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume,
105+ MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume,
106+ }
107+ }
108+}
109+
110+#[cfg(feature = "term")]
111+impl From<crossterm::event::MediaKeyCode> for MediaKeyCode {
112+ fn from(val: crossterm::event::MediaKeyCode) -> Self {
113+ use crossterm::event::MediaKeyCode as CMediaKeyCode;
114+
115+ match val {
116+ CMediaKeyCode::Play => MediaKeyCode::Play,
117+ CMediaKeyCode::Pause => MediaKeyCode::Pause,
118+ CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause,
119+ CMediaKeyCode::Reverse => MediaKeyCode::Reverse,
120+ CMediaKeyCode::Stop => MediaKeyCode::Stop,
121+ CMediaKeyCode::FastForward => MediaKeyCode::FastForward,
122+ CMediaKeyCode::Rewind => MediaKeyCode::Rewind,
123+ CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext,
124+ CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious,
125+ CMediaKeyCode::Record => MediaKeyCode::Record,
126+ CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume,
127+ CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume,
128+ CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume,
129+ }
130+ }
131+}
132+
133+/// Represents a media key (as part of [`KeyCode::Modifier`]).
134+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
135+pub enum ModifierKeyCode {
136+ /// Left Shift key.
137+ LeftShift,
138+ /// Left Control key.
139+ LeftControl,
140+ /// Left Alt key.
141+ LeftAlt,
142+ /// Left Super key.
143+ LeftSuper,
144+ /// Left Hyper key.
145+ LeftHyper,
146+ /// Left Meta key.
147+ LeftMeta,
148+ /// Right Shift key.
149+ RightShift,
150+ /// Right Control key.
151+ RightControl,
152+ /// Right Alt key.
153+ RightAlt,
154+ /// Right Super key.
155+ RightSuper,
156+ /// Right Hyper key.
157+ RightHyper,
158+ /// Right Meta key.
159+ RightMeta,
160+ /// Iso Level3 Shift key.
161+ IsoLevel3Shift,
162+ /// Iso Level5 Shift key.
163+ IsoLevel5Shift,
164+}
165+
166+#[cfg(feature = "term")]
167+impl From<ModifierKeyCode> for crossterm::event::ModifierKeyCode {
168+ fn from(modifier_key_code: ModifierKeyCode) -> Self {
169+ use crossterm::event::ModifierKeyCode as CModifierKeyCode;
170+
171+ match modifier_key_code {
172+ ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift,
173+ ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl,
174+ ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt,
175+ ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper,
176+ ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper,
177+ ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta,
178+ ModifierKeyCode::RightShift => CModifierKeyCode::RightShift,
179+ ModifierKeyCode::RightControl => CModifierKeyCode::RightControl,
180+ ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt,
181+ ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper,
182+ ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper,
183+ ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta,
184+ ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift,
185+ ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift,
186+ }
187+ }
188+}
189+
190+#[cfg(feature = "term")]
191+impl From<crossterm::event::ModifierKeyCode> for ModifierKeyCode {
192+ fn from(val: crossterm::event::ModifierKeyCode) -> Self {
193+ use crossterm::event::ModifierKeyCode as CModifierKeyCode;
194+
195+ match val {
196+ CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift,
197+ CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl,
198+ CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt,
199+ CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper,
200+ CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper,
201+ CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta,
202+ CModifierKeyCode::RightShift => ModifierKeyCode::RightShift,
203+ CModifierKeyCode::RightControl => ModifierKeyCode::RightControl,
204+ CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt,
205+ CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper,
206+ CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper,
207+ CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta,
208+ CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift,
209+ CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift,
210+ }
211+ }
212+}
213+
56214/// Represents a key.
57215#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
58216pub enum KeyCode {
@@ -94,6 +252,24 @@ pub enum KeyCode {
94252 Null,
95253 /// Escape key.
96254 Esc,
255+ /// CapsLock key.
256+ CapsLock,
257+ /// ScrollLock key.
258+ ScrollLock,
259+ /// NumLock key.
260+ NumLock,
261+ /// PrintScreen key.
262+ PrintScreen,
263+ /// Pause key.
264+ Pause,
265+ /// Menu key.
266+ Menu,
267+ /// KeypadBegin key.
268+ KeypadBegin,
269+ /// A media key.
270+ Media(MediaKeyCode),
271+ /// A modifier key.
272+ Modifier(ModifierKeyCode),
97273}
98274
99275#[cfg(feature = "term")]
@@ -119,6 +295,15 @@ impl From<KeyCode> for crossterm::event::KeyCode {
119295 KeyCode::Char(character) => CKeyCode::Char(character),
120296 KeyCode::Null => CKeyCode::Null,
121297 KeyCode::Esc => CKeyCode::Esc,
298+ KeyCode::CapsLock => CKeyCode::CapsLock,
299+ KeyCode::ScrollLock => CKeyCode::ScrollLock,
300+ KeyCode::NumLock => CKeyCode::NumLock,
301+ KeyCode::PrintScreen => CKeyCode::PrintScreen,
302+ KeyCode::Pause => CKeyCode::Pause,
303+ KeyCode::Menu => CKeyCode::Menu,
304+ KeyCode::KeypadBegin => CKeyCode::KeypadBegin,
305+ KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()),
306+ KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()),
122307 }
123308 }
124309}
@@ -147,17 +332,15 @@ impl From<crossterm::event::KeyCode> for KeyCode {
147332 CKeyCode::Char(character) => KeyCode::Char(character),
148333 CKeyCode::Null => KeyCode::Null,
149334 CKeyCode::Esc => KeyCode::Esc,
150− CKeyCode::CapsLock
151− | CKeyCode::ScrollLock
152− | CKeyCode::NumLock
153− | CKeyCode::PrintScreen
154− | CKeyCode::Pause
155− | CKeyCode::Menu
156− | CKeyCode::KeypadBegin
157− | CKeyCode::Media(_)
158− | CKeyCode::Modifier(_) => unreachable!(
159− "Shouldn't get this key without enabling DISAMBIGUATE_ESCAPE_CODES in crossterm"
160− ),
335+ CKeyCode::CapsLock => KeyCode::CapsLock,
336+ CKeyCode::ScrollLock => KeyCode::ScrollLock,
337+ CKeyCode::NumLock => KeyCode::NumLock,
338+ CKeyCode::PrintScreen => KeyCode::PrintScreen,
339+ CKeyCode::Pause => KeyCode::Pause,
340+ CKeyCode::Menu => KeyCode::Menu,
341+ CKeyCode::KeypadBegin => KeyCode::KeypadBegin,
342+ CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()),
343+ CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()),
161344 }
162345 }
163346}