From 0036e5c86c39c89b1a560a1e2ffc744d38ad0e24 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 16 Mar 2022 15:59:47 -0600 Subject: [PATCH] Replace ProjectEntry struct with ProjectEntryId Previously, we tracked the worktree_id and entry_id separately, but now that entry ids are unique across all worktrees this is unnecessary. Co-Authored-By: Max Brunsfeld Co-Authored-By: Keith Simmons --- crates/diagnostics/src/diagnostics.rs | 2 +- crates/editor/src/editor.rs | 4 +- crates/editor/src/items.rs | 6 +- crates/project/src/project.rs | 61 +++++++++---- crates/project/src/worktree.rs | 51 +++++------ crates/project_panel/src/project_panel.rs | 106 +++++++++------------- crates/search/src/project_search.rs | 2 +- crates/workspace/src/pane.rs | 8 +- crates/workspace/src/workspace.rs | 12 +-- 9 files changed, 126 insertions(+), 126 deletions(-) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 1db19f7f5e..2b10adb202 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -449,7 +449,7 @@ impl workspace::ItemView for ProjectDiagnosticsEditor { None } - fn project_entry(&self, _: &AppContext) -> Option { + fn project_entry_id(&self, _: &AppContext) -> Option { None } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 6a29859195..704a2cf248 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -842,8 +842,8 @@ impl Editor { ) -> ViewHandle { let project = workspace.project().clone(); - if let Some(project_entry) = - project::File::from_dyn(buffer.read(cx).file()).and_then(|file| file.project_entry(cx)) + if let Some(project_entry) = project::File::from_dyn(buffer.read(cx).file()) + .and_then(|file| file.project_entry_id(cx)) { return workspace .open_item_for_project_entry(project_entry, cx, |cx| { diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index b84a095e6b..a9bac1908b 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -5,7 +5,7 @@ use gpui::{ View, ViewContext, ViewHandle, WeakModelHandle, }; use language::{Bias, Buffer, Diagnostic, File as _}; -use project::{File, Project, ProjectEntry, ProjectPath}; +use project::{File, Project, ProjectEntryId, ProjectPath}; use std::fmt::Write; use std::path::PathBuf; use text::{Point, Selection}; @@ -75,8 +75,8 @@ impl ItemView for Editor { }) } - fn project_entry(&self, cx: &AppContext) -> Option { - File::from_dyn(self.buffer().read(cx).file(cx)).and_then(|file| file.project_entry(cx)) + fn project_entry_id(&self, cx: &AppContext) -> Option { + File::from_dyn(self.buffer().read(cx).file(cx)).and_then(|file| file.project_entry_id(cx)) } fn clone_on_split(&self, cx: &mut ViewContext) -> Option diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index b9bb25a5fc..ae60ab825f 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -39,7 +39,7 @@ use std::{ path::{Component, Path, PathBuf}, rc::Rc, sync::{ - atomic::{AtomicBool, AtomicUsize}, + atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst}, Arc, }, time::Instant, @@ -51,7 +51,7 @@ pub use worktree::*; pub struct Project { worktrees: Vec, - active_entry: Option, + active_entry: Option, languages: Arc, language_servers: HashMap<(WorktreeId, Arc), Arc>, started_language_servers: HashMap<(WorktreeId, Arc), Task>>>, @@ -114,7 +114,7 @@ pub struct Collaborator { #[derive(Clone, Debug, PartialEq)] pub enum Event { - ActiveEntryChanged(Option), + ActiveEntryChanged(Option), WorktreeRemoved(WorktreeId), DiskBasedDiagnosticsStarted, DiskBasedDiagnosticsUpdated, @@ -226,10 +226,25 @@ impl DiagnosticSummary { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct ProjectEntry { - pub worktree_id: WorktreeId, - pub entry_id: usize, +#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ProjectEntryId(usize); + +impl ProjectEntryId { + pub fn new(counter: &AtomicUsize) -> Self { + Self(counter.fetch_add(1, SeqCst)) + } + + pub fn from_proto(id: u64) -> Self { + Self(id as usize) + } + + pub fn to_proto(&self) -> u64 { + self.0 as u64 + } + + pub fn to_usize(&self) -> usize { + self.0 + } } impl Project { @@ -623,6 +638,24 @@ impl Project { .find(|worktree| worktree.read(cx).id() == id) } + pub fn worktree_for_entry( + &self, + entry_id: ProjectEntryId, + cx: &AppContext, + ) -> Option> { + self.worktrees(cx) + .find(|worktree| worktree.read(cx).contains_entry(entry_id)) + } + + pub fn worktree_id_for_entry( + &self, + entry_id: ProjectEntryId, + cx: &AppContext, + ) -> Option { + self.worktree_for_entry(entry_id, cx) + .map(|worktree| worktree.read(cx).id()) + } + pub fn share(&self, cx: &mut ModelContext) -> Task> { let rpc = self.client.clone(); cx.spawn(|this, mut cx| async move { @@ -3163,10 +3196,7 @@ impl Project { let new_active_entry = entry.and_then(|project_path| { let worktree = self.worktree_for_id(project_path.worktree_id, cx)?; let entry = worktree.read(cx).entry_for_path(project_path.path)?; - Some(ProjectEntry { - worktree_id: project_path.worktree_id, - entry_id: entry.id, - }) + Some(entry.id) }); if new_active_entry != self.active_entry { self.active_entry = new_active_entry; @@ -3217,18 +3247,15 @@ impl Project { } } - pub fn active_entry(&self) -> Option { + pub fn active_entry(&self) -> Option { self.active_entry } - pub fn entry_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option { + pub fn entry_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option { self.worktree_for_id(path.worktree_id, cx)? .read(cx) .entry_for_path(&path.path) - .map(|entry| ProjectEntry { - worktree_id: path.worktree_id, - entry_id: entry.id, - }) + .map(|entry| entry.id) } // RPC message handlers diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 4a121c82e4..2bc9c3d234 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -1,4 +1,4 @@ -use crate::ProjectEntry; +use crate::ProjectEntryId; use super::{ fs::{self, Fs}, @@ -41,10 +41,7 @@ use std::{ future::Future, ops::{Deref, DerefMut}, path::{Path, PathBuf}, - sync::{ - atomic::{AtomicUsize, Ordering::SeqCst}, - Arc, - }, + sync::{atomic::AtomicUsize, Arc}, time::{Duration, SystemTime}, }; use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap}; @@ -103,7 +100,7 @@ pub struct LocalSnapshot { abs_path: Arc, scan_id: usize, ignores: HashMap, (Arc, usize)>, - removed_entry_ids: HashMap, + removed_entry_ids: HashMap, next_entry_id: Arc, snapshot: Snapshot, } @@ -858,13 +855,16 @@ impl Snapshot { self.id } + pub fn contains_entry(&self, entry_id: ProjectEntryId) -> bool { + self.entries_by_id.get(&entry_id, &()).is_some() + } + pub(crate) fn apply_remote_update(&mut self, update: proto::UpdateWorktree) -> Result<()> { let mut entries_by_path_edits = Vec::new(); let mut entries_by_id_edits = Vec::new(); for entry_id in update.removed_entries { - let entry_id = entry_id as usize; let entry = self - .entry_for_id(entry_id) + .entry_for_id(ProjectEntryId::from_proto(entry_id)) .ok_or_else(|| anyhow!("unknown entry"))?; entries_by_path_edits.push(Edit::Remove(PathKey(entry.path.clone()))); entries_by_id_edits.push(Edit::Remove(entry.id)); @@ -987,7 +987,7 @@ impl Snapshot { }) } - pub fn entry_for_id(&self, id: usize) -> Option<&Entry> { + pub fn entry_for_id(&self, id: ProjectEntryId) -> Option<&Entry> { let entry = self.entries_by_id.get(&id, &())?; self.entry_for_path(&entry.path) } @@ -1064,7 +1064,7 @@ impl LocalSnapshot { other_entries.next(); } Ordering::Greater => { - removed_entries.push(other_entry.id as u64); + removed_entries.push(other_entry.id.to_proto()); other_entries.next(); } } @@ -1075,7 +1075,7 @@ impl LocalSnapshot { self_entries.next(); } (None, Some(other_entry)) => { - removed_entries.push(other_entry.id as u64); + removed_entries.push(other_entry.id.to_proto()); other_entries.next(); } (None, None) => break, @@ -1328,7 +1328,7 @@ pub struct File { pub worktree: ModelHandle, pub path: Arc, pub mtime: SystemTime, - pub(crate) entry_id: Option, + pub(crate) entry_id: Option, pub(crate) is_local: bool, } @@ -1425,7 +1425,7 @@ impl language::File for File { fn to_proto(&self) -> rpc::proto::File { rpc::proto::File { worktree_id: self.worktree.id() as u64, - entry_id: self.entry_id.map(|entry_id| entry_id as u64), + entry_id: self.entry_id.map(|entry_id| entry_id.to_proto()), path: self.path.to_string_lossy().into(), mtime: Some(self.mtime.into()), } @@ -1492,7 +1492,7 @@ impl File { worktree, path: Path::new(&proto.path).into(), mtime: proto.mtime.ok_or_else(|| anyhow!("no timestamp"))?.into(), - entry_id: proto.entry_id.map(|entry_id| entry_id as usize), + entry_id: proto.entry_id.map(ProjectEntryId::from_proto), is_local: false, }) } @@ -1505,17 +1505,14 @@ impl File { self.worktree.read(cx).id() } - pub fn project_entry(&self, cx: &AppContext) -> Option { - self.entry_id.map(|entry_id| ProjectEntry { - worktree_id: self.worktree_id(cx), - entry_id, - }) + pub fn project_entry_id(&self, _: &AppContext) -> Option { + self.entry_id } } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Entry { - pub id: usize, + pub id: ProjectEntryId, pub kind: EntryKind, pub path: Arc, pub inode: u64, @@ -1539,7 +1536,7 @@ impl Entry { root_char_bag: CharBag, ) -> Self { Self { - id: next_entry_id.fetch_add(1, SeqCst), + id: ProjectEntryId::new(next_entry_id), kind: if metadata.is_dir { EntryKind::PendingDir } else { @@ -1629,7 +1626,7 @@ impl sum_tree::Summary for EntrySummary { #[derive(Clone, Debug)] struct PathEntry { - id: usize, + id: ProjectEntryId, path: Arc, is_ignored: bool, scan_id: usize, @@ -1644,7 +1641,7 @@ impl sum_tree::Item for PathEntry { } impl sum_tree::KeyedItem for PathEntry { - type Key = usize; + type Key = ProjectEntryId; fn key(&self) -> Self::Key { self.id @@ -1653,7 +1650,7 @@ impl sum_tree::KeyedItem for PathEntry { #[derive(Clone, Debug, Default)] struct PathEntrySummary { - max_id: usize, + max_id: ProjectEntryId, } impl sum_tree::Summary for PathEntrySummary { @@ -1664,7 +1661,7 @@ impl sum_tree::Summary for PathEntrySummary { } } -impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for usize { +impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId { fn add_summary(&mut self, summary: &'a PathEntrySummary, _: &()) { *self = summary.max_id; } @@ -2354,7 +2351,7 @@ impl<'a> Iterator for ChildEntriesIter<'a> { impl<'a> From<&'a Entry> for proto::Entry { fn from(entry: &'a Entry) -> Self { Self { - id: entry.id as u64, + id: entry.id.to_proto(), is_dir: entry.is_dir(), path: entry.path.to_string_lossy().to_string(), inode: entry.inode, @@ -2379,7 +2376,7 @@ impl<'a> TryFrom<(&'a CharBag, proto::Entry)> for Entry { }; let path: Arc = Arc::from(Path::new(&entry.path)); Ok(Entry { - id: entry.id as usize, + id: ProjectEntryId::from_proto(entry.id), kind, path: path.clone(), inode: entry.inode, diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 7f03005b80..372f0c169b 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -9,7 +9,7 @@ use gpui::{ AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, View, ViewContext, ViewHandle, WeakViewHandle, }; -use project::{Project, ProjectEntry, ProjectPath, Worktree, WorktreeId}; +use project::{Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId}; use std::{ collections::{hash_map, HashMap}, ffi::OsStr, @@ -24,7 +24,7 @@ pub struct ProjectPanel { project: ModelHandle, list: UniformListState, visible_entries: Vec<(WorktreeId, Vec)>, - expanded_dir_ids: HashMap>, + expanded_dir_ids: HashMap>, selection: Option, handle: WeakViewHandle, } @@ -32,7 +32,7 @@ pub struct ProjectPanel { #[derive(Copy, Clone)] struct Selection { worktree_id: WorktreeId, - entry_id: usize, + entry_id: ProjectEntryId, index: usize, } @@ -47,8 +47,8 @@ struct EntryDetails { action!(ExpandSelectedEntry); action!(CollapseSelectedEntry); -action!(ToggleExpanded, ProjectEntry); -action!(Open, ProjectEntry); +action!(ToggleExpanded, ProjectEntryId); +action!(Open, ProjectEntryId); pub fn init(cx: &mut MutableAppContext) { cx.add_action(ProjectPanel::expand_selected_entry); @@ -64,10 +64,7 @@ pub fn init(cx: &mut MutableAppContext) { } pub enum Event { - OpenedEntry { - worktree_id: WorktreeId, - entry_id: usize, - }, + OpenedEntry(ProjectEntryId), } impl ProjectPanel { @@ -78,15 +75,15 @@ impl ProjectPanel { cx.notify(); }) .detach(); - cx.subscribe(&project, |this, _, event, cx| match event { - project::Event::ActiveEntryChanged(Some(ProjectEntry { - worktree_id, - entry_id, - })) => { - this.expand_entry(*worktree_id, *entry_id, cx); - this.update_visible_entries(Some((*worktree_id, *entry_id)), cx); - this.autoscroll(); - cx.notify(); + cx.subscribe(&project, |this, project, event, cx| match event { + project::Event::ActiveEntryChanged(Some(entry_id)) => { + if let Some(worktree_id) = project.read(cx).worktree_id_for_entry(*entry_id, cx) + { + this.expand_entry(worktree_id, *entry_id, cx); + this.update_visible_entries(Some((worktree_id, *entry_id)), cx); + this.autoscroll(); + cx.notify(); + } } project::Event::WorktreeRemoved(id) => { this.expanded_dir_ids.remove(id); @@ -109,16 +106,13 @@ impl ProjectPanel { this }); cx.subscribe(&project_panel, move |workspace, _, event, cx| match event { - &Event::OpenedEntry { - worktree_id, - entry_id, - } => { - if let Some(worktree) = project.read(cx).worktree_for_id(worktree_id, cx) { + &Event::OpenedEntry(entry_id) => { + if let Some(worktree) = project.read(cx).worktree_for_entry(entry_id, cx) { if let Some(entry) = worktree.read(cx).entry_for_id(entry_id) { workspace .open_path( ProjectPath { - worktree_id, + worktree_id: worktree.read(cx).id(), path: entry.path.clone(), }, cx, @@ -152,10 +146,7 @@ impl ProjectPanel { } } } else { - let event = Event::OpenedEntry { - worktree_id: worktree.id(), - entry_id: entry.id, - }; + let event = Event::OpenedEntry(entry.id); cx.emit(event); } } @@ -193,22 +184,20 @@ impl ProjectPanel { } fn toggle_expanded(&mut self, action: &ToggleExpanded, cx: &mut ViewContext) { - let ProjectEntry { - worktree_id, - entry_id, - } = action.0; - - if let Some(expanded_dir_ids) = self.expanded_dir_ids.get_mut(&worktree_id) { - match expanded_dir_ids.binary_search(&entry_id) { - Ok(ix) => { - expanded_dir_ids.remove(ix); - } - Err(ix) => { - expanded_dir_ids.insert(ix, entry_id); + let entry_id = action.0; + if let Some(worktree_id) = self.project.read(cx).worktree_id_for_entry(entry_id, cx) { + if let Some(expanded_dir_ids) = self.expanded_dir_ids.get_mut(&worktree_id) { + match expanded_dir_ids.binary_search(&entry_id) { + Ok(ix) => { + expanded_dir_ids.remove(ix); + } + Err(ix) => { + expanded_dir_ids.insert(ix, entry_id); + } } + self.update_visible_entries(Some((worktree_id, entry_id)), cx); + cx.focus_self(); } - self.update_visible_entries(Some((worktree_id, entry_id)), cx); - cx.focus_self(); } } @@ -229,10 +218,7 @@ impl ProjectPanel { } fn open_entry(&mut self, action: &Open, cx: &mut ViewContext) { - cx.emit(Event::OpenedEntry { - worktree_id: action.0.worktree_id, - entry_id: action.0.entry_id, - }); + cx.emit(Event::OpenedEntry(action.0)); } fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext) { @@ -313,7 +299,7 @@ impl ProjectPanel { fn update_visible_entries( &mut self, - new_selected_entry: Option<(WorktreeId, usize)>, + new_selected_entry: Option<(WorktreeId, ProjectEntryId)>, cx: &mut ViewContext, ) { let worktrees = self @@ -379,7 +365,7 @@ impl ProjectPanel { fn expand_entry( &mut self, worktree_id: WorktreeId, - entry_id: usize, + entry_id: ProjectEntryId, cx: &mut ViewContext, ) { let project = self.project.read(cx); @@ -411,7 +397,7 @@ impl ProjectPanel { &self, range: Range, cx: &mut ViewContext, - mut callback: impl FnMut(ProjectEntry, EntryDetails, &mut ViewContext), + mut callback: impl FnMut(ProjectEntryId, EntryDetails, &mut ViewContext), ) { let mut ix = 0; for (worktree_id, visible_worktree_entries) in &self.visible_entries { @@ -450,11 +436,7 @@ impl ProjectPanel { e.worktree_id == snapshot.id() && e.entry_id == entry.id }), }; - let entry = ProjectEntry { - worktree_id: snapshot.id(), - entry_id: entry.id, - }; - callback(entry, details, cx); + callback(entry.id, details, cx); } } } @@ -463,13 +445,13 @@ impl ProjectPanel { } fn render_entry( - entry: ProjectEntry, + entry_id: ProjectEntryId, details: EntryDetails, theme: &theme::ProjectPanel, cx: &mut ViewContext, ) -> ElementBox { let is_dir = details.is_dir; - MouseEventHandler::new::(entry.entry_id, cx, |state, _| { + MouseEventHandler::new::(entry_id.to_usize(), cx, |state, _| { let style = match (details.is_selected, state.hovered) { (false, false) => &theme.entry, (false, true) => &theme.hovered_entry, @@ -519,9 +501,9 @@ impl ProjectPanel { }) .on_click(move |cx| { if is_dir { - cx.dispatch_action(ToggleExpanded(entry)) + cx.dispatch_action(ToggleExpanded(entry_id)) } else { - cx.dispatch_action(Open(entry)) + cx.dispatch_action(Open(entry_id)) } }) .with_cursor_style(CursorStyle::PointingHand) @@ -830,13 +812,7 @@ mod tests { let worktree = worktree.read(cx); if let Ok(relative_path) = path.strip_prefix(worktree.root_name()) { let entry_id = worktree.entry_for_path(relative_path).unwrap().id; - panel.toggle_expanded( - &ToggleExpanded(ProjectEntry { - worktree_id: worktree.id(), - entry_id, - }), - cx, - ); + panel.toggle_expanded(&ToggleExpanded(entry_id), cx); return; } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 56395b107a..20df486f48 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -250,7 +250,7 @@ impl ItemView for ProjectSearchView { None } - fn project_entry(&self, _: &AppContext) -> Option { + fn project_entry_id(&self, _: &AppContext) -> Option { None } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 9f5ee52274..5d346279f0 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -10,7 +10,7 @@ use gpui::{ AnyViewHandle, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; -use project::{ProjectEntry, ProjectPath}; +use project::{ProjectEntryId, ProjectPath}; use std::{ any::{Any, TypeId}, cell::RefCell, @@ -97,7 +97,7 @@ pub enum Event { } pub struct Pane { - item_views: Vec<(Option, Box)>, + item_views: Vec<(Option, Box)>, active_item_index: usize, nav_history: Rc>, toolbars: HashMap>, @@ -323,9 +323,9 @@ impl Pane { .map(|(_, view)| view.clone()) } - pub fn item_for_entry(&self, entry: ProjectEntry) -> Option> { + pub fn item_for_entry(&self, entry_id: ProjectEntryId) -> Option> { self.item_views.iter().find_map(|(id, view)| { - if *id == Some(entry.entry_id) { + if *id == Some(entry_id) { Some(view.boxed_clone()) } else { None diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 5a3385a014..464eecd307 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -26,7 +26,7 @@ use log::error; pub use pane::*; pub use pane_group::*; use postage::prelude::Stream; -use project::{fs, Fs, Project, ProjectEntry, ProjectPath, Worktree}; +use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, Worktree}; pub use settings::Settings; use sidebar::{Side, Sidebar, SidebarItemId, ToggleSidebarItem, ToggleSidebarItemFocus}; use status_bar::StatusBar; @@ -138,7 +138,7 @@ pub trait ItemView: View { fn navigate(&mut self, _: Box, _: &mut ViewContext) {} fn tab_content(&self, style: &theme::Tab, cx: &AppContext) -> ElementBox; fn project_path(&self, cx: &AppContext) -> Option; - fn project_entry(&self, cx: &AppContext) -> Option; + fn project_entry_id(&self, cx: &AppContext) -> Option; fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext); fn clone_on_split(&self, _: &mut ViewContext) -> Option where @@ -191,7 +191,7 @@ pub trait ItemView: View { pub trait ItemViewHandle: 'static { fn tab_content(&self, style: &theme::Tab, cx: &AppContext) -> ElementBox; fn project_path(&self, cx: &AppContext) -> Option; - fn project_entry_id(&self, cx: &AppContext) -> Option; + fn project_entry_id(&self, cx: &AppContext) -> Option; fn boxed_clone(&self) -> Box; fn set_nav_history(&self, nav_history: Rc>, cx: &mut MutableAppContext); fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option>; @@ -239,8 +239,8 @@ impl ItemViewHandle for ViewHandle { self.read(cx).project_path(cx) } - fn project_entry_id(&self, cx: &AppContext) -> Option { - Some(self.read(cx).project_entry(cx)?.entry_id) + fn project_entry_id(&self, cx: &AppContext) -> Option { + self.read(cx).project_entry_id(cx) } fn boxed_clone(&self) -> Box { @@ -850,7 +850,7 @@ impl Workspace { pub fn open_item_for_project_entry( &mut self, - project_entry: ProjectEntry, + project_entry: ProjectEntryId, cx: &mut ViewContext, build_view: F, ) -> Box