Revert "Replace `project_path` with `project_entry` in `workspace::{Item, ItemView}`"

Nathan Sobo created

This reverts commit 9c9a09cccb41c4ea2a3d06b32170876e77946ba1.

Change summary

crates/diagnostics/src/diagnostics.rs |  4 
crates/editor/src/items.rs            | 25 ++++++----
crates/project/src/project.rs         |  8 ---
crates/project/src/worktree.rs        |  9 ---
crates/workspace/src/pane.rs          | 30 ++++++------
crates/workspace/src/workspace.rs     | 50 +++++++--------------
crates/zed/src/zed.rs                 | 67 +++++++---------------------
7 files changed, 67 insertions(+), 126 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -539,7 +539,7 @@ impl workspace::Item for ProjectDiagnostics {
         diagnostics
     }
 
-    fn project_entry(&self) -> Option<project::ProjectEntry> {
+    fn project_path(&self) -> Option<project::ProjectPath> {
         None
     }
 }
@@ -555,7 +555,7 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
         "Project Diagnostics".to_string()
     }
 
-    fn project_entry(&self, _: &AppContext) -> Option<project::ProjectEntry> {
+    fn project_path(&self, _: &AppContext) -> Option<project::ProjectPath> {
         None
     }
 

crates/editor/src/items.rs 🔗

@@ -4,13 +4,12 @@ use gpui::{
     elements::*, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, RenderContext,
     Subscription, Task, View, ViewContext, ViewHandle, WeakModelHandle,
 };
-use language::{Bias, Buffer, Diagnostic};
+use language::{Bias, Buffer, Diagnostic, File as _};
 use postage::watch;
-use project::worktree::File;
-use project::{Project, ProjectEntry, ProjectPath};
-use std::cell::RefCell;
+use project::{File, Project, ProjectPath};
+use std::path::PathBuf;
 use std::rc::Rc;
-use std::{fmt::Write, path::PathBuf};
+use std::{cell::RefCell, fmt::Write};
 use text::{Point, Selection};
 use util::TryFutureExt;
 use workspace::{
@@ -75,8 +74,11 @@ impl ItemHandle for BufferItemHandle {
         Box::new(WeakBufferItemHandle(self.0.downgrade()))
     }
 
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        File::from_dyn(self.0.read(cx).file()).and_then(|f| f.project_entry(cx))
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
+        File::from_dyn(self.0.read(cx).file()).map(|f| ProjectPath {
+            worktree_id: f.worktree_id(cx),
+            path: f.path().clone(),
+        })
     }
 
     fn id(&self) -> usize {
@@ -132,8 +134,11 @@ impl ItemView for Editor {
         }
     }
 
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        File::from_dyn(self.buffer().read(cx).file(cx)).and_then(|file| file.project_entry(cx))
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
+        File::from_dyn(self.buffer().read(cx).file(cx)).map(|file| ProjectPath {
+            worktree_id: file.worktree_id(cx),
+            path: file.path().clone(),
+        })
     }
 
     fn clone_on_split(&self, cx: &mut ViewContext<Self>) -> Option<Self>
@@ -158,7 +163,7 @@ impl ItemView for Editor {
     }
 
     fn can_save(&self, cx: &AppContext) -> bool {
-        self.project_entry(cx).is_some()
+        self.project_path(cx).is_some()
     }
 
     fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {

crates/project/src/project.rs 🔗

@@ -959,14 +959,6 @@ impl Project {
         }
     }
 
-    pub fn path_for_entry(&self, entry: ProjectEntry, cx: &AppContext) -> Option<ProjectPath> {
-        let worktree = self.worktree_for_id(entry.worktree_id, cx)?.read(cx);
-        Some(ProjectPath {
-            worktree_id: entry.worktree_id,
-            path: worktree.entry_for_id(entry.entry_id)?.path.clone(),
-        })
-    }
-
     pub fn is_running_disk_based_diagnostics(&self) -> bool {
         self.language_servers_with_diagnostics_running > 0
     }

crates/project/src/worktree.rs 🔗

@@ -1,7 +1,7 @@
 use super::{
     fs::{self, Fs},
     ignore::IgnoreStack,
-    DiagnosticSummary, ProjectEntry,
+    DiagnosticSummary,
 };
 use ::ignore::gitignore::{Gitignore, GitignoreBuilder};
 use anyhow::{anyhow, Result};
