chore: initial attempt

dino created

Change summary

crates/project/src/project.rs             |  1 
crates/project/src/worktree_store.rs      |  2 +
crates/project_panel/src/project_panel.rs |  5 +++
crates/proto/proto/worktree.proto         |  8 ++++++
crates/worktree/src/worktree.rs           | 32 +++++++++++++++++-------
5 files changed, 38 insertions(+), 10 deletions(-)

Detailed changes

crates/project/src/project.rs 🔗

@@ -2578,6 +2578,7 @@ impl Project {
         trash: bool,
         cx: &mut Context<Self>,
     ) -> Option<Task<Result<Option<TrashedEntry>>>> {
+        dbg!("Project::delete_entry");
         let worktree = self.worktree_for_entry(entry_id, cx)?;
         cx.emit(Event::DeletedEntry(worktree.read(cx).id(), entry_id));
         worktree.update(cx, |worktree, cx| {

crates/project/src/worktree_store.rs 🔗

@@ -1158,6 +1158,7 @@ impl WorktreeStore {
         Ok(proto::ProjectEntryResponse {
             entry: entry.as_ref().map(|entry| entry.into()),
             worktree_scan_id: scan_id as u64,
+            trashed_entry: None,
         })
     }
 
@@ -1221,6 +1222,7 @@ impl WorktreeStore {
                 CreatedEntry::Excluded { .. } => None,
             },
             worktree_scan_id: scan_id as u64,
+            trashed_entry: None,
         })
     }
 

crates/project_panel/src/project_panel.rs 🔗

@@ -1208,7 +1208,8 @@ impl ProjectPanel {
                             .when(!should_hide_rename, |menu| {
                                 menu.separator().action("Rename", Box::new(Rename))
                             })
-                            .when(!is_root && !is_remote, |menu| {
+                            // .when(!is_root && !is_remote, |menu| {
+                            .when(!is_root, |menu| {
                                 menu.action("Trash", Box::new(Trash { skip_prompt: false }))
                             })
                             .when(!is_root, |menu| {
@@ -2213,10 +2214,12 @@ impl ProjectPanel {
     }
 
     fn trash(&mut self, action: &Trash, window: &mut Window, cx: &mut Context<Self>) {
+        dbg!("ProjectPanel::trash");
         self.remove(true, action.skip_prompt, window, cx);
     }
 
     fn delete(&mut self, action: &Delete, window: &mut Window, cx: &mut Context<Self>) {
+        dbg!("ProjectPanel::delete");
         self.remove(false, action.skip_prompt, window, cx);
     }
 

crates/proto/proto/worktree.proto 🔗

@@ -140,6 +140,14 @@ message ExpandAllForProjectEntryResponse {
 message ProjectEntryResponse {
   optional Entry entry = 1;
   uint64 worktree_scan_id = 2;
+  // TODO!(dino): new message for delete?
+  optional TrashedEntry trashed_entry = 3;
+}
+
+message TrashedEntry {
+  string trash_id = 1;
+  string file_name = 2;
+  string original_parent_path = 3;
 }
 
 message UpdateWorktreeSettings {

crates/worktree/src/worktree.rs 🔗

@@ -851,8 +851,14 @@ impl Worktree {
         cx: &mut Context<Worktree>,
     ) -> Option<Task<Result<Option<TrashedEntry>>>> {
         let task = match self {
-            Worktree::Local(this) => this.delete_entry(entry_id, trash, cx),
-            Worktree::Remote(this) => this.delete_entry(entry_id, trash, cx),
+            Worktree::Local(this) => {
+                dbg!(("LOCAL", trash));
+                this.delete_entry(entry_id, trash, cx)
+            }
+            Worktree::Remote(this) => {
+                dbg!(("REMOTE", trash));
+                this.delete_entry(entry_id, trash, cx)
+            }
         }?;
 
         let entry = match &*self {
@@ -994,6 +1000,7 @@ impl Worktree {
                 CreatedEntry::Excluded { .. } => None,
             },
             worktree_scan_id: scan_id as u64,
+            trashed_entry: None,
         })
     }
 
@@ -1012,11 +1019,17 @@ impl Worktree {
                 ),
             )
         });
-        task.ok_or_else(|| anyhow::anyhow!("invalid entry"))?
+        let trashed_entry = task
+            .ok_or_else(|| anyhow::anyhow!("invalid entry"))?
             .await?;
         Ok(proto::ProjectEntryResponse {
             entry: None,
             worktree_scan_id: scan_id as u64,
+            trashed_entry: trashed_entry.map(|e| proto::TrashedEntry {
+                trash_id: e.id.to_string_lossy().to_string(),
+                file_name: e.name.to_string_lossy().to_string(),
+                original_parent_path: e.original_parent.to_string_lossy().to_string(),
+            }),
         })
     }
 
@@ -2156,6 +2169,7 @@ impl RemoteWorktree {
         Some(cx.spawn(async move |this, cx| {
             let response = response.await?;
             let scan_id = response.worktree_scan_id as usize;
+            let trashed_entry = response.trashed_entry;
 
             this.update(cx, move |this, _| {
                 this.as_remote_mut().unwrap().wait_for_snapshot(scan_id)
@@ -2167,13 +2181,13 @@ impl RemoteWorktree {
                 let snapshot = &mut this.background_snapshot.lock().0;
                 snapshot.delete_entry(entry_id);
                 this.snapshot = snapshot.clone();
+            })?;
 
-                // TODO: How can we actually track the deleted entry when
-                // working in remote? We likely only need to keep this
-                // information on the remote side in order to support restoring
-                // the trashed file.
-                None
-            })
+            Ok(trashed_entry.map(|e| TrashedEntry {
+                id: e.trash_id.into(),
+                name: e.file_name.into(),
+                original_parent: e.original_parent_path.into(),
+            }))
         }))
     }