diff --git a/src/command/cmd.rs b/src/command/cmd.rs index 41d7c89..e0cbc57 100644 --- a/src/command/cmd.rs +++ b/src/command/cmd.rs @@ -562,12 +562,7 @@ impl Cmd for TogglePanelAndFocus { open: self.open, })); if self.focused { - let mode = match self.panel { - Panel::Formula => AppMode::FormulaPanel, - Panel::Category => AppMode::CategoryPanel, - Panel::View => AppMode::ViewPanel, - }; - effects.push(effect::change_mode(mode)); + effects.push(effect::change_mode(self.panel.mode())); } else { effects.push(effect::change_mode(AppMode::Normal)); } diff --git a/src/ui/app.rs b/src/ui/app.rs index 5c8b114..98e4ef3 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -482,6 +482,56 @@ mod tests { assert_eq!(app.model.active_view().selected.0, 5); } + #[test] + fn jump_last_row_scrolls_with_small_terminal() { + let mut app = two_col_model(); + // Total rows: A, B, C + R0..R9 = 13 rows. Last row = 12. + for i in 0..10 { + app.model.category_mut("Row").unwrap().add_item(&format!("R{i}")); + } + app.term_height = 13; // ~5 visible rows + app.model.active_view_mut().selected = (0, 0); + // G jumps to last row (row 12) + app.handle_key(KeyEvent::new(KeyCode::Char('G'), KeyModifiers::NONE)) + .unwrap(); + let last = app.model.active_view().selected.0; + assert_eq!(last, 12, "should be at last row"); + // With only ~5 visible rows and 13 rows, offset should scroll. + // Bug: hardcoded 20 means `12 >= 0 + 20` is false → no scroll. + let offset = app.model.active_view().row_offset; + assert!( + offset > 0, + "row_offset should scroll when last row is beyond visible area, but is {offset}" + ); + } + + #[test] + fn ctrl_d_scrolls_viewport_with_small_terminal() { + let mut app = two_col_model(); + for i in 0..30 { + app.model + .category_mut("Row") + .unwrap() + .add_item(&format!("R{i}")); + } + app.term_height = 13; // ~5 visible rows + app.model.active_view_mut().selected = (0, 0); + // Ctrl+d scrolls by 5 rows + app.handle_key(KeyEvent::new(KeyCode::Char('d'), KeyModifiers::CONTROL)) + .unwrap(); + assert_eq!(app.model.active_view().selected.0, 5); + // Press Ctrl+d again — now at row 10 with only 5 visible rows, + // row_offset should have scrolled (not stay at 0 due to hardcoded 20) + app.handle_key(KeyEvent::new(KeyCode::Char('d'), KeyModifiers::CONTROL)) + .unwrap(); + assert_eq!(app.model.active_view().selected.0, 10); + assert!( + app.model.active_view().row_offset > 0, + "row_offset should scroll with small terminal, but is {}", + app.model.active_view().row_offset + ); + } + #[test] fn tab_in_edit_mode_commits_and_moves_right() { let mut app = two_col_model(); diff --git a/src/ui/effect.rs b/src/ui/effect.rs index 464b0aa..bc26390 100644 --- a/src/ui/effect.rs +++ b/src/ui/effect.rs @@ -830,6 +830,16 @@ pub enum Panel { View, } +impl Panel { + pub fn mode(self) -> AppMode { + match self { + Panel::Formula => AppMode::FormulaPanel, + Panel::Category => AppMode::CategoryPanel, + Panel::View => AppMode::ViewPanel, + } + } +} + impl Effect for SetPanelOpen { fn apply(&self, app: &mut App) { match self.panel {