From 70286ffad159cb9c3dce83bdea6a225615dfbb3e Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Thu, 3 Nov 2022 05:13:27 -0400 Subject: [PATCH] Don't panic if we get an unexpected key code It seems like we get media play/pause/mute/etc keys despite not emitting DISAMBIGUATE_ESCAPE_CODES(#4125). Make crossterm::event::KeyCode a TryInto for KeyCode instead of Into to let us ignore keys we don't care about. --- helix-term/src/application.rs | 12 ++++++++++-- helix-view/src/input.rs | 28 +++++++++++++++------------- helix-view/src/keyboard.rs | 12 +++++++----- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 173c5d49a55b..910dc0bc5e08 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -538,14 +538,22 @@ impl Application { jobs: &mut self.jobs, scroll: None, }; - // Handle key events let should_redraw = match event.unwrap() { CrosstermEvent::Resize(width, height) => { self.compositor.resize(width, height); self.compositor .handle_event(&Event::Resize(width, height), &mut cx) } - event => self.compositor.handle_event(&event.into(), &mut cx), + event => match &event.try_into() { + Ok(event) => self.compositor.handle_event(event, &mut cx), + Err(err) => { + log::warn!( + "Unable to convert crossterm event to helix event. Ignoring. Cause: {}", + err + ); + false + } + }, }; if should_redraw && !self.editor.should_close() { diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 30fa72c49653..5020ccb4b2fd 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -276,16 +276,17 @@ impl<'de> Deserialize<'de> for KeyEvent { } #[cfg(feature = "term")] -impl From for Event { - fn from(event: crossterm::event::Event) -> Self { - match event { - crossterm::event::Event::Key(key) => Self::Key(key.into()), +impl TryFrom for Event { + type Error = anyhow::Error; + fn try_from(event: crossterm::event::Event) -> Result { + Ok(match event { + crossterm::event::Event::Key(key) => Self::Key(key.try_into()?), crossterm::event::Event::Mouse(mouse) => Self::Mouse(mouse.into()), crossterm::event::Event::Resize(w, h) => Self::Resize(w, h), crossterm::event::Event::FocusGained => Self::FocusGained, crossterm::event::Event::FocusLost => Self::FocusLost, crossterm::event::Event::Paste(s) => Self::Paste(s), - } + }) } } @@ -334,25 +335,26 @@ impl From for MouseButton { } #[cfg(feature = "term")] -impl From for KeyEvent { - fn from( +impl TryFrom for KeyEvent { + type Error = anyhow::Error; + fn try_from( crossterm::event::KeyEvent { code, modifiers, .. }: crossterm::event::KeyEvent, - ) -> Self { + ) -> Result { if code == crossterm::event::KeyCode::BackTab { // special case for BackTab -> Shift-Tab let mut modifiers: KeyModifiers = modifiers.into(); modifiers.insert(KeyModifiers::SHIFT); - Self { + Ok(Self { code: KeyCode::Tab, modifiers, - } + }) } else { - Self { - code: code.into(), + Ok(Self { + code: code.try_into()?, modifiers: modifiers.into(), - } + }) } } } diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs index 84cfebf160d7..6231542d5bdf 100644 --- a/helix-view/src/keyboard.rs +++ b/helix-view/src/keyboard.rs @@ -1,3 +1,4 @@ +use anyhow::{bail, Error}; use bitflags::bitflags; bitflags! { @@ -124,11 +125,12 @@ impl From for crossterm::event::KeyCode { } #[cfg(feature = "term")] -impl From for KeyCode { - fn from(val: crossterm::event::KeyCode) -> Self { +impl TryFrom for KeyCode { + type Error = Error; + fn try_from(val: crossterm::event::KeyCode) -> Result { use crossterm::event::KeyCode as CKeyCode; - match val { + Ok(match val { CKeyCode::Backspace => KeyCode::Backspace, CKeyCode::Enter => KeyCode::Enter, CKeyCode::Left => KeyCode::Left, @@ -155,9 +157,9 @@ impl From for KeyCode { | CKeyCode::Menu | CKeyCode::KeypadBegin | CKeyCode::Media(_) - | CKeyCode::Modifier(_) => unreachable!( + | CKeyCode::Modifier(_) => bail!( "Shouldn't get this key without enabling DISAMBIGUATE_ESCAPE_CODES in crossterm" ), - } + }) } }