diff --git a/Cargo.lock b/Cargo.lock index d9cbdce80147ce61ea141278bbfe6c64f0d56206..634ef452a369b142c983302bcb471c00395e1a19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,6 +613,7 @@ dependencies = [ "collections", "editor", "gpui", + "itertools", "language", "project", "search", diff --git a/crates/breadcrumbs/Cargo.toml b/crates/breadcrumbs/Cargo.toml index 88fd614a893e0badaa5800a9c9eef6d75b4da374..e5cae74e8f61fc8177d1cc84b9a7463df5c61ddb 100644 --- a/crates/breadcrumbs/Cargo.toml +++ b/crates/breadcrumbs/Cargo.toml @@ -17,6 +17,7 @@ search = { path = "../search" } settings = { path = "../settings" } theme = { path = "../theme" } workspace = { path = "../workspace" } +itertools = "0.10" [dev-dependencies] editor = { path = "../editor", features = ["test-support"] } diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 2d8089c1205709e63e2adcc42715ba4a48be4d61..85f0509caf6f7f73e84312454a321d94d139edcd 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -1,48 +1,29 @@ -use editor::{Anchor, Editor}; use gpui::{ - elements::*, AppContext, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext, - ViewHandle, + elements::*, AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle, }; -use language::{Buffer, OutlineItem}; -use project::Project; +use itertools::Itertools; use search::ProjectSearchView; use settings::Settings; -use theme::SyntaxTheme; -use workspace::{ItemHandle, ToolbarItemLocation, ToolbarItemView}; +use workspace::{ItemEvent, ItemHandle, ToolbarItemLocation, ToolbarItemView}; pub enum Event { UpdateLocation, } pub struct Breadcrumbs { - project: ModelHandle, - editor: Option>, + active_item: Option>, project_search: Option>, - subscriptions: Vec, + subscription: Option, } impl Breadcrumbs { - pub fn new(project: ModelHandle) -> Self { + pub fn new() -> Self { Self { - project, - editor: Default::default(), - subscriptions: Default::default(), + active_item: Default::default(), + subscription: Default::default(), project_search: Default::default(), } } - - fn active_symbols( - &self, - theme: &SyntaxTheme, - cx: &AppContext, - ) -> Option<(ModelHandle, Vec>)> { - let editor = self.editor.as_ref()?.read(cx); - let cursor = editor.selections.newest_anchor().head(); - let multibuffer = &editor.buffer().read(cx); - let (buffer_id, symbols) = multibuffer.symbols_containing(cursor, Some(theme), cx)?; - let buffer = multibuffer.buffer(buffer_id)?; - Some((buffer, symbols)) - } } impl Entity for Breadcrumbs { @@ -56,40 +37,23 @@ impl View for Breadcrumbs { fn render(&mut self, cx: &mut RenderContext) -> ElementBox { let theme = cx.global::().theme.clone(); - let (buffer, symbols) = - if let Some((buffer, symbols)) = self.active_symbols(&theme.editor.syntax, cx) { - (buffer, symbols) - } else { - return Empty::new().boxed(); - }; - let buffer = buffer.read(cx); - let filename = if let Some(file) = buffer.file() { - if file.path().file_name().is_none() - || self.project.read(cx).visible_worktrees(cx).count() > 1 - { - file.full_path(cx).to_string_lossy().to_string() - } else { - file.path().to_string_lossy().to_string() - } + if let Some(breadcrumbs) = self + .active_item + .as_ref() + .and_then(|item| item.breadcrumbs(&theme, cx)) + { + Flex::row() + .with_children(Itertools::intersperse_with(breadcrumbs.into_iter(), || { + Label::new(" 〉 ".to_string(), theme.breadcrumbs.text.clone()).boxed() + })) + .contained() + .with_style(theme.breadcrumbs.container) + .aligned() + .left() + .boxed() } else { - "untitled".to_string() - }; - - Flex::row() - .with_child(Label::new(filename, theme.breadcrumbs.text.clone()).boxed()) - .with_children(symbols.into_iter().flat_map(|symbol| { - [ - Label::new(" 〉 ".to_string(), theme.breadcrumbs.text.clone()).boxed(), - Text::new(symbol.text, theme.breadcrumbs.text.clone()) - .with_highlights(symbol.highlight_ranges) - .boxed(), - ] - })) - .contained() - .with_style(theme.breadcrumbs.container) - .aligned() - .left() - .boxed() + Empty::new().boxed() + } } } @@ -100,39 +64,25 @@ impl ToolbarItemView for Breadcrumbs { cx: &mut ViewContext, ) -> ToolbarItemLocation { cx.notify(); - self.subscriptions.clear(); - self.editor = None; + self.active_item = None; self.project_search = None; if let Some(item) = active_pane_item { - if let Some(editor) = item.act_as::(cx) { - self.subscriptions - .push(cx.subscribe(&editor, |_, _, event, cx| match event { - editor::Event::BufferEdited - | editor::Event::TitleChanged - | editor::Event::Saved - | editor::Event::Reparsed => cx.notify(), - editor::Event::SelectionsChanged { local } if *local => cx.notify(), - _ => {} - })); - self.editor = Some(editor); - if let Some(project_search) = item.downcast::() { - self.subscriptions - .push(cx.subscribe(&project_search, |_, _, _, cx| { - cx.emit(Event::UpdateLocation); - })); - self.project_search = Some(project_search.clone()); - - if project_search.read(cx).has_matches() { - ToolbarItemLocation::Secondary - } else { - ToolbarItemLocation::Hidden + let this = cx.weak_handle(); + self.subscription = Some(item.subscribe_to_item_events( + cx, + Box::new(move |event, cx| { + if let Some(this) = this.upgrade(cx) { + if let ItemEvent::UpdateBreadcrumbs = event { + this.update(cx, |_, cx| { + cx.emit(Event::UpdateLocation); + cx.notify(); + }); + } } - } else { - ToolbarItemLocation::PrimaryLeft { flex: None } - } - } else { - ToolbarItemLocation::Hidden - } + }), + )); + self.active_item = Some(item.boxed_clone()); + item.breadcrumb_location(cx) } else { ToolbarItemLocation::Hidden } @@ -144,12 +94,8 @@ impl ToolbarItemView for Breadcrumbs { current_location: ToolbarItemLocation, cx: &AppContext, ) -> ToolbarItemLocation { - if let Some(project_search) = self.project_search.as_ref() { - if project_search.read(cx).has_matches() { - ToolbarItemLocation::Secondary - } else { - ToolbarItemLocation::Hidden - } + if let Some(active_item) = self.active_item.as_ref() { + active_item.breadcrumb_location(cx) } else { current_location } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index e14a44b05825f39656ca3ccd4f8b121ba8eb8753..271843dc69a5f572264ee02ab40c921d856759d8 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -566,12 +566,8 @@ impl workspace::Item for ProjectDiagnosticsEditor { unreachable!() } - fn should_update_tab_on_event(event: &Event) -> bool { - Editor::should_update_tab_on_event(event) - } - - fn is_edit_event(event: &Self::Event) -> bool { - Editor::is_edit_event(event) + fn to_item_events(event: &Self::Event) -> Vec { + Editor::to_item_events(event) } fn set_nav_history(&mut self, nav_history: ItemNavHistory, cx: &mut ViewContext) { diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 3d412c423ec9ec38ddda520026cf75cc2c1b5c57..fb6f12a16f7335dcdc62d0809158faa14d656881 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -26,7 +26,8 @@ use text::{Point, Selection}; use util::TryFutureExt; use workspace::{ searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle}, - FollowableItem, Item, ItemHandle, ItemNavHistory, ProjectItem, StatusItemView, + FollowableItem, Item, ItemEvent, ItemHandle, ItemNavHistory, ProjectItem, StatusItemView, + ToolbarItemLocation, }; pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2); @@ -475,23 +476,71 @@ impl Item for Editor { }) } - fn should_close_item_on_event(event: &Event) -> bool { - matches!(event, Event::Closed) + fn to_item_events(event: &Self::Event) -> Vec { + let mut result = Vec::new(); + match event { + Event::Closed => result.push(ItemEvent::CloseItem), + Event::Saved | Event::TitleChanged => { + result.push(ItemEvent::UpdateTab); + result.push(ItemEvent::UpdateBreadcrumbs); + } + Event::Reparsed => { + result.push(ItemEvent::UpdateBreadcrumbs); + } + Event::SelectionsChanged { local } if *local => { + result.push(ItemEvent::UpdateBreadcrumbs); + } + Event::DirtyChanged => { + result.push(ItemEvent::UpdateTab); + } + Event::BufferEdited => { + result.push(ItemEvent::Edit); + result.push(ItemEvent::UpdateBreadcrumbs); + } + _ => {} + } + result } - fn should_update_tab_on_event(event: &Event) -> bool { - matches!( - event, - Event::Saved | Event::DirtyChanged | Event::TitleChanged - ) + fn as_searchable(&self, handle: &ViewHandle) -> Option> { + Some(Box::new(handle.clone())) } - fn is_edit_event(event: &Self::Event) -> bool { - matches!(event, Event::BufferEdited) + fn breadcrumb_location(&self) -> ToolbarItemLocation { + ToolbarItemLocation::PrimaryLeft { flex: None } } - fn as_searchable(&self, handle: &ViewHandle) -> Option> { - Some(Box::new(handle.clone())) + fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option> { + let cursor = self.selections.newest_anchor().head(); + let multibuffer = &self.buffer().read(cx); + let (buffer_id, symbols) = + multibuffer.symbols_containing(cursor, Some(&theme.editor.syntax), cx)?; + let buffer = multibuffer.buffer(buffer_id)?; + + let buffer = buffer.read(cx); + let filename = if let Some(file) = buffer.file() { + if file.path().file_name().is_none() + || self + .project + .as_ref() + .map(|project| project.read(cx).visible_worktrees(cx).count() > 1) + .unwrap_or_default() + { + file.full_path(cx).to_string_lossy().to_string() + } else { + file.path().to_string_lossy().to_string() + } + } else { + "untitled".to_string() + }; + + let mut breadcrumbs = vec![Label::new(filename, theme.breadcrumbs.text.clone()).boxed()]; + breadcrumbs.extend(symbols.into_iter().map(|symbol| { + Text::new(symbol.text, theme.breadcrumbs.text.clone()) + .with_highlights(symbol.highlight_ranges) + .boxed() + })); + Some(breadcrumbs) } } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 22574b9b718f6cec0619aaaf14faabcb8db749f0..c042e29e78d478ff013f78bb3d4e0345dc3e98de 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -189,18 +189,21 @@ impl ToolbarItemView for BufferSearchBar { self.active_searchable_item.take(); self.pending_search.take(); - if let Some(searchable_item_handle) = item.and_then(|item| item.as_searchable(cx)) { + if let Some(searchable_item_handle) = + item.and_then(|item| item.to_searchable_item_handle(cx)) + { let handle = cx.weak_handle(); - self.active_searchable_item_subscription = Some(searchable_item_handle.subscribe( - cx, - Box::new(move |search_event, cx| { - if let Some(this) = handle.upgrade(cx) { - this.update(cx, |this, cx| { - this.on_active_searchable_item_event(search_event, cx) - }); - } - }), - )); + self.active_searchable_item_subscription = + Some(searchable_item_handle.subscribe_to_search_events( + cx, + Box::new(move |search_event, cx| { + if let Some(this) = handle.upgrade(cx) { + this.update(cx, |this, cx| { + this.on_active_searchable_item_event(search_event, cx) + }); + } + }), + )); self.active_searchable_item = Some(searchable_item_handle); self.update_matches(false, cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 8caa7bf71de3a36b67c51b7e761e653236fb1ff2..ca073bb10a0e5e40517ca781936082ede2574f25 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -24,7 +24,8 @@ use std::{ use util::ResultExt as _; use workspace::{ searchable::{Direction, SearchableItem, SearchableItemHandle}, - Item, ItemHandle, ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, Workspace, + Item, ItemEvent, ItemHandle, ItemNavHistory, Pane, ToolbarItemLocation, ToolbarItemView, + Workspace, }; actions!(project_search, [SearchInNew, ToggleFocus]); @@ -326,17 +327,25 @@ impl Item for ProjectSearchView { .update(cx, |editor, cx| editor.navigate(data, cx)) } - fn should_update_tab_on_event(event: &ViewEvent) -> bool { - matches!(event, ViewEvent::UpdateTab) + fn to_item_events(event: &Self::Event) -> Vec { + match event { + ViewEvent::UpdateTab => vec![ItemEvent::UpdateBreadcrumbs, ItemEvent::UpdateTab], + ViewEvent::EditorEvent(editor_event) => Editor::to_item_events(editor_event), + _ => Vec::new(), + } } - fn is_edit_event(event: &Self::Event) -> bool { - if let ViewEvent::EditorEvent(editor_event) = event { - Editor::is_edit_event(editor_event) + fn breadcrumb_location(&self) -> ToolbarItemLocation { + if self.has_matches() { + ToolbarItemLocation::Secondary } else { - false + ToolbarItemLocation::Hidden } } + + fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option> { + self.results_editor.breadcrumbs(theme, cx) + } } impl ProjectSearchView { diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 85a6fef7b6239b3c7583f5aed398533806cc3fdc..d6c22ee6bce68013123028d17fe1e176f9229c66 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -83,6 +83,7 @@ const DEBUG_LINE_HEIGHT: f32 = 5.; #[derive(Clone, Copy, Debug)] pub enum Event { TitleChanged, + BreadcrumbsChanged, CloseTerminal, Bell, Wakeup, @@ -494,9 +495,11 @@ impl Terminal { match event { AlacTermEvent::Title(title) => { self.breadcrumb_text = title.to_string(); + cx.emit(Event::BreadcrumbsChanged); } AlacTermEvent::ResetTitle => { self.breadcrumb_text = String::new(); + cx.emit(Event::BreadcrumbsChanged); } AlacTermEvent::ClipboardStore(_, data) => { cx.write_to_clipboard(ClipboardItem::new(data.to_string())) diff --git a/crates/terminal/src/terminal_container_view.rs b/crates/terminal/src/terminal_container_view.rs index baba4879804d46f968726d84bf32dabb601cdca0..1aebd1f5e7a06200594df31bd4bc2dd6fc42b356 100644 --- a/crates/terminal/src/terminal_container_view.rs +++ b/crates/terminal/src/terminal_container_view.rs @@ -9,7 +9,7 @@ use gpui::{ }; use util::truncate_and_trailoff; use workspace::searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle}; -use workspace::{Item, Workspace}; +use workspace::{Item, ItemEvent, ToolbarItemLocation, Workspace}; use crate::TerminalSize; use project::{LocalWorktree, Project, ProjectPath}; @@ -359,16 +359,40 @@ impl Item for TerminalContainer { false } - fn should_update_tab_on_event(event: &Self::Event) -> bool { - matches!(event, &Event::TitleChanged | &Event::Wakeup) + fn as_searchable(&self, handle: &ViewHandle) -> Option> { + Some(Box::new(handle.clone())) } - fn should_close_item_on_event(event: &Self::Event) -> bool { - matches!(event, &Event::CloseTerminal) + fn to_item_events(event: &Self::Event) -> Vec { + match event { + Event::BreadcrumbsChanged => vec![ItemEvent::UpdateBreadcrumbs], + Event::TitleChanged | Event::Wakeup => vec![ItemEvent::UpdateTab], + Event::CloseTerminal => vec![ItemEvent::CloseItem], + _ => vec![], + } } - fn as_searchable(&self, handle: &ViewHandle) -> Option> { - Some(Box::new(handle.clone())) + fn breadcrumb_location(&self) -> ToolbarItemLocation { + if self.connected().is_some() { + ToolbarItemLocation::PrimaryLeft { flex: None } + } else { + ToolbarItemLocation::Hidden + } + } + + fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option> { + let connected = self.connected()?; + + Some(vec![Text::new( + connected + .read(cx) + .terminal() + .read(cx) + .breadcrumb_text + .to_string(), + theme.breadcrumbs.text.clone(), + ) + .boxed()]) } } diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index f566d1136e58e2e658d176bd15919ffa5bee3189..cbe7364536281856da7947a1e2162e5024347683 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -88,7 +88,7 @@ pub trait SearchableItemHandle: ItemHandle { fn downgrade(&self) -> Box; fn boxed_clone(&self) -> Box; fn supported_options(&self) -> SearchOptions; - fn subscribe( + fn subscribe_to_search_events( &self, cx: &mut MutableAppContext, handler: Box, @@ -134,7 +134,7 @@ impl SearchableItemHandle for ViewHandle { T::supported_options() } - fn subscribe( + fn subscribe_to_search_events( &self, cx: &mut MutableAppContext, handler: Box, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c7a122e9db14f79322ba0ebc2842a7da21e10e3e..9f6c7f16122a1b8dbd4121720dbceb010ad600f3 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -267,6 +267,14 @@ pub struct AppState { pub initialize_workspace: fn(&mut Workspace, &Arc, &mut ViewContext), } +#[derive(Eq, PartialEq, Hash)] +pub enum ItemEvent { + CloseItem, + UpdateTab, + UpdateBreadcrumbs, + Edit, +} + pub trait Item: View { fn deactivated(&mut self, _: &mut ViewContext) {} fn workspace_deactivated(&mut self, _: &mut ViewContext) {} @@ -311,15 +319,7 @@ pub trait Item: View { project: ModelHandle, cx: &mut ViewContext, ) -> Task>; - fn should_close_item_on_event(_: &Self::Event) -> bool { - false - } - fn should_update_tab_on_event(_: &Self::Event) -> bool { - false - } - fn is_edit_event(_: &Self::Event) -> bool { - false - } + fn to_item_events(event: &Self::Event) -> Vec; fn act_as_type( &self, type_id: TypeId, @@ -335,6 +335,13 @@ pub trait Item: View { fn as_searchable(&self, _: &ViewHandle) -> Option> { None } + + fn breadcrumb_location(&self) -> ToolbarItemLocation { + ToolbarItemLocation::Hidden + } + fn breadcrumbs(&self, _theme: &Theme, _cx: &AppContext) -> Option> { + None + } } pub trait ProjectItem: Item { @@ -430,6 +437,11 @@ impl FollowableItemHandle for ViewHandle { } pub trait ItemHandle: 'static + fmt::Debug { + fn subscribe_to_item_events( + &self, + cx: &mut MutableAppContext, + handler: Box, + ) -> gpui::Subscription; fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option>; fn tab_content(&self, detail: Option, style: &theme::Tab, cx: &AppContext) -> ElementBox; @@ -469,7 +481,9 @@ pub trait ItemHandle: 'static + fmt::Debug { cx: &mut MutableAppContext, callback: Box, ) -> gpui::Subscription; - fn as_searchable(&self, cx: &AppContext) -> Option>; + fn to_searchable_item_handle(&self, cx: &AppContext) -> Option>; + fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation; + fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option>; } pub trait WeakItemHandle { @@ -490,6 +504,18 @@ impl dyn ItemHandle { } impl ItemHandle for ViewHandle { + fn subscribe_to_item_events( + &self, + cx: &mut MutableAppContext, + handler: Box, + ) -> gpui::Subscription { + cx.subscribe(self, move |_, event, cx| { + for item_event in T::to_item_events(event) { + handler(item_event, cx) + } + }) + } + fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option> { self.read(cx).tab_description(detail, cx) } @@ -605,47 +631,53 @@ impl ItemHandle for ViewHandle { } } - if T::should_close_item_on_event(event) { - Pane::close_item(workspace, pane, item.id(), cx).detach_and_log_err(cx); - return; - } - - if T::should_update_tab_on_event(event) { - pane.update(cx, |_, cx| { - cx.emit(pane::Event::ChangeItemTitle); - cx.notify(); - }); - } - - if T::is_edit_event(event) { - if let Autosave::AfterDelay { milliseconds } = - cx.global::().autosave - { - let prev_autosave = pending_autosave - .take() - .unwrap_or_else(|| Task::ready(Some(()))); - let (cancel_tx, mut cancel_rx) = oneshot::channel::<()>(); - let prev_cancel_tx = - mem::replace(&mut cancel_pending_autosave, cancel_tx); - let project = workspace.project.downgrade(); - let _ = prev_cancel_tx.send(()); - pending_autosave = Some(cx.spawn_weak(|_, mut cx| async move { - let mut timer = cx - .background() - .timer(Duration::from_millis(milliseconds)) - .fuse(); - prev_autosave.await; - futures::select_biased! { - _ = cancel_rx => return None, - _ = timer => {} + for item_event in T::to_item_events(event).into_iter() { + match item_event { + ItemEvent::CloseItem => { + Pane::close_item(workspace, pane, item.id(), cx) + .detach_and_log_err(cx); + return; + } + ItemEvent::UpdateTab => { + pane.update(cx, |_, cx| { + cx.emit(pane::Event::ChangeItemTitle); + cx.notify(); + }); + } + ItemEvent::Edit => { + if let Autosave::AfterDelay { milliseconds } = + cx.global::().autosave + { + let prev_autosave = pending_autosave + .take() + .unwrap_or_else(|| Task::ready(Some(()))); + let (cancel_tx, mut cancel_rx) = oneshot::channel::<()>(); + let prev_cancel_tx = + mem::replace(&mut cancel_pending_autosave, cancel_tx); + let project = workspace.project.downgrade(); + let _ = prev_cancel_tx.send(()); + let item = item.clone(); + pending_autosave = + Some(cx.spawn_weak(|_, mut cx| async move { + let mut timer = cx + .background() + .timer(Duration::from_millis(milliseconds)) + .fuse(); + prev_autosave.await; + futures::select_biased! { + _ = cancel_rx => return None, + _ = timer => {} + } + + let project = project.upgrade(&cx)?; + cx.update(|cx| Pane::autosave_item(&item, project, cx)) + .await + .log_err(); + None + })); } - - let project = project.upgrade(&cx)?; - cx.update(|cx| Pane::autosave_item(&item, project, cx)) - .await - .log_err(); - None - })); + } + _ => {} } } })); @@ -746,9 +778,17 @@ impl ItemHandle for ViewHandle { cx.observe_release(self, move |_, cx| callback(cx)) } - fn as_searchable(&self, cx: &AppContext) -> Option> { + fn to_searchable_item_handle(&self, cx: &AppContext) -> Option> { self.read(cx).as_searchable(self) } + + fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation { + self.read(cx).breadcrumb_location() + } + + fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option> { + self.read(cx).breadcrumbs(theme, cx) + } } impl From> for AnyViewHandle { @@ -3590,12 +3630,8 @@ mod tests { Task::ready(Ok(())) } - fn should_update_tab_on_event(_: &Self::Event) -> bool { - true - } - - fn is_edit_event(event: &Self::Event) -> bool { - matches!(event, TestItemEvent::Edit) + fn to_item_events(_: &Self::Event) -> Vec { + vec![ItemEvent::UpdateTab, ItemEvent::Edit] } } } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index e9248127189f2fcae44fb322253a86a52739c218..f64da9c1c89d340147ffa4f6d2196447e74dfe3f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -225,12 +225,11 @@ pub fn initialize_workspace( cx: &mut ViewContext, ) { cx.subscribe(&cx.handle(), { - let project = workspace.project().clone(); move |_, _, event, cx| { if let workspace::Event::PaneAdded(pane) = event { pane.update(cx, |pane, cx| { pane.toolbar().update(cx, |toolbar, cx| { - let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(project.clone())); + let breadcrumbs = cx.add_view(|_| Breadcrumbs::new()); toolbar.add_item(breadcrumbs, cx); let buffer_search_bar = cx.add_view(BufferSearchBar::new); toolbar.add_item(buffer_search_bar, cx);