diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index a1dd7be744..7bee815ad9 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -450,6 +450,10 @@ impl workspace::Item for ProjectDiagnosticsEditor { None } + fn project_entry_id(&self, _: &AppContext) -> Option { + None + } + fn navigate(&mut self, data: Box, cx: &mut ViewContext) { self.editor .update(cx, |editor, cx| editor.navigate(data, cx)); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 6f083f00a9..d865511a62 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -5,7 +5,7 @@ use gpui::{ ViewContext, ViewHandle, }; use language::{Bias, Buffer, Diagnostic, File as _}; -use project::{File, Project, ProjectPath}; +use project::{File, Project, ProjectEntryId, ProjectPath}; use std::fmt::Write; use std::path::PathBuf; use text::{Point, Selection}; @@ -41,6 +41,10 @@ impl Item for Editor { }) } + 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 where Self: Sized, diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index ef8ff3611a..f027c965c6 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -250,6 +250,10 @@ impl Item for ProjectSearchView { None } + fn project_entry_id(&self, _: &AppContext) -> Option { + None + } + fn can_save(&self, _: &gpui::AppContext) -> bool { true } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index ec27d2400e..c3b6a5fd29 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -9,8 +9,8 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f}, keymap::Binding, platform::{CursorStyle, NavigationDirection}, - AnyViewHandle, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AnyViewHandle, AppContext, Entity, MutableAppContext, Quad, RenderContext, Task, View, + ViewContext, ViewHandle, WeakViewHandle, }; use project::{ProjectEntryId, ProjectPath}; use std::{ @@ -99,7 +99,7 @@ pub enum Event { } pub struct Pane { - items: Vec<(Option, Box)>, + items: Vec>, active_item_index: usize, nav_history: Rc>, toolbars: HashMap>, @@ -110,8 +110,7 @@ pub struct Pane { pub(crate) struct FollowerState { pub(crate) leader_id: PeerId, pub(crate) current_view_id: usize, - pub(crate) items_by_leader_view_id: - HashMap, Box)>, + pub(crate) items_by_leader_view_id: HashMap>, } pub trait Toolbar: View { @@ -295,8 +294,8 @@ impl Pane { cx: &mut ViewContext, build_item: impl FnOnce(&mut MutableAppContext) -> Box, ) -> Box { - for (ix, (existing_entry_id, item)) in self.items.iter().enumerate() { - if *existing_entry_id == Some(project_entry_id) { + for (ix, item) in self.items.iter().enumerate() { + if item.project_entry_id(cx) == Some(project_entry_id) { let item = item.boxed_clone(); self.activate_item(ix, cx); return item; @@ -304,20 +303,15 @@ impl Pane { } let item = build_item(cx); - self.add_item(Some(project_entry_id), item.boxed_clone(), cx); + self.add_item(item.boxed_clone(), cx); item } - pub(crate) fn add_item( - &mut self, - project_entry_id: Option, - mut item: Box, - cx: &mut ViewContext, - ) { + pub(crate) fn add_item(&mut self, mut item: Box, cx: &mut ViewContext) { item.set_nav_history(self.nav_history.clone(), cx); item.added_to_pane(cx); let item_idx = cmp::min(self.active_item_index + 1, self.items.len()); - self.items.insert(item_idx, (project_entry_id, item)); + self.items.insert(item_idx, item); self.activate_item(item_idx, cx); cx.notify(); } @@ -328,39 +322,45 @@ impl Pane { cx: &mut ViewContext, ) -> Result<()> { let current_view_id = follower_state.current_view_id as usize; - let (project_entry_id, item) = follower_state + let item = follower_state .items_by_leader_view_id .get(¤t_view_id) .ok_or_else(|| anyhow!("invalid current view id"))? .clone(); - self.add_item(project_entry_id, item, cx); + self.add_item(item, cx); Ok(()) } pub fn items(&self) -> impl Iterator> { - self.items.iter().map(|(_, view)| view) + self.items.iter() } pub fn active_item(&self) -> Option> { - self.items - .get(self.active_item_index) - .map(|(_, view)| view.clone()) + self.items.get(self.active_item_index).cloned() } - pub fn project_entry_id_for_item(&self, item: &dyn ItemHandle) -> Option { - self.items.iter().find_map(|(entry_id, existing)| { + pub fn project_entry_id_for_item( + &self, + item: &dyn ItemHandle, + cx: &AppContext, + ) -> Option { + self.items.iter().find_map(|existing| { if existing.id() == item.id() { - *entry_id + existing.project_entry_id(cx) } else { None } }) } - pub fn item_for_entry(&self, entry_id: ProjectEntryId) -> Option> { - self.items.iter().find_map(|(id, view)| { - if *id == Some(entry_id) { - Some(view.boxed_clone()) + pub fn item_for_entry( + &self, + entry_id: ProjectEntryId, + cx: &AppContext, + ) -> Option> { + self.items.iter().find_map(|item| { + if item.project_entry_id(cx) == Some(entry_id) { + Some(item.boxed_clone()) } else { None } @@ -368,7 +368,7 @@ impl Pane { } pub fn index_for_item(&self, item: &dyn ItemHandle) -> Option { - self.items.iter().position(|(_, i)| i.id() == item.id()) + self.items.iter().position(|i| i.id() == item.id()) } pub fn activate_item(&mut self, index: usize, cx: &mut ViewContext) { @@ -377,7 +377,7 @@ impl Pane { if prev_active_item_ix != self.active_item_index && prev_active_item_ix < self.items.len() { - self.items[prev_active_item_ix].1.deactivated(cx); + self.items[prev_active_item_ix].deactivated(cx); } self.update_active_toolbar(cx); self.focus_active_item(cx); @@ -408,13 +408,13 @@ impl Pane { pub fn close_active_item(&mut self, cx: &mut ViewContext) { if !self.items.is_empty() { - self.close_item(self.items[self.active_item_index].1.id(), cx) + self.close_item(self.items[self.active_item_index].id(), cx) } } pub fn close_inactive_items(&mut self, cx: &mut ViewContext) { if !self.items.is_empty() { - let active_item_id = self.items[self.active_item_index].1.id(); + let active_item_id = self.items[self.active_item_index].id(); self.close_items(cx, |id| id != active_item_id); } } @@ -430,7 +430,7 @@ impl Pane { ) { let mut item_ix = 0; let mut new_active_item_index = self.active_item_index; - self.items.retain(|(_, item)| { + self.items.retain(|item| { if should_close(item.id()) { if item_ix == self.active_item_index { item.deactivated(cx); @@ -529,7 +529,7 @@ impl Pane { fn update_active_toolbar(&mut self, cx: &mut ViewContext) { let active_item = self.items.get(self.active_item_index); for (toolbar_type_id, toolbar) in &self.toolbars { - let visible = toolbar.active_item_changed(active_item.map(|i| i.1.clone()), cx); + let visible = toolbar.active_item_changed(active_item.cloned(), cx); if Some(*toolbar_type_id) == self.active_toolbar_type { self.active_toolbar_visible = visible; } @@ -542,7 +542,7 @@ impl Pane { enum Tabs {} let tabs = MouseEventHandler::new::(0, cx, |mouse_state, cx| { let mut row = Flex::row(); - for (ix, (_, item)) in self.items.iter().enumerate() { + for (ix, item) in self.items.iter().enumerate() { let is_active = ix == self.active_item_index; row.add_child({ diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 80f5b4e7a1..85672db11b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -53,7 +53,7 @@ type FollowedItemBuilders = Vec< ModelHandle, &mut Option, &mut MutableAppContext, - ) -> Option, Box)>>>, + ) -> Option>>>, >; action!(Open, Arc); @@ -157,6 +157,7 @@ pub trait Item: 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_id(&self, cx: &AppContext) -> Option; fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext); fn clone_on_split(&self, _: &mut ViewContext) -> Option where @@ -224,12 +225,13 @@ pub trait FollowedItem: Item { project: ModelHandle, state: &mut Option, cx: &mut MutableAppContext, - ) -> Option, Box)>>>; + ) -> Option>>>; } pub trait ItemHandle: '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 boxed_clone(&self) -> Box; fn set_nav_history(&self, nav_history: Rc>, cx: &mut MutableAppContext); fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option>; @@ -277,6 +279,10 @@ impl ItemHandle for ViewHandle { self.read(cx).project_path(cx) } + fn project_entry_id(&self, cx: &AppContext) -> Option { + self.read(cx).project_entry_id(cx) + } + fn boxed_clone(&self) -> Box { Box::new(self.clone()) } @@ -814,7 +820,7 @@ impl Workspace { pub fn add_item(&mut self, item: Box, cx: &mut ViewContext) { self.active_pane() - .update(cx, |pane, cx| pane.add_item(None, item, cx)) + .update(cx, |pane, cx| pane.add_item(item, cx)) } pub fn open_path( @@ -877,7 +883,7 @@ impl Workspace { if let Some(item) = project_item .read(cx) .entry_id(cx) - .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id)) + .and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx)) .and_then(|item| item.downcast()) { self.activate_item(&item, cx); @@ -959,10 +965,9 @@ impl Workspace { let new_pane = self.add_pane(cx); self.activate_pane(new_pane.clone(), cx); if let Some(item) = pane.read(cx).active_item() { - let project_entry_id = pane.read(cx).project_entry_id_for_item(item.as_ref()); if let Some(clone) = item.clone_on_split(cx.as_mut()) { new_pane.update(cx, |new_pane, cx| { - new_pane.add_item(project_entry_id, clone, cx); + new_pane.add_item(clone, cx); }); } }