@@ -653,6 +653,16 @@ impl<Tab> Tree<Tab> {
653653 level += 1 ;
654654 }
655655 }
656+ // Ensure that there are no trailing `Node::Empty` items
657+ while let Some ( last_index) = self . nodes . len ( ) . checked_sub ( 1 ) . map ( NodeIndex ) {
658+ if self [ last_index] . is_empty ( )
659+ && last_index. parent ( ) . is_some_and ( |pi| !self [ pi] . is_parent ( ) )
660+ {
661+ self . nodes . pop ( ) ;
662+ } else {
663+ break ;
664+ }
665+ }
656666 }
657667
658668 /// Pushes a tab to the first `Leaf` it finds or create a new leaf if an `Empty` node is encountered.
@@ -833,7 +843,10 @@ impl<Tab> Tree<Tab> {
833843 fn balance ( & mut self , emptied_nodes : HashSet < NodeIndex > ) {
834844 let mut emptied_parents = HashSet :: default ( ) ;
835845 for parent_index in emptied_nodes. into_iter ( ) . filter_map ( |ni| ni. parent ( ) ) {
836- if self [ parent_index. left ( ) ] . is_empty ( ) && self [ parent_index. right ( ) ] . is_empty ( ) {
846+ if !self [ parent_index] . is_parent ( ) {
847+ continue ;
848+ } else if self [ parent_index. left ( ) ] . is_empty ( ) && self [ parent_index. right ( ) ] . is_empty ( )
849+ {
837850 self [ parent_index] = Node :: Empty ;
838851 emptied_parents. insert ( parent_index) ;
839852 } else if self [ parent_index. left ( ) ] . is_empty ( ) {
@@ -938,3 +951,39 @@ where
938951 self . find_tab_from ( |tab| tab == needle_tab)
939952 }
940953}
954+
955+ #[ cfg( test) ]
956+ mod test {
957+ use super :: * ;
958+
959+ #[ derive( Copy , Clone , Debug , PartialEq ) ]
960+ struct Tab ( u64 ) ;
961+
962+ /// Checks that `retain` works after removing a node
963+ #[ test]
964+ fn remove_and_retain ( ) {
965+ let mut tree: Tree < Tab > = Tree :: new ( vec ! [ ] ) ;
966+ tree. push_to_focused_leaf ( Tab ( 0 ) ) ;
967+ let ( n0, _t0) = tree. find_tab ( & Tab ( 0 ) ) . unwrap ( ) ;
968+ tree. split_below ( n0, 0.5 , vec ! [ Tab ( 1 ) ] ) ;
969+
970+ let i1 = tree. find_tab ( & Tab ( 1 ) ) . unwrap ( ) ;
971+ tree. remove_tab ( i1) ;
972+ assert_eq ! ( tree. nodes. len( ) , 1 ) ;
973+
974+ tree. retain_tabs ( |_| true ) ;
975+ assert ! ( tree. find_tab( & Tab ( 0 ) ) . is_some( ) ) ;
976+ }
977+
978+ /// Tests whether `retain_tabs` works correctly with trailing `Empty` nodes
979+ #[ test]
980+ fn retain_trailing_empty ( ) {
981+ let mut tree: Tree < Tab > = Tree :: new ( vec ! [ ] ) ;
982+ tree. push_to_focused_leaf ( Tab ( 0 ) ) ;
983+ tree. nodes . push ( Node :: Empty ) ;
984+ tree. nodes . push ( Node :: Empty ) ;
985+
986+ tree. retain_tabs ( |_| true ) ;
987+ assert ! ( tree. find_tab( & Tab ( 0 ) ) . is_some( ) ) ;
988+ }
989+ }
0 commit comments