Skip to content

Commit af72d20

Browse files
committed
Properly support multiple visible lines in view
Previously, only one line could be marked as visible in the view data. This resulted in the multi-select mode not correctly scrolling to the start index in cases where lines are reordered. This change adds support for multiple visible lines in the view data, resulting in the "ensure visible" algorithm running over each visible line.
1 parent 28c9132 commit af72d20

File tree

6 files changed

+80
-12
lines changed

6 files changed

+80
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
55

66
## [2.4.0] - 2024-06-01
77
### Added
8-
- Add support for `NO_COLOR` environment
9-
variable ([#896](https://github.com/MitMaro/git-interactive-rebase-tool/pull/896))
8+
- Add support for `NO_COLOR` environment variable ([#896](https://github.com/MitMaro/git-interactive-rebase-tool/pull/896))
109
- Post modified line exec command ([#888](https://github.com/MitMaro/git-interactive-rebase-tool/pull/890))
1110

1211
### Changed
@@ -15,6 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
1514
### Fixed
1615
- Fixed TTY support on macOS ([#874](https://github.com/MitMaro/git-interactive-rebase-tool/pull/874))
1716
- Flicker when action width changes ([#888](https://github.com/MitMaro/git-interactive-rebase-tool/pull/891))
17+
- Selected line was not always visible when multiple lines were selected ([#918](https://github.com/MitMaro/git-interactive-rebase-tool/pull/918))
1818

1919
## [2.3.0] - 2023-07-19
2020
### Added
@@ -183,7 +183,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
183183
### Added
184184
- Initial project release
185185

186-
[Unreleased]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.3.0...HEAD
186+
[Unreleased]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.4.0...HEAD
187+
[2.4.0]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.3.0...2.4.0
187188
[2.3.0]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.2.1...2.3.0
188189
[2.2.1]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.2.0...2.2.1
189190
[2.2.0]: https://github.com/MitMaro/git-interactive-rebase-tool/compare/2.1.0...2.2.0

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ nonstandard_style = { level = "warn", priority = -2 }
103103
rust_2018_compatibility = { level = "warn", priority = -2 }
104104
rust_2018_idioms = { level = "warn", priority = -2 }
105105
rust_2021_compatibility = { level = "warn", priority = -2 }
106-
rust_2024_compatibility = { level = "warn", priority = -2 }
106+
# rust_2024_compatibility = { level = "warn", priority = -2 } - requires some significant changes
107107
unused = { level = "warn", priority = -2 }
108108

109109
unknown_lints = { level = "warn", priority = -1 }

src/view/render_slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl RenderSlice {
274274
self.padding_height < self.height && lines_length > (self.height - self.padding_height);
275275

276276
self.scroll_position.set_lines_length(lines_length);
277-
if let Some(row) = view_data.get_visible_row().as_ref() {
277+
for row in view_data.visible_rows() {
278278
self.scroll_position.ensure_line_visible(*row);
279279
}
280280

src/view/tests.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,56 @@ fn render_with_scroll_bar() {
182182
],
183183
);
184184
}
185+
186+
#[test]
187+
fn render_ensure_visible_row_single() {
188+
assert_render(
189+
30,
190+
3,
191+
&ViewData::new(|updater| {
192+
updater.push_line(ViewLine::from("This is line 1"));
193+
updater.push_line(ViewLine::from("This is line 2"));
194+
updater.push_line(ViewLine::from("This is line 3"));
195+
updater.push_line(ViewLine::from("This is line 4"));
196+
updater.push_line(ViewLine::from("This is line 5"));
197+
updater.ensure_line_visible(3);
198+
}),
199+
&["This is line 2 ", "This is line 3 ", "This is line 4█"],
200+
);
201+
}
202+
203+
#[test]
204+
fn render_ensure_visible_multiple_rows_increasing_order() {
205+
assert_render(
206+
30,
207+
3,
208+
&ViewData::new(|updater| {
209+
updater.push_line(ViewLine::from("This is line 1"));
210+
updater.push_line(ViewLine::from("This is line 2"));
211+
updater.push_line(ViewLine::from("This is line 3"));
212+
updater.push_line(ViewLine::from("This is line 4"));
213+
updater.push_line(ViewLine::from("This is line 5"));
214+
updater.ensure_line_visible(3);
215+
updater.ensure_line_visible(4);
216+
}),
217+
&["This is line 3 ", "This is line 4 ", "This is line 5█"],
218+
);
219+
}
220+
221+
#[test]
222+
fn render_ensure_visible_multiple_rows_decreasing_order() {
223+
assert_render(
224+
30,
225+
3,
226+
&ViewData::new(|updater| {
227+
updater.push_line(ViewLine::from("This is line 1"));
228+
updater.push_line(ViewLine::from("This is line 2"));
229+
updater.push_line(ViewLine::from("This is line 3"));
230+
updater.push_line(ViewLine::from("This is line 4"));
231+
updater.push_line(ViewLine::from("This is line 5"));
232+
updater.ensure_line_visible(4);
233+
updater.ensure_line_visible(3);
234+
}),
235+
&["This is line 3 ", "This is line 4 ", "This is line 5█"],
236+
);
237+
}

src/view/view_data.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub(crate) struct ViewData {
1515
show_title: bool,
1616
version: u32,
1717
visible_column: Option<usize>,
18-
visible_row: Option<usize>,
18+
visible_rows: Vec<usize>,
1919
}
2020

2121
impl ViewData {
@@ -33,7 +33,7 @@ impl ViewData {
3333
show_title: false,
3434
version: 0,
3535
visible_column: None,
36-
visible_row: None,
36+
visible_rows: vec![],
3737
};
3838
let mut view_data_updater = ViewDataUpdater::new(&mut view_data);
3939
callback(&mut view_data_updater);
@@ -69,8 +69,12 @@ impl ViewData {
6969
self.lines.clear();
7070
}
7171

72+
pub(crate) fn clear_visible_lines(&mut self) {
73+
self.visible_rows.clear();
74+
}
75+
7276
pub(crate) fn ensure_line_visible(&mut self, row_index: usize) {
73-
self.visible_row = Some(row_index);
77+
self.visible_rows.push(row_index);
7478
}
7579

7680
pub(crate) fn ensure_column_visible(&mut self, column_index: usize) {
@@ -129,8 +133,8 @@ impl ViewData {
129133
&self.visible_column
130134
}
131135

132-
pub(crate) const fn get_visible_row(&self) -> &Option<usize> {
133-
&self.visible_row
136+
pub(crate) const fn visible_rows(&self) -> &Vec<usize> {
137+
&self.visible_rows
134138
}
135139

136140
pub(crate) fn get_name(&self) -> &str {
@@ -210,7 +214,16 @@ mod tests {
210214
fn ensure_line_visible() {
211215
let mut view_data = ViewData::new(|_| {});
212216
view_data.ensure_line_visible(10);
213-
assert_eq!(view_data.get_visible_row().unwrap(), 10);
217+
view_data.ensure_line_visible(11);
218+
assert_eq!(view_data.visible_rows(), &vec![10, 11]);
219+
}
220+
221+
#[test]
222+
fn clear_visible_lines() {
223+
let mut view_data = ViewData::new(|_| {});
224+
view_data.ensure_line_visible(10);
225+
view_data.clear_visible_lines();
226+
assert_eq!(view_data.visible_rows().len(), 0);
214227
}
215228

216229
#[test]

src/view/view_data_updater.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ impl<'view_data> ViewDataUpdater<'view_data> {
1818
/// Clear content of the view data.
1919
pub(crate) fn clear(&mut self) {
2020
self.modified = true;
21+
self.view_data.clear_visible_lines();
2122
self.view_data.clear();
2223
}
2324

@@ -127,7 +128,7 @@ mod tests {
127128
let mut updater = ViewDataUpdater::new(&mut view_data);
128129
updater.ensure_line_visible(10);
129130
assert!(updater.is_modified());
130-
assert_eq!(view_data.get_visible_row().unwrap(), 10);
131+
assert_eq!(view_data.visible_rows(), &vec![10]);
131132
}
132133

133134
#[test]

0 commit comments

Comments
 (0)