Skip to content

Commit cb58452

Browse files
committed
Handle disambiguated keycodes
Media keys are sent despite `DISAMBIGUATE_ESCAPE_CODES` being set. Previously we panicked on these. This change translates the disambiguated keys from crossterm so that do not cause a panic.
1 parent 2271c3a commit cb58452

File tree

2 files changed

+335
-12
lines changed

2 files changed

+335
-12
lines changed

helix-view/src/input.rs

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use helix_core::unicode::{segmentation::UnicodeSegmentation, width::UnicodeWidth
44
use serde::de::{self, Deserialize, Deserializer};
55
use 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)]
1010
pub 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

124158
impl 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();

0 commit comments

Comments
 (0)