diff --git a/src/components/utils/filetree.rs b/src/components/utils/filetree.rs index 079f826c..9120ddbf 100644 --- a/src/components/utils/filetree.rs +++ b/src/components/utils/filetree.rs @@ -185,6 +185,20 @@ impl FileTreeItems { self.file_count } + /// + pub(crate) fn find_parent_index(&self, index: usize) -> usize { + let item_indent = &self.items[index].info.indent; + let mut parent_index = index; + while item_indent <= &self.items[parent_index].info.indent { + if parent_index == 0 { + return 0; + } + parent_index -= 1; + } + + parent_index + } + fn push_dirs<'a>( item_path: &'a Path, nodes: &mut Vec, @@ -397,4 +411,23 @@ mod tests { assert_eq!(res.multiple_items_at_path(1), false); assert_eq!(res.multiple_items_at_path(2), true); } + + #[test] + fn test_find_parent() { + //0 a/ + //1 b/ + //2 c + //3 d + + let res = FileTreeItems::new( + &string_vec_to_status(&[ + "a/b/c", // + "a/b/d", // + ]), + &BTreeSet::new(), + ) + .unwrap(); + + assert_eq!(res.find_parent_index(3), 1); + } } diff --git a/src/components/utils/statustree.rs b/src/components/utils/statustree.rs index 990f4f87..61f2f9bc 100644 --- a/src/components/utils/statustree.rs +++ b/src/components/utils/statustree.rs @@ -324,7 +324,14 @@ impl StatusTree { || matches!(item_kind,FileTreeItemKind::Path(PathCollapsed(collapsed)) if collapsed) { - self.selection_updown(current_selection, true) + let mut cur_parent = + self.tree.find_parent_index(current_selection); + while !self.available_selections.contains(&cur_parent) + && cur_parent != 0 + { + cur_parent = self.tree.find_parent_index(cur_parent); + } + SelectionChange::new(cur_parent, false) } else if matches!(item_kind, FileTreeItemKind::Path(PathCollapsed(collapsed)) if !collapsed) { @@ -889,11 +896,8 @@ mod tests { assert!(res.move_selection(MoveSelection::Left)); // folds 7 assert_eq!(res.selection, Some(7)); - assert!(res.move_selection(MoveSelection::Left)); // move to 4 - assert_eq!(res.selection, Some(4)); - assert!(res.move_selection(MoveSelection::Left)); // move to 1 - assert_eq!(res.selection, Some(1)); - assert!(res.move_selection(MoveSelection::Left)); // move to 0 + + assert!(res.move_selection(MoveSelection::Left)); // jump to 0 assert_eq!(res.selection, Some(0)); } }