@@ -95,7 +95,7 @@ fn closed_pane_scrollback_bytes(records: &[ClosedPaneRecord]) -> usize {
9595
9696fn capture_closed_pane_record (
9797 pane : & gpui:: Entity < crate :: pane:: Pane > ,
98- workspace_idx : usize ,
98+ workspace_id : u64 ,
9999 cx : & App ,
100100) -> Option < ClosedPaneRecord > {
101101 let pane_ref = pane. read ( cx) ;
@@ -130,10 +130,18 @@ fn capture_closed_pane_record(
130130 Some ( ClosedPaneRecord {
131131 tabs,
132132 selected_idx : pane_ref. selected_idx ,
133- workspace_idx ,
133+ workspace_id ,
134134 } )
135135}
136136
137+ /// Locate the workspace a closed-pane record should restore into.
138+ ///
139+ /// Indexes shift when workspaces close or reorder; the record stores a
140+ /// stable `Workspace.id`. `None` means that workspace is gone.
141+ fn workspace_index_for_undo ( ids : & [ u64 ] , record_id : u64 ) -> Option < usize > {
142+ ids. iter ( ) . position ( |& id| id == record_id)
143+ }
144+
137145/// After `workspaces.remove(removed_idx)`, map the previous `active_idx` onto
138146/// the remaining `len` slots. Closing a workspace before the active one
139147/// decrements; closing at or past the new last index clamps; an empty list is 0.
@@ -496,17 +504,17 @@ impl PaneFlowApp {
496504 ) {
497505 // Capture state of the pane being closed for undo (US-014).
498506 // Must happen BEFORE the tree mutation that drops the pane entity.
499- let workspace_idx = self . active_idx ;
500507 if let Some ( ws) = self . active_workspace ( )
501508 && let Some ( root) = & ws. root
502509 {
510+ let workspace_id = ws. id ;
503511 let closing_pane = if ws. is_zoomed ( ) {
504512 root. first_leaf ( )
505513 } else {
506514 root. focused_pane ( window, cx)
507515 } ;
508516 if let Some ( pane) = closing_pane
509- && let Some ( record) = capture_closed_pane_record ( & pane, workspace_idx , cx)
517+ && let Some ( record) = capture_closed_pane_record ( & pane, workspace_id , cx)
510518 {
511519 push_closed_pane_record ( & mut self . closed_panes , record) ;
512520 }
@@ -575,16 +583,15 @@ impl PaneFlowApp {
575583 return ; // No closed panes to restore
576584 } ;
577585
578- // Switch to the workspace where the pane was closed, if it still exists
579- if record. workspace_idx < self . workspaces . len ( ) {
580- self . active_idx = record. workspace_idx ;
581- }
582-
583- let Some ( ws_id) = self . active_workspace ( ) . map ( |ws| ws. id ) else {
584- self . closed_panes . push ( record) ;
585- self . show_toast ( "No active workspace to restore pane" , cx) ;
586+ // Restore into the workspace the pane was closed in. Indexes shift
587+ // on close/reorder; the record stores a stable Workspace.id.
588+ let ids: Vec < u64 > = self . workspaces . iter ( ) . map ( |ws| ws. id ) . collect ( ) ;
589+ let Some ( idx) = workspace_index_for_undo ( & ids, record. workspace_id ) else {
590+ self . show_toast ( "Workspace no longer exists" , cx) ;
586591 return ;
587592 } ;
593+ self . active_idx = idx;
594+ let ws_id = record. workspace_id ;
588595 let selected_idx = record. selected_idx ;
589596 let tabs = record
590597 . tabs
@@ -1162,10 +1169,24 @@ mod tests {
11621169 font_size: None ,
11631170 } ] ,
11641171 selected_idx : 0 ,
1165- workspace_idx : 0 ,
1172+ workspace_id : 0 ,
11661173 }
11671174 }
11681175
1176+ #[ test]
1177+ fn workspace_index_for_undo_matches_after_lower_workspace_closed ( ) {
1178+ // Originally [10, 20, 30]; workspace 10 (index 0) closed → [20, 30].
1179+ // A pane closed in workspace 20 was index 1; it is now index 0.
1180+ assert_eq ! ( workspace_index_for_undo( & [ 20 , 30 ] , 20 ) , Some ( 0 ) ) ;
1181+ assert_eq ! ( workspace_index_for_undo( & [ 20 , 30 ] , 30 ) , Some ( 1 ) ) ;
1182+ }
1183+
1184+ #[ test]
1185+ fn workspace_index_for_undo_missing_id_returns_none ( ) {
1186+ assert_eq ! ( workspace_index_for_undo( & [ 20 , 30 ] , 10 ) , None ) ;
1187+ assert_eq ! ( workspace_index_for_undo( & [ ] , 1 ) , None ) ;
1188+ }
1189+
11691190 #[ test]
11701191 fn closed_pane_budget_drops_oldest_scrollback_not_record ( ) {
11711192 let one_mib = 1024 * 1024 ;
@@ -1268,7 +1289,7 @@ mod tests {
12681289 font_size: None ,
12691290 } ] ,
12701291 selected_idx : 0 ,
1271- workspace_idx : 0 ,
1292+ workspace_id : 0 ,
12721293 } ,
12731294 ) ;
12741295
0 commit comments