From e7c14dacae6cb984992715a732572a5526782ed3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 11 Dec 2023 14:01:16 +0100 Subject: [PATCH 1/3] Show the correct outline when clicking on a breadcrumb --- crates/breadcrumbs2/src/breadcrumbs.rs | 37 ++++++++---------------- crates/outline2/src/outline.rs | 40 ++++++++++++++------------ crates/zed2/src/zed2.rs | 2 +- 3 files changed, 35 insertions(+), 44 deletions(-) diff --git a/crates/breadcrumbs2/src/breadcrumbs.rs b/crates/breadcrumbs2/src/breadcrumbs.rs index ee6ad2c8e6d79344865b857d5dc8710d65f947a6..3b8ce1c6c5a34096a985d5ace4ff62f744ad870c 100644 --- a/crates/breadcrumbs2/src/breadcrumbs.rs +++ b/crates/breadcrumbs2/src/breadcrumbs.rs @@ -1,13 +1,14 @@ +use editor::Editor; use gpui::{ Div, Element, EventEmitter, IntoElement, ParentElement, Render, StyledText, Subscription, - ViewContext, WeakView, + ViewContext, }; use itertools::Itertools; use theme::ActiveTheme; use ui::{prelude::*, ButtonLike, ButtonStyle, Label, Tooltip}; use workspace::{ item::{ItemEvent, ItemHandle}, - ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, + ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, }; pub enum Event { @@ -18,16 +19,14 @@ pub struct Breadcrumbs { pane_focused: bool, active_item: Option>, subscription: Option, - workspace: WeakView, } impl Breadcrumbs { - pub fn new(workspace: &Workspace) -> Self { + pub fn new() -> Self { Self { pane_focused: false, active_item: Default::default(), subscription: Default::default(), - workspace: workspace.weak_handle(), } } } @@ -62,31 +61,19 @@ impl Render for Breadcrumbs { Label::new("›").into_any_element() }); + let editor = active_item + .downcast::() + .map(|editor| editor.downgrade()); + element.child( ButtonLike::new("toggle outline view") .style(ButtonStyle::Subtle) .child(h_stack().gap_1().children(breadcrumbs)) - // We disable the button when the containing pane is not focused: - // Because right now all the breadcrumb does is open the outline view, which is an - // action which operates on the active editor, clicking the breadcrumbs of another - // editor could cause weirdness. I remember that at one point it actually caused a - // panic weirdly. - // - // It might be possible that with changes around how focus is managed that we - // might be able to update the active editor to the one with the breadcrumbs - // clicked on? That or we could just add a code path for being able to open the - // outline for a specific editor. Long term we'd like for it to be an actual - // breadcrumb bar so that problem goes away - // - // — Julia (https://github.com/zed-industries/zed/pull/3505#pullrequestreview-1766198050) - .disabled(!self.pane_focused) - .on_click(cx.listener(|breadcrumbs, _, cx| { - if let Some(workspace) = breadcrumbs.workspace.upgrade() { - workspace.update(cx, |workspace, cx| { - outline::toggle(workspace, &outline::Toggle, cx) - }) + .on_click(move |_, cx| { + if let Some(editor) = editor.as_ref().and_then(|editor| editor.upgrade()) { + outline::toggle(editor, &outline::Toggle, cx) } - })) + }) .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)), ) } diff --git a/crates/outline2/src/outline.rs b/crates/outline2/src/outline.rs index 5fce79e4320d799fc77b73e4e1a3267cf0361597..9d578c68316cb4ce4084ad9910fb6439ee4f8ef3 100644 --- a/crates/outline2/src/outline.rs +++ b/crates/outline2/src/outline.rs @@ -1,6 +1,6 @@ use editor::{ display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Anchor, AnchorRangeExt, - DisplayPoint, Editor, ToPoint, + DisplayPoint, Editor, EditorMode, ToPoint, }; use fuzzy::StringMatch; use gpui::{ @@ -20,7 +20,7 @@ use std::{ use theme::{color_alpha, ActiveTheme, ThemeSettings}; use ui::{prelude::*, ListItem}; use util::ResultExt; -use workspace::{ModalView, Workspace}; +use workspace::ModalView; actions!(outline, [Toggle]); @@ -28,21 +28,18 @@ pub fn init(cx: &mut AppContext) { cx.observe_new_views(OutlineView::register).detach(); } -pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { - if let Some(editor) = workspace - .active_item(cx) - .and_then(|item| item.downcast::()) - { - let outline = editor - .read(cx) - .buffer() - .read(cx) - .snapshot(cx) - .outline(Some(&cx.theme().syntax())); - - if let Some(outline) = outline { +pub fn toggle(editor: View, _: &Toggle, cx: &mut WindowContext) { + let outline = editor + .read(cx) + .buffer() + .read(cx) + .snapshot(cx) + .outline(Some(&cx.theme().syntax())); + + if let Some((workspace, outline)) = editor.read(cx).workspace().zip(outline) { + workspace.update(cx, |workspace, cx| { workspace.toggle_modal(cx, |cx| OutlineView::new(outline, editor, cx)); - } + }) } } @@ -68,8 +65,15 @@ impl Render for OutlineView { } impl OutlineView { - fn register(workspace: &mut Workspace, _: &mut ViewContext) { - workspace.register_action(toggle); + fn register(editor: &mut Editor, cx: &mut ViewContext) { + if editor.mode() == EditorMode::Full { + let handle = cx.view().downgrade(); + editor.register_action(move |action, cx| { + if let Some(editor) = handle.upgrade() { + toggle(editor, action, cx); + } + }); + } } fn new( diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index d5edbc6f8db501c47419b62aa9f503bdced48356..0a44bf6ec0fc7e25fb3135fd91379dc8a4fd7ba9 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -419,7 +419,7 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { fn initialize_pane(workspace: &mut Workspace, pane: &View, cx: &mut ViewContext) { pane.update(cx, |pane, cx| { pane.toolbar().update(cx, |toolbar, cx| { - let breadcrumbs = cx.build_view(|_| Breadcrumbs::new(workspace)); + let breadcrumbs = cx.build_view(|_| Breadcrumbs::new()); toolbar.add_item(breadcrumbs, cx); let buffer_search_bar = cx.build_view(search::BufferSearchBar::new); toolbar.add_item(buffer_search_bar.clone(), cx); From 5768f14a0388ef702b391a5c424bfc9341cafeb9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 11 Dec 2023 14:02:08 +0100 Subject: [PATCH 2/3] Emit `Focus` events from `Pane` only when it didn't have focus before --- crates/workspace2/src/pane.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index 38e0706fb1896b6e4bd90dcc141063d22def0b04..8c98ad8df70ec5be54371a47d24cdb8e04f81d3d 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -159,6 +159,7 @@ pub struct Pane { items: Vec>, activation_history: Vec, zoomed: bool, + was_focused: bool, active_item_index: usize, last_focused_view_by_item: HashMap, autoscroll: bool, @@ -317,6 +318,7 @@ impl Pane { focus_handle: cx.focus_handle(), items: Vec::new(), activation_history: Vec::new(), + was_focused: false, zoomed: false, active_item_index: 0, last_focused_view_by_item: Default::default(), @@ -413,7 +415,8 @@ impl Pane { } fn focus_in(&mut self, cx: &mut ViewContext) { - if !self.has_focus(cx) { + if !self.was_focused { + self.was_focused = true; cx.emit(Event::Focus); cx.notify(); } @@ -444,6 +447,7 @@ impl Pane { } fn focus_out(&mut self, cx: &mut ViewContext) { + self.was_focused = false; self.toolbar.update(cx, |toolbar, cx| { toolbar.focus_changed(false, cx); }); From 3c56f6d5c12bfa79e5eb1a1a2fe0c3470fc67a8d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 11 Dec 2023 14:18:46 +0100 Subject: [PATCH 3/3] Focus editor when confirming outline item --- crates/outline2/src/outline.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/outline2/src/outline.rs b/crates/outline2/src/outline.rs index 9d578c68316cb4ce4084ad9910fb6439ee4f8ef3..f3d1f327da7b587f48a5175ea3ebea3112d3bfb5 100644 --- a/crates/outline2/src/outline.rs +++ b/crates/outline2/src/outline.rs @@ -243,6 +243,7 @@ impl PickerDelegate for OutlineViewDelegate { s.select_ranges([position..position]) }); active_editor.highlight_rows(None); + active_editor.focus(cx); } });