From 75b14d5048ba7c4309b3a6e970106834eb7eead6 Mon Sep 17 00:00:00 2001 From: cxreiff Date: Wed, 27 Nov 2024 00:14:07 -0800 Subject: [PATCH] feat: handle repeat key events using crossterm backend --- src/backend/crossterm.rs | 88 ++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/src/backend/crossterm.rs b/src/backend/crossterm.rs index 9f130b0..de00045 100644 --- a/src/backend/crossterm.rs +++ b/src/backend/crossterm.rs @@ -19,43 +19,45 @@ pub fn to_input_request(evt: &CrosstermEvent) -> Option { modifiers, kind, state: _, - }) if *kind == KeyEventKind::Press => match (*code, *modifiers) { - (Backspace, KeyModifiers::NONE) | (Char('h'), KeyModifiers::CONTROL) => { - Some(DeletePrevChar) + }) if *kind == KeyEventKind::Press || *kind == KeyEventKind::Repeat => { + match (*code, *modifiers) { + (Backspace, KeyModifiers::NONE) | (Char('h'), KeyModifiers::CONTROL) => { + Some(DeletePrevChar) + } + (Delete, KeyModifiers::NONE) => Some(DeleteNextChar), + (Tab, KeyModifiers::NONE) => None, + (Left, KeyModifiers::NONE) | (Char('b'), KeyModifiers::CONTROL) => { + Some(GoToPrevChar) + } + (Left, KeyModifiers::CONTROL) | (Char('b'), KeyModifiers::META) => { + Some(GoToPrevWord) + } + (Right, KeyModifiers::NONE) | (Char('f'), KeyModifiers::CONTROL) => { + Some(GoToNextChar) + } + (Right, KeyModifiers::CONTROL) | (Char('f'), KeyModifiers::META) => { + Some(GoToNextWord) + } + (Char('u'), KeyModifiers::CONTROL) => Some(DeleteLine), + + (Char('w'), KeyModifiers::CONTROL) + | (Char('d'), KeyModifiers::META) + | (Backspace, KeyModifiers::META) + | (Backspace, KeyModifiers::ALT) => Some(DeletePrevWord), + + (Delete, KeyModifiers::CONTROL) => Some(DeleteNextWord), + (Char('k'), KeyModifiers::CONTROL) => Some(DeleteTillEnd), + (Char('a'), KeyModifiers::CONTROL) | (Home, KeyModifiers::NONE) => { + Some(GoToStart) + } + (Char('e'), KeyModifiers::CONTROL) | (End, KeyModifiers::NONE) => { + Some(GoToEnd) + } + (Char(c), KeyModifiers::NONE) => Some(InsertChar(c)), + (Char(c), KeyModifiers::SHIFT) => Some(InsertChar(c)), + (_, _) => None, } - (Delete, KeyModifiers::NONE) => Some(DeleteNextChar), - (Tab, KeyModifiers::NONE) => None, - (Left, KeyModifiers::NONE) | (Char('b'), KeyModifiers::CONTROL) => { - Some(GoToPrevChar) - } - (Left, KeyModifiers::CONTROL) | (Char('b'), KeyModifiers::META) => { - Some(GoToPrevWord) - } - (Right, KeyModifiers::NONE) | (Char('f'), KeyModifiers::CONTROL) => { - Some(GoToNextChar) - } - (Right, KeyModifiers::CONTROL) | (Char('f'), KeyModifiers::META) => { - Some(GoToNextWord) - } - (Char('u'), KeyModifiers::CONTROL) => Some(DeleteLine), - - (Char('w'), KeyModifiers::CONTROL) - | (Char('d'), KeyModifiers::META) - | (Backspace, KeyModifiers::META) - | (Backspace, KeyModifiers::ALT) => Some(DeletePrevWord), - - (Delete, KeyModifiers::CONTROL) => Some(DeleteNextWord), - (Char('k'), KeyModifiers::CONTROL) => Some(DeleteTillEnd), - (Char('a'), KeyModifiers::CONTROL) | (Home, KeyModifiers::NONE) => { - Some(GoToStart) - } - (Char('e'), KeyModifiers::CONTROL) | (End, KeyModifiers::NONE) => { - Some(GoToEnd) - } - (Char(c), KeyModifiers::NONE) => Some(InsertChar(c)), - (Char(c), KeyModifiers::SHIFT) => Some(InsertChar(c)), - (_, _) => None, - }, + } _ => None, } } @@ -135,4 +137,18 @@ mod tests { assert!(req.is_none()); } + + #[test] + fn handle_repeat() { + let evt = CrosstermEvent::Key(KeyEvent { + code: KeyCode::Char('a'), + modifiers: KeyModifiers::NONE, + kind: KeyEventKind::Repeat, + state: KeyEventState::NONE, + }); + + let req = to_input_request(&evt); + + assert_eq!(req, Some(InputRequest::InsertChar('a'))); + } }