Skip to content

Commit 655cdfb

Browse files
committed
take "error" result from binary search into account
1 parent 463c411 commit 655cdfb

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5050
* disable blame and history popup keybinds for untracked files [[@kpbaks](https://github.com/kpbaks)] ([#2489](https://github.com/gitui-org/gitui/pull/2489))
5151
* overwrites committer on amend of unsigned commits [[@cruessler](https://github.com/cruessler)] ([#2784](https://github.com/gitui-org/gitui/issues/2784))
5252
* Updated project links to point to `gitui-org` instead of `extrawurst` [[@vasleymus](https://github.com/vasleymus)] ([#2538](https://github.com/gitui-org/gitui/pull/2538))
53+
* when staging the last file in a directory, the first item after the directory is no longer skipped [[@Tillerino](https://github.com/Tillerino)] ([#2748](https://github.com/gitui-org/gitui/issues/2748))
5354

5455
## [0.27.0] - 2025-01-14
5556

src/components/utils/statustree.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,13 @@ impl StatusTree {
5151

5252
let last_selection =
5353
self.selected_item().map(|e| e.info.full_path);
54-
let last_selection_index = self.selection.unwrap_or(0);
5554

5655
self.tree = FileTreeItems::new(list, &last_collapsed)?;
5756
self.selection = last_selection.as_ref().map_or_else(
5857
|| self.tree.items().first().map(|_| 0),
5958
|last_selection| {
60-
self.find_last_selection(
61-
last_selection,
62-
last_selection_index,
63-
)
64-
.or_else(|| self.tree.items().first().map(|_| 0))
59+
self.find_last_selection(last_selection)
60+
.or_else(|| self.tree.items().first().map(|_| 0))
6561
},
6662
);
6763

@@ -196,19 +192,18 @@ impl StatusTree {
196192
fn find_last_selection(
197193
&self,
198194
last_selection: &str,
199-
last_index: usize,
200195
) -> Option<usize> {
201196
if self.is_empty() {
202197
return None;
203198
}
204199

205-
if let Ok(i) = self.tree.items().binary_search_by(|e| {
200+
let res = self.tree.items().binary_search_by(|e| {
206201
e.info.full_path.as_str().cmp(last_selection)
207-
}) {
208-
return Some(i);
202+
});
203+
match res {
204+
Ok(i) => Some(i),
205+
Err(i) => Some(cmp::min(i, self.tree.len() - 1)),
209206
}
210-
211-
Some(cmp::min(last_index, self.tree.len() - 1))
212207
}
213208

214209
fn selection_updown(
@@ -520,7 +515,7 @@ mod tests {
520515
res.update(&string_vec_to_status(&["a", "b"])).unwrap();
521516
res.selection = Some(1);
522517

523-
res.update(&string_vec_to_status(&["d", "c", "a"])).unwrap();
518+
res.update(&string_vec_to_status(&["a", "c", "d"])).unwrap();
524519
assert_eq!(res.selection, Some(1));
525520
}
526521

@@ -545,6 +540,33 @@ mod tests {
545540
assert_eq!(res.selection, Some(0));
546541
}
547542

543+
#[test]
544+
fn test_next_when_dir_disappears() {
545+
let mut tree = StatusTree::default();
546+
tree.update(&string_vec_to_status(&["a/b", "c", "d"]))
547+
.unwrap();
548+
tree.selection = Some(1);
549+
assert_eq!(
550+
tree.selected_item().unwrap().info.full_path,
551+
"a/b"
552+
);
553+
554+
tree.update(&string_vec_to_status(&["c", "d"])).unwrap();
555+
assert_eq!(tree.selected_item().unwrap().info.full_path, "c");
556+
}
557+
558+
#[test]
559+
fn test_next_when_last_dir_disappears() {
560+
let mut tree = StatusTree::default();
561+
tree.update(&string_vec_to_status(&["a", "b", "c"]))
562+
.unwrap();
563+
tree.selection = Some(2);
564+
assert_eq!(tree.selected_item().unwrap().info.full_path, "c");
565+
566+
tree.update(&string_vec_to_status(&["a", "b"])).unwrap();
567+
assert_eq!(tree.selected_item().unwrap().info.full_path, "b");
568+
}
569+
548570
#[test]
549571
fn test_keep_collapsed_states() {
550572
let mut res = StatusTree::default();

0 commit comments

Comments
 (0)