From 92256292081c9b18c0fde68dd0a0f46ca90dd807 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 15:51:59 +0200 Subject: [PATCH 1/4] Re-render breadcrumbs on save or when the editor title changes --- crates/breadcrumbs/src/breadcrumbs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index ce32fb22723833fdf86c5ec2c49c155f34368b2a..7085712f8c1f5299e1c4c68b40c09b0955a0cd1e 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -99,7 +99,9 @@ impl ToolbarItemView for Breadcrumbs { if let Some(editor) = item.act_as::(cx) { self.subscriptions .push(cx.subscribe(&editor, |_, _, event, cx| match event { - editor::Event::BufferEdited => cx.notify(), + editor::Event::BufferEdited + | editor::Event::TitleChanged + | editor::Event::Saved => cx.notify(), editor::Event::SelectionsChanged { local } if *local => cx.notify(), _ => {} })); From c39de1f9dc1d59e27be549e62fd99ffe56ecfb0f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:10:10 +0200 Subject: [PATCH 2/4] Show full path for file worktrees or when there is more than 1 worktree --- Cargo.lock | 1 + crates/breadcrumbs/Cargo.toml | 1 + crates/breadcrumbs/src/breadcrumbs.rs | 35 +++++++++++++++++---------- crates/editor/src/multi_buffer.rs | 11 +++++++-- crates/zed/src/zed.rs | 27 ++++++++++++--------- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 276fbf1525ff8d21f678e1b47a6ca7abf8abc697..2c64dd0ba78d68af43898a92304da3f23322c611 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -727,6 +727,7 @@ dependencies = [ "editor", "gpui", "language", + "project", "search", "theme", "workspace", diff --git a/crates/breadcrumbs/Cargo.toml b/crates/breadcrumbs/Cargo.toml index 2e74fd2090dedaf165c15e950bfe113e8d9c392b..7dbafdb3be560805d18df4fe47a4c0b7c605b95a 100644 --- a/crates/breadcrumbs/Cargo.toml +++ b/crates/breadcrumbs/Cargo.toml @@ -12,6 +12,7 @@ collections = { path = "../collections" } editor = { path = "../editor" } gpui = { path = "../gpui" } language = { path = "../language" } +project = { path = "../project" } search = { path = "../search" } theme = { path = "../theme" } workspace = { path = "../workspace" } diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 7085712f8c1f5299e1c4c68b40c09b0955a0cd1e..0f8ac9274e3bf69c5baa972799df9c8743d9564e 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -1,10 +1,11 @@ use editor::{Anchor, Editor}; use gpui::{ - elements::*, AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle, + elements::*, AppContext, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext, + ViewHandle, }; -use language::{BufferSnapshot, OutlineItem}; +use language::{Buffer, OutlineItem}; +use project::Project; use search::ProjectSearchView; -use std::borrow::Cow; use theme::SyntaxTheme; use workspace::{ItemHandle, Settings, ToolbarItemLocation, ToolbarItemView}; @@ -13,14 +14,16 @@ pub enum Event { } pub struct Breadcrumbs { + project: ModelHandle, editor: Option>, project_search: Option>, subscriptions: Vec, } impl Breadcrumbs { - pub fn new() -> Self { + pub fn new(project: ModelHandle) -> Self { Self { + project, editor: Default::default(), subscriptions: Default::default(), project_search: Default::default(), @@ -31,14 +34,14 @@ impl Breadcrumbs { &self, theme: &SyntaxTheme, cx: &AppContext, - ) -> Option<(BufferSnapshot, Vec>)> { + ) -> Option<(ModelHandle, Vec>)> { let editor = self.editor.as_ref()?.read(cx); let cursor = editor.newest_anchor_selection().head(); - let (buffer, symbols) = editor - .buffer() - .read(cx) + let multibuffer = &editor.buffer().read(cx); + let (buffer_id, symbols) = multibuffer .read(cx) .symbols_containing(cursor, Some(theme))?; + let buffer = multibuffer.buffer(buffer_id)?; Some((buffer, symbols)) } } @@ -60,15 +63,21 @@ impl View for Breadcrumbs { } else { return Empty::new().boxed(); }; - - let filename = if let Some(path) = buffer.path() { - path.to_string_lossy() + 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() + } } else { - Cow::Borrowed("untitled") + "untitled".to_string() }; Flex::row() - .with_child(Label::new(filename.to_string(), theme.breadcrumbs.text.clone()).boxed()) + .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(), diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index ad3fc3202d94cfeef9f6ace31ccac8068b0c9b10..c07df895c995eda51d44da0221a30bf5118b5e39 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -1001,6 +1001,13 @@ impl MultiBuffer { .collect() } + pub fn buffer(&self, buffer_id: usize) -> Option> { + self.buffers + .borrow() + .get(&buffer_id) + .map(|state| state.buffer.clone()) + } + pub fn save(&mut self, cx: &mut ModelContext) -> Task> { let mut save_tasks = Vec::new(); for BufferState { buffer, .. } in self.buffers.borrow().values() { @@ -2268,12 +2275,12 @@ impl MultiBufferSnapshot { &self, offset: T, theme: Option<&SyntaxTheme>, - ) -> Option<(BufferSnapshot, Vec>)> { + ) -> Option<(usize, Vec>)> { let anchor = self.anchor_before(offset); let excerpt_id = anchor.excerpt_id(); let excerpt = self.excerpt(excerpt_id)?; Some(( - excerpt.buffer.clone(), + excerpt.buffer_id, excerpt .buffer .symbols_containing(anchor.text_anchor, theme) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 7b54b3df9a2d07ee9e5cc6963536cc091f713792..aec0bc533e4a1842789b813c4fc060eaa334e165 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -106,18 +106,21 @@ pub fn build_workspace( app_state: &Arc, cx: &mut ViewContext, ) -> Workspace { - cx.subscribe(&cx.handle(), |_, _, event, cx| { - let workspace::Event::PaneAdded(pane) = event; - pane.update(cx, |pane, cx| { - pane.toolbar().update(cx, |toolbar, cx| { - let breadcrumbs = cx.add_view(|_| Breadcrumbs::new()); - toolbar.add_item(breadcrumbs, cx); - let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); - toolbar.add_item(buffer_search_bar, cx); - let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); - toolbar.add_item(project_search_bar, cx); - }) - }); + cx.subscribe(&cx.handle(), { + let project = project.clone(); + move |_, _, event, cx| { + 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())); + toolbar.add_item(breadcrumbs, cx); + let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); + toolbar.add_item(buffer_search_bar, cx); + let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); + toolbar.add_item(project_search_bar, cx); + }) + }); + } }) .detach(); From d0a17f8c2cda6ffc8eeee68460a650c83a8e76e5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:16:47 +0200 Subject: [PATCH 3/4] Update toolbar and automatically unfollow when navigating back and forth --- crates/workspace/src/pane.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 33df9fd4c79285919330510a383befb94b6e5284..8dfe0f49a2abe72abc1a18455e028a135321bb6b 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -207,13 +207,16 @@ impl Pane { let prev_active_index = mem::replace(&mut pane.active_item_index, index); pane.focus_active_item(cx); + pane.update_toolbar(cx); + cx.emit(Event::ActivateItem { local: true }); + cx.notify(); + let mut navigated = prev_active_index != pane.active_item_index; if let Some(data) = entry.data { navigated |= pane.active_item()?.navigate(data, cx); } if navigated { - cx.notify(); break None; } } From b0b54365c79e7431a735c8132a93647df3fcf57a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:19:15 +0200 Subject: [PATCH 4/4] Re-render breadcrumbs when buffer has been reparsed --- crates/breadcrumbs/src/breadcrumbs.rs | 3 ++- crates/editor/src/editor.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 0f8ac9274e3bf69c5baa972799df9c8743d9564e..59c8b08b685270576967492f3f0c87d659a5799b 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -110,7 +110,8 @@ impl ToolbarItemView for Breadcrumbs { .push(cx.subscribe(&editor, |_, _, event, cx| match event { editor::Event::BufferEdited | editor::Event::TitleChanged - | editor::Event::Saved => cx.notify(), + | editor::Event::Saved + | editor::Event::Reparsed => cx.notify(), editor::Event::SelectionsChanged { local } if *local => cx.notify(), _ => {} })); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 1135c9b260367a563add678c6a73a46b2d6d561e..8a35e4b3d21faaace8275e9a4cd091d1a6124840 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5860,6 +5860,7 @@ impl Editor { self.refresh_code_actions(cx); cx.emit(Event::BufferEdited); } + language::Event::Reparsed => cx.emit(Event::Reparsed), language::Event::Dirtied => cx.emit(Event::Dirtied), language::Event::Saved => cx.emit(Event::Saved), language::Event::FileHandleChanged => cx.emit(Event::TitleChanged), @@ -5987,6 +5988,7 @@ pub enum Event { Activate, BufferEdited, Edited, + Reparsed, Blurred, Dirtied, Saved,