chore: Remove outline dependency from breadcrumbs (#22504)

Piotr Osiewicz created

This slashes our incremental dev times (touch editor) by 0.6s
(8.1->7.6s) due to unblocking terminal_view build sooner.

Closes #ISSUE

Release Notes:

- N/A

Change summary

Cargo.lock                             |  3 ++-
crates/breadcrumbs/Cargo.toml          |  2 +-
crates/breadcrumbs/src/breadcrumbs.rs  | 11 +++++++----
crates/editor/src/actions.rs           |  2 --
crates/outline/Cargo.toml              |  1 +
crates/outline/src/outline.rs          | 21 ++++++++++++++++-----
crates/zed/src/zed/app_menus.rs        |  5 ++++-
crates/zed/src/zed/quick_action_bar.rs |  4 ++--
crates/zed_actions/src/lib.rs          | 10 ++++++++++
9 files changed, 43 insertions(+), 16 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1945,10 +1945,10 @@ dependencies = [
  "editor",
  "gpui",
  "itertools 0.13.0",
- "outline",
  "theme",
  "ui",
  "workspace",
+ "zed_actions",
 ]
 
 [[package]]
@@ -8629,6 +8629,7 @@ dependencies = [
  "ui",
  "util",
  "workspace",
+ "zed_actions",
 ]
 
 [[package]]

crates/breadcrumbs/Cargo.toml 🔗

@@ -16,10 +16,10 @@ doctest = false
 editor.workspace = true
 gpui.workspace = true
 itertools.workspace = true
-outline.workspace = true
 theme.workspace = true
 ui.workspace = true
 workspace.workspace = true
+zed_actions.workspace = true
 
 [dev-dependencies]
 editor = { workspace = true, features = ["test-support"] }

crates/breadcrumbs/src/breadcrumbs.rs 🔗

@@ -102,8 +102,11 @@ impl Render for Breadcrumbs {
                     .on_click({
                         let editor = editor.clone();
                         move |_, cx| {
-                            if let Some(editor) = editor.upgrade() {
-                                outline::toggle(editor, &editor::actions::ToggleOutline, cx)
+                            if let Some((editor, callback)) = editor
+                                .upgrade()
+                                .zip(zed_actions::outline::TOGGLE_OUTLINE.get())
+                            {
+                                callback(editor.to_any(), cx);
                             }
                         }
                     })
@@ -112,14 +115,14 @@ impl Render for Breadcrumbs {
                             let focus_handle = editor.read(cx).focus_handle(cx);
                             Tooltip::for_action_in(
                                 "Show Symbol Outline",
-                                &editor::actions::ToggleOutline,
+                                &zed_actions::outline::ToggleOutline,
                                 &focus_handle,
                                 cx,
                             )
                         } else {
                             Tooltip::for_action(
                                 "Show Symbol Outline",
-                                &editor::actions::ToggleOutline,
+                                &zed_actions::outline::ToggleOutline,
                                 cx,
                             )
                         }

crates/editor/src/actions.rs 🔗

@@ -388,6 +388,4 @@ gpui::actions!(
     ]
 );
 
-action_as!(outline, ToggleOutline as Toggle);
-
 action_as!(go_to_line, ToggleGoToLine as Toggle);

crates/outline/Cargo.toml 🔗

@@ -25,6 +25,7 @@ theme.workspace = true
 ui.workspace = true
 util.workspace = true
 workspace.workspace = true
+zed_actions.workspace = true
 
 [dev-dependencies]
 editor = { workspace = true, features = ["test-support"] }

crates/outline/src/outline.rs 🔗

@@ -4,9 +4,7 @@ use std::{
     sync::Arc,
 };
 
-use editor::{
-    actions::ToggleOutline, scroll::Autoscroll, Anchor, AnchorRangeExt, Editor, EditorMode,
-};
+use editor::{scroll::Autoscroll, Anchor, AnchorRangeExt, Editor, EditorMode};
 use fuzzy::StringMatch;
 use gpui::{
     div, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, HighlightStyle,
@@ -24,9 +22,22 @@ use workspace::{DismissDecision, ModalView};
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(OutlineView::register).detach();
+    zed_actions::outline::TOGGLE_OUTLINE
+        .set(|view, cx| {
+            let Ok(view) = view.downcast::<Editor>() else {
+                return;
+            };
+
+            toggle(view, &Default::default(), cx);
+        })
+        .ok();
 }
 
-pub fn toggle(editor: View<Editor>, _: &ToggleOutline, cx: &mut WindowContext) {
+pub fn toggle(
+    editor: View<Editor>,
+    _: &zed_actions::outline::ToggleOutline,
+    cx: &mut WindowContext,
+) {
     let outline = editor
         .read(cx)
         .buffer()
@@ -459,7 +470,7 @@ mod tests {
         workspace: &View<Workspace>,
         cx: &mut VisualTestContext,
     ) -> View<Picker<OutlineViewDelegate>> {
-        cx.dispatch_action(ToggleOutline);
+        cx.dispatch_action(zed_actions::outline::ToggleOutline);
         workspace.update(cx, |workspace, cx| {
             workspace
                 .active_modal::<OutlineView>(cx)

crates/zed/src/zed/app_menus.rs 🔗

@@ -156,7 +156,10 @@ pub fn app_menus() -> Vec<Menu> {
                 MenuItem::separator(),
                 MenuItem::action("Go to File...", workspace::ToggleFileFinder::default()),
                 // MenuItem::action("Go to Symbol in Project", project_symbols::Toggle),
-                MenuItem::action("Go to Symbol in Editor...", editor::actions::ToggleOutline),
+                MenuItem::action(
+                    "Go to Symbol in Editor...",
+                    zed_actions::outline::ToggleOutline,
+                ),
                 MenuItem::action("Go to Line/Column...", editor::actions::ToggleGoToLine),
                 MenuItem::separator(),
                 MenuItem::action("Go to Definition", editor::actions::GoToDefinition),

crates/zed/src/zed/quick_action_bar.rs 🔗

@@ -6,7 +6,7 @@ use assistant::AssistantPanel;
 use editor::actions::{
     AddSelectionAbove, AddSelectionBelow, DuplicateLineDown, GoToDiagnostic, GoToHunk,
     GoToPrevDiagnostic, GoToPrevHunk, MoveLineDown, MoveLineUp, SelectAll, SelectLargerSyntaxNode,
-    SelectNext, SelectSmallerSyntaxNode, ToggleGoToLine, ToggleOutline,
+    SelectNext, SelectSmallerSyntaxNode, ToggleGoToLine,
 };
 use editor::{Editor, EditorSettings};
 use gpui::{
@@ -23,7 +23,7 @@ use vim_mode_setting::VimModeSetting;
 use workspace::{
     item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
 };
-use zed_actions::InlineAssist;
+use zed_actions::{outline::ToggleOutline, InlineAssist};
 
 pub struct QuickActionBar {
     _inlay_hints_enabled_subscription: Option<Subscription>,

crates/zed_actions/src/lib.rs 🔗

@@ -151,3 +151,13 @@ pub struct Rerun {
 }
 
 impl_actions!(task, [Spawn, Rerun]);
+
+pub mod outline {
+    use std::sync::OnceLock;
+
+    use gpui::{action_as, AnyView, WindowContext};
+
+    action_as!(outline, ToggleOutline as Toggle);
+    /// A pointer to outline::toggle function, exposed here to sewer the breadcrumbs <-> outline dependency.
+    pub static TOGGLE_OUTLINE: OnceLock<fn(AnyView, &mut WindowContext<'_>)> = OnceLock::new();
+}