@@ -2202,13 +2202,6 @@ impl File {
     pub fn worktree_id(&self, cx: &AppContext) -> WorktreeId {
         self.worktree.read(cx).id()
     }
-
-    pub fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        self.entry_id.map(|entry_id| ProjectEntry {
-            worktree_id: self.worktree_id(cx),
-            entry_id,
-        })
-    }
 }
 
 #[derive(Clone, Debug)]

crates/workspace/src/pane.rs 🔗

@@ -10,7 +10,7 @@ use gpui::{
     Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, ViewHandle,
 };
 use postage::watch;
-use project::ProjectEntry;
+use project::ProjectPath;
 use std::{any::Any, cell::RefCell, cmp, mem, rc::Rc};
 use util::ResultExt;
 
@@ -89,7 +89,7 @@ pub struct NavHistory {
     mode: NavigationMode,
     backward_stack: VecDeque<NavigationEntry>,
     forward_stack: VecDeque<NavigationEntry>,
-    project_entries_by_item: HashMap<usize, ProjectEntry>,
+    paths_by_item: HashMap<usize, ProjectPath>,
 }
 
 #[derive(Copy, Clone)]
@@ -150,10 +150,10 @@ impl Pane {
     ) -> Task<()> {
         let to_load = pane.update(cx, |pane, cx| {
             // Retrieve the weak item handle from the history.
-            let nav_entry = pane.nav_history.borrow_mut().pop(mode)?;
+            let entry = pane.nav_history.borrow_mut().pop(mode)?;
 
             // If the item is still present in this pane, then activate it.
-            if let Some(index) = nav_entry
+            if let Some(index) = entry
                 .item_view
                 .upgrade(cx)
                 .and_then(|v| pane.index_for_item_view(v.as_ref()))
@@ -168,7 +168,7 @@ impl Pane {
 
                 pane.active_item_index = index;
                 pane.focus_active_item(cx);
-                if let Some(data) = nav_entry.data {
+                if let Some(data) = entry.data {
                     pane.active_item()?.navigate(data, cx);
                 }
                 cx.notify();
@@ -179,17 +179,17 @@ impl Pane {
             else {
                 pane.nav_history
                     .borrow_mut()
-                    .project_entries_by_item
-                    .get(&nav_entry.item_view.id())
+                    .paths_by_item
+                    .get(&entry.item_view.id())
                     .cloned()
-                    .map(|project_entry| (project_entry, nav_entry))
+                    .map(|project_path| (project_path, entry))
             }
         });
 
-        if let Some((project_entry, nav_entry)) = to_load {
+        if let Some((project_path, entry)) = to_load {
             // If the item was no longer present, then load it again from its previous path.
             let pane = pane.downgrade();
-            let task = workspace.load_entry(project_entry, cx);
+            let task = workspace.load_path(project_path, cx);
             cx.spawn(|workspace, mut cx| async move {
                 let item = task.await;
                 if let Some(pane) = cx.read(|cx| pane.upgrade(cx)) {
@@ -201,7 +201,7 @@ impl Pane {
                                 p.nav_history.borrow_mut().set_mode(NavigationMode::Normal)
                             });
 
-                            if let Some(data) = nav_entry.data {
+                            if let Some(data) = entry.data {
                                 item_view.navigate(data, cx);
                             }
                         });
@@ -328,12 +328,10 @@ impl Pane {
                 }
 
                 let mut nav_history = self.nav_history.borrow_mut();
-                if let Some(entry) = item_view.project_entry(cx) {
-                    nav_history
-                        .project_entries_by_item
-                        .insert(item_view.id(), entry);
+                if let Some(path) = item_view.project_path(cx) {
+                    nav_history.paths_by_item.insert(item_view.id(), path);
                 } else {
-                    nav_history.project_entries_by_item.remove(&item_view.id());
+                    nav_history.paths_by_item.remove(&item_view.id());
                 }
 
                 item_ix += 1;

crates/workspace/src/workspace.rs 🔗

@@ -27,7 +27,7 @@ pub use pane::*;
 pub use pane_group::*;
 use parking_lot::Mutex;
 use postage::{prelude::Stream, watch};
-use project::{fs, Fs, Project, ProjectEntry, ProjectPath, Worktree};
+use project::{fs, Fs, Project, ProjectPath, Worktree};
 pub use settings::Settings;
 use sidebar::{Side, Sidebar, SidebarItemId, ToggleSidebarItem, ToggleSidebarItemFocus};
 use status_bar::StatusBar;
@@ -145,7 +145,8 @@ pub trait Item: Entity + Sized {
         nav_history: ItemNavHistory,
         cx: &mut ViewContext<Self::View>,
     ) -> Self::View;
-    fn project_entry(&self) -> Option<ProjectEntry>;
+
+    fn project_path(&self) -> Option<ProjectPath>;
 }
 
 pub trait ItemView: View {
@@ -155,7 +156,7 @@ pub trait ItemView: View {
     fn navigate(&mut self, _: Box<dyn Any>, _: &mut ViewContext<Self>) {}
     fn item_handle(&self, cx: &AppContext) -> Self::ItemHandle;
     fn title(&self, cx: &AppContext) -> String;
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry>;
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
     fn clone_on_split(&self, _: &mut ViewContext<Self>) -> Option<Self>
     where
         Self: Sized,
@@ -212,7 +213,7 @@ pub trait ItemHandle: Send + Sync {
     fn boxed_clone(&self) -> Box<dyn ItemHandle>;
     fn downgrade(&self) -> Box<dyn WeakItemHandle>;
     fn to_any(&self) -> AnyModelHandle;
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry>;
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
 }
 
 pub trait WeakItemHandle {
@@ -223,7 +224,7 @@ pub trait WeakItemHandle {
 pub trait ItemViewHandle: 'static {
     fn item_handle(&self, cx: &AppContext) -> Box<dyn ItemHandle>;
     fn title(&self, cx: &AppContext) -> String;
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry>;
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
     fn boxed_clone(&self) -> Box<dyn ItemViewHandle>;
     fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option<Box<dyn ItemViewHandle>>;
     fn added_to_pane(&mut self, cx: &mut ViewContext<Pane>);
@@ -280,8 +281,8 @@ impl<T: Item> ItemHandle for ModelHandle<T> {
         self.clone().into()
     }
 
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        self.read(cx).project_entry()
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
+        self.read(cx).project_path()
     }
 }
 
@@ -312,8 +313,8 @@ impl ItemHandle for Box<dyn ItemHandle> {
         self.as_ref().to_any()
     }
 
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        self.as_ref().project_entry(cx)
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
+        self.as_ref().project_path(cx)
     }
 }
 
@@ -361,8 +362,8 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
         self.read(cx).title(cx)
     }
 
-    fn project_entry(&self, cx: &AppContext) -> Option<ProjectEntry> {
-        self.read(cx).project_entry(cx)
+    fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
+        self.read(cx).project_path(cx)
     }
 
     fn boxed_clone(&self) -> Box<dyn ItemViewHandle> {
@@ -778,18 +779,6 @@ impl Workspace {
         })
     }
 
-    pub fn load_entry(
-        &mut self,
-        path: ProjectEntry,
-        cx: &mut ViewContext<Self>,
-    ) -> Task<Result<Box<dyn ItemHandle>>> {
-        if let Some(path) = self.project.read(cx).path_for_entry(path, cx) {
-            self.load_path(path, cx)
-        } else {
-            Task::ready(Err(anyhow!("entry does not exist")))
-        }
-    }
-
     pub fn load_path(
         &mut self,
         path: ProjectPath,
@@ -812,13 +801,10 @@ impl Workspace {
     }
 
     fn item_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option<Box<dyn ItemHandle>> {
-        let project = self.project.read(cx);
-        self.items.iter().filter_map(|i| i.upgrade(cx)).find(|i| {
-            let item_path = i
-                .project_entry(cx)
-                .and_then(|entry| project.path_for_entry(entry, cx));
-            item_path.as_ref() == Some(path)
-        })
+        self.items
+            .iter()
+            .filter_map(|i| i.upgrade(cx))
+            .find(|i| i.project_path(cx).as_ref() == Some(path))
     }
 
     pub fn item_of_type<T: Item>(&self, cx: &AppContext) -> Option<ModelHandle<T>> {
@@ -832,9 +818,7 @@ impl Workspace {
     }
 
     fn active_project_path(&self, cx: &ViewContext<Self>) -> Option<ProjectPath> {
-        self.active_item(cx)
-            .and_then(|item| item.project_entry(cx))
-            .and_then(|entry| self.project.read(cx).path_for_entry(entry, cx))
+        self.active_item(cx).and_then(|item| item.project_path(cx))
     }
 
     pub fn save_active_item(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {

crates/zed/src/zed.rs 🔗

@@ -263,11 +263,9 @@ mod tests {
             .await
             .unwrap();
         cx.read(|cx| {
-            let workspace = workspace.read(cx);
-            let pane = workspace.active_pane().read(cx);
-            let entry = pane.active_item().unwrap().project_entry(cx).unwrap();
+            let pane = workspace.read(cx).active_pane().read(cx);
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(entry, cx),
+                pane.active_item().unwrap().project_path(cx),
                 Some(file1.clone())
             );
             assert_eq!(pane.item_views().count(), 1);
@@ -279,11 +277,9 @@ mod tests {
             .await
             .unwrap();
         cx.read(|cx| {
-            let workspace = workspace.read(cx);
-            let pane = workspace.active_pane().read(cx);
-            let entry = pane.active_item().unwrap().project_entry(cx).unwrap();
+            let pane = workspace.read(cx).active_pane().read(cx);
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(entry, cx),
+                pane.active_item().unwrap().project_path(cx),
                 Some(file2.clone())
             );
             assert_eq!(pane.item_views().count(), 2);
@@ -297,11 +293,9 @@ mod tests {
         assert_eq!(entry_1.id(), entry_1b.id());
 
         cx.read(|cx| {
-            let workspace = workspace.read(cx);
-            let pane = workspace.active_pane().read(cx);
-            let entry = pane.active_item().unwrap().project_entry(cx).unwrap();
+            let pane = workspace.read(cx).active_pane().read(cx);
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(entry, cx),
+                pane.active_item().unwrap().project_path(cx),
                 Some(file1.clone())
             );
             assert_eq!(pane.item_views().count(), 2);
@@ -316,11 +310,13 @@ mod tests {
             .await
             .unwrap();
 
-        workspace.read_with(&cx, |workspace, cx| {
-            let pane = workspace.active_pane().read(cx);
-            let entry = pane.active_item().unwrap().project_entry(cx).unwrap();
+        workspace.read_with(&cx, |w, cx| {
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(entry, cx),
+                w.active_pane()
+                    .read(cx)
+                    .active_item()
+                    .unwrap()
+                    .project_path(cx.as_ref()),
                 Some(file2.clone())
             );
         });
@@ -335,22 +331,14 @@ mod tests {
         t1.await.unwrap();
         t2.await.unwrap();
         cx.read(|cx| {
-            let workspace = workspace.read(cx);
-            let pane = workspace.active_pane().read(cx);
-            let entry = pane.active_item().unwrap().project_entry(cx).unwrap();
+            let pane = workspace.read(cx).active_pane().read(cx);
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(entry, cx),
+                pane.active_item().unwrap().project_path(cx),
                 Some(file3.clone())
             );
             let pane_entries = pane
                 .item_views()
-                .map(|i| {
-                    workspace
-                        .project()
-                        .read(cx)
-                        .path_for_entry(i.project_entry(cx).unwrap(), cx)
-                        .unwrap()
-                })
+                .map(|i| i.project_path(cx).unwrap())
                 .collect::<Vec<_>>();
             assert_eq!(pane_entries, &[file1, file2, file3]);
         });
@@ -654,15 +642,8 @@ mod tests {
             .await
             .unwrap();
         cx.read(|cx| {
-            let workspace = workspace.read(cx);
-            let pane1_entry = pane_1
-                .read(cx)
-                .active_item()
-                .unwrap()
-                .project_entry(cx)
-                .unwrap();
             assert_eq!(
-                workspace.project().read(cx).path_for_entry(pane1_entry, cx),
+                pane_1.read(cx).active_item().unwrap().project_path(cx),
                 Some(file1.clone())
             );
         });
@@ -677,15 +658,7 @@ mod tests {
             assert_ne!(pane_1, pane_2);
 
             let pane2_item = pane_2.read(cx).active_item().unwrap();
-            let pane2_entry = pane2_item.project_entry(cx).unwrap();
-            assert_eq!(
-                workspace
-                    .read(cx)
-                    .project()
-                    .read(cx)
-                    .path_for_entry(pane2_entry, cx),
-                Some(file1.clone())
-            );
+            assert_eq!(pane2_item.project_path(cx.as_ref()), Some(file1.clone()));
 
             cx.dispatch_action(window_id, vec![pane_2.id()], &workspace::CloseActiveItem);
             let workspace = workspace.read(cx);
@@ -863,11 +836,7 @@ mod tests {
                 let item = workspace.active_item(cx).unwrap();
                 let editor = item.downcast::<Editor>().unwrap();
                 let selections = editor.update(cx, |editor, cx| editor.selected_display_ranges(cx));
-                let path = workspace
-                    .project()
-                    .read(cx)
-                    .path_for_entry(item.project_entry(cx).unwrap(), cx);
-                (path.unwrap(), selections[0].start)
+                (item.project_path(cx).unwrap(), selections[0].start)
             })
         }
     }