ssh remoting: Restore items/buffers when opening SSH project (#18083)

Thorsten Ball and Bennet created

Demo:


https://github.com/user-attachments/assets/ab79ed0d-13a6-4ae7-8e76-6365fc322ec4



Release Notes:

- N/A

Co-authored-by: Bennet <bennet@zed.dev>

Change summary

crates/editor/src/items.rs        |  8 ++++++--
crates/workspace/src/workspace.rs | 27 +++++++++++++++++----------
2 files changed, 23 insertions(+), 12 deletions(-)

Detailed changes

crates/editor/src/items.rs 🔗

@@ -1087,10 +1087,14 @@ impl SerializableItem for Editor {
         let workspace_id = workspace.database_id()?;
 
         let buffer = self.buffer().read(cx).as_singleton()?;
+        let path = buffer
+            .read(cx)
+            .file()
+            .map(|file| file.full_path(cx))
+            .and_then(|full_path| project.read(cx).find_project_path(&full_path, cx))
+            .and_then(|project_path| project.read(cx).absolute_path(&project_path, cx));
 
         let is_dirty = buffer.read(cx).is_dirty();
-        let local_file = buffer.read(cx).file().and_then(|file| file.as_local());
-        let path = local_file.map(|file| file.abs_path(cx));
         let mtime = buffer.read(cx).saved_mtime();
 
         let snapshot = buffer.read(cx).snapshot();

crates/workspace/src/workspace.rs 🔗

@@ -1114,18 +1114,16 @@ impl Workspace {
             }
 
             // Get project paths for all of the abs_paths
-            let mut worktree_roots: HashSet<Arc<Path>> = Default::default();
             let mut project_paths: Vec<(PathBuf, Option<ProjectPath>)> =
                 Vec::with_capacity(paths_to_open.len());
             for path in paths_to_open.into_iter() {
-                if let Some((worktree, project_entry)) = cx
+                if let Some((_, project_entry)) = cx
                     .update(|cx| {
                         Workspace::project_path_for_path(project_handle.clone(), &path, true, cx)
                     })?
                     .await
                     .log_err()
                 {
-                    worktree_roots.extend(worktree.update(&mut cx, |tree, _| tree.abs_path()).ok());
                     project_paths.push((path, Some(project_entry)));
                 } else {
                     project_paths.push((path, None));
@@ -5532,12 +5530,13 @@ pub fn open_ssh_project(
         let serialized_workspace =
             persistence::DB.workspace_for_ssh_project(&serialized_ssh_project);
 
-        let workspace_id =
-            if let Some(workspace_id) = serialized_workspace.map(|workspace| workspace.id) {
-                workspace_id
-            } else {
-                persistence::DB.next_id().await?
-            };
+        let workspace_id = if let Some(workspace_id) =
+            serialized_workspace.as_ref().map(|workspace| workspace.id)
+        {
+            workspace_id
+        } else {
+            persistence::DB.next_id().await?
+        };
 
         cx.update_window(window.into(), |_, cx| {
             cx.replace_root_view(|cx| {
@@ -5548,7 +5547,15 @@ pub fn open_ssh_project(
             });
         })?;
 
-        window.update(&mut cx, |_, cx| cx.activate_window())
+        window
+            .update(&mut cx, |_, cx| {
+                cx.activate_window();
+
+                open_items(serialized_workspace, vec![], app_state, cx)
+            })?
+            .await?;
+
+        Ok(())
     })
 }