From 2bd4b1ff83da1799df4713296f8d993958d3bf73 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Tue, 17 Dec 2024 22:21:13 -0500 Subject: [PATCH] feat: `gg` will move to the top row --- src/ui/mod.rs | 16 ++++++++++++++++ src/ui/test.rs | 20 +++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2ee3ad3..8b09161 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -78,6 +78,7 @@ pub struct AppState<'ws> { pub viewport_state: ViewportState, pub command_state: TextState<'ws>, pub numeric_prefix: Vec, + pub char_queue: Vec, pub range_select: RangeSelection, dirty: bool, popup: Vec, @@ -91,6 +92,7 @@ impl<'ws> Default for AppState<'ws> { viewport_state: Default::default(), command_state: Default::default(), numeric_prefix: Default::default(), + char_queue: Default::default(), range_select: Default::default(), dirty: Default::default(), popup: Default::default(), @@ -240,6 +242,12 @@ impl<'ws> Workspace<'ws> { Ok(()) } + /// Move to the top row without changing columns + pub fn move_to_top(&mut self) -> Result<()> { + self.book.move_to(&Address { row: 1, col: self.book.location.col })?; + Ok(()) + } + /// Move a row up in the current sheet. pub fn move_up(&mut self) -> Result<()> { let mut loc = self.book.location.clone(); @@ -801,6 +809,14 @@ impl<'ws> Workspace<'ws> { Ok(()) })?; } + KeyCode::Char('g') => { + if self.state.char_queue.first().map(|c| *c == 'g').unwrap_or(false) { + self.state.char_queue.pop(); + self.move_to_top()?; + } else { + self.state.char_queue.push('g'); + } + } _ => { // noop } diff --git a/src/ui/test.rs b/src/ui/test.rs index fce996e..72e4280 100644 --- a/src/ui/test.rs +++ b/src/ui/test.rs @@ -200,7 +200,6 @@ fn construct_modified_key_event(code: KeyCode, mods: KeyModifiers) -> Event { Event::Key(KeyEvent::new(code, mods)) } -// TODO(zaphar): Interaction testing for input. #[test] fn test_input_navitation_enter_key() { let mut ws = @@ -425,3 +424,22 @@ fn test_range_copy_mode_from_edit_mode() { .expect("Failed to handle 'Ctrl-r' key event"); assert_eq!(Some(&Modality::RangeSelect), ws.state.modality_stack.last()); } + +#[test] +fn test_gg_movement() { + let mut ws = + Workspace::new_empty("en", "America/New_York").expect("Failed to get empty workbook"); + assert_eq!(Some(&Modality::Navigate), ws.state.modality_stack.last()); + ws.handle_input(construct_key_event(KeyCode::Char('j'))) + .expect("Failed to handle 'e' key event"); + ws.handle_input(construct_key_event(KeyCode::Char('j'))) + .expect("Failed to handle 'e' key event"); + assert_eq!(ws.book.location, Address { row: 3, col: 1 }); + ws.handle_input(construct_key_event(KeyCode::Char('l'))) + .expect("Failed to handle 'e' key event"); + ws.handle_input(construct_key_event(KeyCode::Char('g'))) + .expect("Failed to handle 'e' key event"); + ws.handle_input(construct_key_event(KeyCode::Char('g'))) + .expect("Failed to handle 'e' key event"); + assert_eq!(ws.book.location, Address { row: 1, col: 2 }); +}