From 7576e0eb01c7875b95bea50e57144698bdeef6e9 Mon Sep 17 00:00:00 2001 From: Tim Oram Date: Fri, 7 Jun 2024 23:01:07 -0230 Subject: [PATCH] Fix hidden line on non-body line addition When a leading, trailing or header line was added to the view data, the RenderSlice was not correctly updated to take into account which lines should be visible. This resulted in some lines being hidden below the view "window". This fixes the RenderSlice to recalculate the scroll position when a leading, trailing or header line is changed. --- CHANGELOG.md | 1 + src/view/render_slice.rs | 1 + src/view/tests.rs | 73 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 554283759..8ca939ce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). - Fixed TTY support on macOS ([#874](https://github.com/MitMaro/git-interactive-rebase-tool/pull/874)) - Flicker when action width changes ([#888](https://github.com/MitMaro/git-interactive-rebase-tool/pull/891)) - Selected line was not always visible when multiple lines were selected ([#918](https://github.com/MitMaro/git-interactive-rebase-tool/pull/918)) +- Selected line hidden by added trailing, leading or header line when view was not resized ([#919](https://github.com/MitMaro/git-interactive-rebase-tool/pull/919)) ## [2.3.0] - 2023-07-19 ### Added diff --git a/src/view/render_slice.rs b/src/view/render_slice.rs index 9af71c231..c6e486465 100644 --- a/src/view/render_slice.rs +++ b/src/view/render_slice.rs @@ -218,6 +218,7 @@ impl RenderSlice { if self.padding_height != padding_height { self.padding_height = padding_height; + self.update_scroll_position_size(); } } diff --git a/src/view/tests.rs b/src/view/tests.rs index d07b54ee3..1e747b4ba 100644 --- a/src/view/tests.rs +++ b/src/view/tests.rs @@ -1,7 +1,7 @@ use super::*; use crate::{config::Theme, display::Size, test_helpers::mocks}; -fn assert_render(width: usize, height: usize, view_data: &ViewData, expected: &[&str]) { +fn assert_render_slice(width: usize, height: usize, render_slice: &RenderSlice, expected: &[&str]) { let theme = Theme::new_with_config(None).unwrap(); let mut crossterm = mocks::CrossTerm::new(); let readonly_tui = crossterm.clone(); @@ -9,11 +9,15 @@ fn assert_render(width: usize, height: usize, view_data: &ViewData, expected: &[ let display = Display::new(crossterm, &theme); let mut view = View::new(display, "~", "?"); + view.render(&render_slice).unwrap(); + assert_eq!(readonly_tui.get_output().join(""), format!("{}\n", expected.join("\n"))); +} + +fn assert_render(width: usize, height: usize, view_data: &ViewData, expected: &[&str]) { let mut render_slice = RenderSlice::new(); render_slice.record_resize(width, height); render_slice.sync_view_data(view_data); - view.render(&render_slice).unwrap(); - assert_eq!(readonly_tui.get_output().join(""), format!("{}\n", expected.join("\n"))); + assert_render_slice(width, height, &render_slice, expected); } #[test] @@ -235,3 +239,66 @@ fn render_ensure_visible_multiple_rows_decreasing_order() { &["This is line 3 ", "This is line 4 ", "This is line 5█"], ); } + +#[test] +fn render_after_leading_lines_change() { + let width = 30; + let height = 2; + let mut render_slice = RenderSlice::new(); + render_slice.record_resize(width, height); + let mut view_data = ViewData::new(|updater| { + updater.push_line(ViewLine::from("This is line 1")); + updater.push_line(ViewLine::from("This is line 2")); + updater.push_line(ViewLine::from("This is line 3")); + updater.ensure_line_visible(2); + }); + render_slice.sync_view_data(&view_data); + view_data.update_view_data(|updater| { + updater.push_leading_line(ViewLine::from("This is line 0")); + }); + render_slice.sync_view_data(&view_data); + assert_render_slice(width, height, &render_slice, &["This is line 0", "This is line 3█"]); +} + +#[test] +fn render_after_title_show() { + let width = 30; + let height = 2; + let mut render_slice = RenderSlice::new(); + render_slice.record_resize(width, height); + let mut view_data = ViewData::new(|updater| { + updater.push_line(ViewLine::from("This is line 1")); + updater.push_line(ViewLine::from("This is line 2")); + updater.push_line(ViewLine::from("This is line 3")); + updater.ensure_line_visible(2); + }); + render_slice.sync_view_data(&view_data); + view_data.update_view_data(|updater| { + updater.set_show_title(true); + }); + render_slice.sync_view_data(&view_data); + assert_render_slice(width, height, &render_slice, &[ + "Git Interactive Rebase Tool ", + "This is line 3█", + ]); +} + +#[test] +fn render_after_trailing_lines_change() { + let width = 30; + let height = 2; + let mut render_slice = RenderSlice::new(); + render_slice.record_resize(width, height); + let mut view_data = ViewData::new(|updater| { + updater.push_line(ViewLine::from("This is line 1")); + updater.push_line(ViewLine::from("This is line 2")); + updater.push_line(ViewLine::from("This is line 3")); + updater.ensure_line_visible(2); + }); + render_slice.sync_view_data(&view_data); + view_data.update_view_data(|updater| { + updater.push_trailing_line(ViewLine::from("This is line 4")); + }); + render_slice.sync_view_data(&view_data); + assert_render_slice(width, height, &render_slice, &["This is line 3█", "This is line 4"]); +}