diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index 8070bba225..82d08231a3 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -923,7 +923,7 @@ impl Grid { self.saved_cursor_position.as_ref().map(|saved_cursor| saved_cursor.y); let new_cursor_x = self.cursor.x; - let mut saved_cursor_x_coordinates = + let saved_cursor_x_coordinates = self.saved_cursor_position.as_ref().map(|saved_cursor| saved_cursor.x); let current_viewport_row_count = self.viewport.len(); @@ -947,15 +947,15 @@ impl Grid { let row_count_to_transfer = current_viewport_row_count - new_rows; if row_count_to_transfer > new_cursor_y { new_cursor_y = 0; - if let Some(saved_cursor_y_coordinates) = saved_cursor_y_coordinates.as_mut() { - *saved_cursor_y_coordinates = 0 - }; } else { new_cursor_y -= row_count_to_transfer; - if let Some(saved_cursor_y_coordinates) = saved_cursor_y_coordinates.as_mut() { - *saved_cursor_y_coordinates = saved_cursor_y_coordinates - .saturating_sub(row_count_to_transfer); - }; + } + if let Some(saved_cursor_y_coordinates) = saved_cursor_y_coordinates.as_mut() { + if row_count_to_transfer > *saved_cursor_y_coordinates { + *saved_cursor_y_coordinates = 0; + } else { + *saved_cursor_y_coordinates -= row_count_to_transfer; + } } transfer_rows_from_viewport_to_lines_above( &mut self.viewport, diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs index 781904c365..01d6cc9402 100644 --- a/zellij-server/src/panes/unit/grid_tests.rs +++ b/zellij-server/src/panes/unit/grid_tests.rs @@ -2400,6 +2400,48 @@ pub fn scroll_up_increase_width_and_scroll_down() { assert_snapshot!(format!("{:?}", grid)); } +#[test] +fn saved_cursor_across_resize() { + let mut vte_parser = vte::Parser::new(); + let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default())); + let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new())); + let debug = false; + let arrow_fonts = true; + let styled_underlines = true; + let mut grid = Grid::new( + 4, + 20, + Rc::new(RefCell::new(Palette::default())), + terminal_emulator_color_codes, + Rc::new(RefCell::new(LinkHandler::new())), + Rc::new(RefCell::new(None)), + sixel_image_store, + Style::default(), + debug, + arrow_fonts, + styled_underlines, + ); + let mut parse = |s, grid: &mut Grid| + for b in Vec::from(s) { vte_parser.advance(&mut *grid, b) }; + let content = "\n +\rLine 1 >fill to 20_< +\rLine 2 >fill to 20_< +\rLine 3 >fill to 20_< +\rL\u{1b}[sine 4 >fill to 20_<"; + parse(content, &mut grid); + // Move real cursor position up three lines + let content = "\u{1b}[3A"; + parse(content, &mut grid); + // Truncate top of terminal, resetting cursor (but not saved cursor) + grid.change_size(3, 20); + // Wrap, resetting cursor again (but not saved cursor) + grid.change_size(3, 10); + // Restore saved cursor position and write ZZZ + let content = "\u{1b}[uZZZ"; + parse(content, &mut grid); + assert_snapshot!(format!("{:?}", grid)); +} + #[test] pub fn move_cursor_below_scroll_region() { let mut vte_parser = vte::Parser::new(); diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__saved_cursor_across_resize.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__saved_cursor_across_resize.snap new file mode 100644 index 0000000000..dcb20d3880 --- /dev/null +++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__saved_cursor_across_resize.snap @@ -0,0 +1,9 @@ +--- +source: zellij-server/src/panes/./unit/grid_tests.rs +assertion_line: 2443 +expression: "format!(\"{:?}\", grid)" +--- +00 (W): ll to 20_< +01 (C): LZZZ 4 >fi +02 (W): ll to 20_< +