diff --git a/crates/terminal_view/src/persistence.rs b/crates/terminal_view/src/persistence.rs index 14606d4ed58054cca70ca16d420e90083bcbcc14..43f53c3a6516167129d367f29ab957640078b4f1 100644 --- a/crates/terminal_view/src/persistence.rs +++ b/crates/terminal_view/src/persistence.rs @@ -214,14 +214,6 @@ async fn deserialize_pane_group( } SerializedPaneGroup::Pane(serialized_pane) => { let active = serialized_pane.active; - let new_items = deserialize_terminal_views( - workspace_id, - project.clone(), - workspace.clone(), - serialized_pane.children.as_slice(), - cx, - ) - .await; let pane = panel .update_in(cx, |terminal_panel, window, cx| { @@ -236,56 +228,71 @@ async fn deserialize_pane_group( .log_err()?; let active_item = serialized_pane.active_item; let pinned_count = serialized_pane.pinned_count; - let terminal = pane - .update_in(cx, |pane, window, cx| { - populate_pane_items(pane, new_items, active_item, window, cx); - pane.set_pinned_count(pinned_count); + let new_items = deserialize_terminal_views( + workspace_id, + project.clone(), + workspace.clone(), + serialized_pane.children.as_slice(), + cx, + ); + cx.spawn({ + let pane = pane.downgrade(); + async move |cx| { + let new_items = new_items.await; + + let items = pane.update_in(cx, |pane, window, cx| { + populate_pane_items(pane, new_items, active_item, window, cx); + pane.set_pinned_count(pinned_count); + pane.items_len() + }); // Avoid blank panes in splits - if pane.items_len() == 0 { + if items.is_ok_and(|items| items == 0) { let working_directory = workspace .update(cx, |workspace, cx| default_working_directory(workspace, cx)) .ok() .flatten(); - let terminal = project.update(cx, |project, cx| { - project.create_terminal_shell(working_directory, cx) - }); - Some(Some(terminal)) - } else { - Some(None) + let Some(terminal) = project + .update(cx, |project, cx| { + project.create_terminal_shell(working_directory, cx) + }) + .log_err() + else { + return; + }; + + let terminal = terminal.await.log_err(); + pane.update_in(cx, |pane, window, cx| { + if let Some(terminal) = terminal { + let terminal_view = Box::new(cx.new(|cx| { + TerminalView::new( + terminal, + workspace.clone(), + Some(workspace_id), + project.downgrade(), + window, + cx, + ) + })); + pane.add_item(terminal_view, true, false, None, window, cx); + } + }) + .ok(); } - }) - .ok() - .flatten()?; - if let Some(terminal) = terminal { - let terminal = terminal.await.ok()?; - pane.update_in(cx, |pane, window, cx| { - let terminal_view = Box::new(cx.new(|cx| { - TerminalView::new( - terminal, - workspace.clone(), - Some(workspace_id), - project.downgrade(), - window, - cx, - ) - })); - pane.add_item(terminal_view, true, false, None, window, cx); - }) - .ok()?; - } + } + }) + .detach(); Some((Member::Pane(pane.clone()), active.then_some(pane))) } } } -async fn deserialize_terminal_views( +fn deserialize_terminal_views( workspace_id: WorkspaceId, project: Entity, workspace: WeakEntity, item_ids: &[u64], cx: &mut AsyncWindowContext, -) -> Vec> { - let mut items = Vec::with_capacity(item_ids.len()); +) -> impl Future>> + use<> { let mut deserialized_items = item_ids .iter() .map(|item_id| { @@ -302,12 +309,15 @@ async fn deserialize_terminal_views( .unwrap_or_else(|e| Task::ready(Err(e.context("no window present")))) }) .collect::>(); - while let Some(item) = deserialized_items.next().await { - if let Some(item) = item.log_err() { - items.push(item); + async move { + let mut items = Vec::with_capacity(deserialized_items.len()); + while let Some(item) = deserialized_items.next().await { + if let Some(item) = item.log_err() { + items.push(item); + } } + items } - items } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index b3d2a920c5b75125059b7d08b100cf95ff23ef3d..62cf52de19469f7087c42f91363bc9002312fe1f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -3461,28 +3461,31 @@ mod tests { // Open the same newly-created file in another pane item. The new editor should reuse // the same buffer. cx.dispatch_action(window.into(), NewFile); - let (task1, task2) = window + window .update(cx, |workspace, window, cx| { - ( - workspace.split_and_clone( - workspace.active_pane().clone(), - SplitDirection::Right, - window, - cx, - ), - workspace.open_path( - (worktree.read(cx).id(), rel_path("the-new-name.rs")), - None, - true, - window, - cx, - ), + workspace.split_and_clone( + workspace.active_pane().clone(), + SplitDirection::Right, + window, + cx, ) }) + .unwrap() + .await + .unwrap(); + window + .update(cx, |workspace, window, cx| { + workspace.open_path( + (worktree.read(cx).id(), rel_path("the-new-name.rs")), + None, + true, + window, + cx, + ) + }) + .unwrap() + .await .unwrap(); - task1.await.unwrap(); - task2.await.unwrap(); - cx.run_until_parked(); let editor2 = window .update(cx, |workspace, _, cx| { workspace