From 044f47c84883dd2af1f508acbf1e4a6c6cd14506 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 21 Oct 2025 15:10:21 +0200 Subject: [PATCH] Persistence --- crates/terminal_view/src/persistence.rs | 102 +++++++++++++----------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/crates/terminal_view/src/persistence.rs b/crates/terminal_view/src/persistence.rs index 14606d4ed58054cca70ca16d420e90083bcbcc14..8d6ef03fd714e6694aca12f3fe6a3a8bb166e84c 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()?; - } + } + }) + .await; 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)]