diff --git a/assets/icons/chevron_down_up.svg b/assets/icons/chevron_down_up.svg
new file mode 100644
index 0000000000000000000000000000000000000000..340b8d1ad93113a1affe5c723c9b5f5e12a228a8
--- /dev/null
+++ b/assets/icons/chevron_down_up.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json
index 979e5a6ccc1d4520db65981fb3b8a01094f9c625..6f57e6f689a30543ee0b7d6b95d451af885d502a 100644
--- a/assets/keymaps/default-linux.json
+++ b/assets/keymaps/default-linux.json
@@ -407,6 +407,7 @@
     "bindings": {
       "escape": "project_search::ToggleFocus",
       "shift-find": "search::FocusSearch",
+      "shift-enter": "project_search::ToggleAllSearchResults",
       "ctrl-shift-f": "search::FocusSearch",
       "ctrl-shift-h": "search::ToggleReplace",
       "alt-ctrl-g": "search::ToggleRegex",
@@ -479,6 +480,7 @@
       "alt-w": "search::ToggleWholeWord",
       "alt-find": "project_search::ToggleFilters",
       "alt-ctrl-f": "project_search::ToggleFilters",
+      "shift-enter": "project_search::ToggleAllSearchResults",
       "ctrl-alt-shift-r": "search::ToggleRegex",
       "ctrl-alt-shift-x": "search::ToggleRegex",
       "alt-r": "search::ToggleRegex",
diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json
index 4f9b85ff03790a8c9a59a657a3e0ca0710d41e25..a1d38b6028f8ec7690f7133b765ffdbb8d261f17 100644
--- a/assets/keymaps/default-macos.json
+++ b/assets/keymaps/default-macos.json
@@ -468,6 +468,7 @@
     "bindings": {
       "escape": "project_search::ToggleFocus",
       "cmd-shift-j": "project_search::ToggleFilters",
+      "shift-enter": "project_search::ToggleAllSearchResults",
       "cmd-shift-f": "search::FocusSearch",
       "cmd-shift-h": "search::ToggleReplace",
       "alt-cmd-g": "search::ToggleRegex",
@@ -496,6 +497,7 @@
     "bindings": {
       "escape": "project_search::ToggleFocus",
       "cmd-shift-j": "project_search::ToggleFilters",
+      "shift-enter": "project_search::ToggleAllSearchResults",
       "cmd-shift-h": "search::ToggleReplace",
       "alt-cmd-g": "search::ToggleRegex",
       "alt-cmd-x": "search::ToggleRegex"
diff --git a/assets/keymaps/default-windows.json b/assets/keymaps/default-windows.json
index 29146f3080d6ecad75bb9754503bb93c6710ff30..2dd72845b196c029bb2c575bcdd07b5ef07ae970 100644
--- a/assets/keymaps/default-windows.json
+++ b/assets/keymaps/default-windows.json
@@ -488,6 +488,7 @@
       "alt-c": "search::ToggleCaseSensitive",
       "alt-w": "search::ToggleWholeWord",
       "alt-f": "project_search::ToggleFilters",
+      "shift-enter": "project_search::ToggleAllSearchResults",
       "alt-r": "search::ToggleRegex",
       // "ctrl-shift-alt-x": "search::ToggleRegex",
       "ctrl-k shift-enter": "pane::TogglePinTab"
diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs
index 08c0915c58ae50741238574cec5b6f2474d06eb8..7664de3c87673a405118911526cb6606a2fecacf 100644
--- a/crates/breadcrumbs/src/breadcrumbs.rs
+++ b/crates/breadcrumbs/src/breadcrumbs.rs
@@ -100,13 +100,21 @@ impl Render for Breadcrumbs {
 
         let breadcrumbs_stack = h_flex().gap_1().children(breadcrumbs);
 
+        let prefix_element = active_item.breadcrumb_prefix(window, cx);
+
+        let breadcrumbs = if let Some(prefix) = prefix_element {
+            h_flex().gap_1p5().child(prefix).child(breadcrumbs_stack)
+        } else {
+            breadcrumbs_stack
+        };
+
         match active_item
             .downcast::()
             .map(|editor| editor.downgrade())
         {
             Some(editor) => element.child(
                 ButtonLike::new("toggle outline view")
-                    .child(breadcrumbs_stack)
+                    .child(breadcrumbs)
                     .style(ButtonStyle::Transparent)
                     .on_click({
                         let editor = editor.clone();
@@ -141,7 +149,7 @@ impl Render for Breadcrumbs {
                 // Match the height and padding of the `ButtonLike` in the other arm.
                 .h(rems_from_px(22.))
                 .pl_1()
-                .child(breadcrumbs_stack),
+                .child(breadcrumbs),
         }
     }
 }
diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs
index 1442c482d89f0c46e45ccd280e678021e6ba63c7..a4da8c6ccdf04f453a368b902af8543625100436 100644
--- a/crates/icons/src/icons.rs
+++ b/crates/icons/src/icons.rs
@@ -53,6 +53,7 @@ pub enum IconName {
     Check,
     CheckDouble,
     ChevronDown,
+    ChevronDownUp,
     ChevronLeft,
     ChevronRight,
     ChevronUp,
diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs
index 9ee92c73008338e0ee655f3d02cb1dcbf1a3326b..f5a9c272d4846a94230286cc3ae2f7903608dd7d 100644
--- a/crates/search/src/project_search.rs
+++ b/crates/search/src/project_search.rs
@@ -57,7 +57,9 @@ actions!(
         /// Moves to the next input field.
         NextField,
         /// Toggles the search filters panel.
-        ToggleFilters
+        ToggleFilters,
+        /// Toggles collapse/expand state of all search result excerpts.
+        ToggleAllSearchResults
     ]
 );
 
@@ -120,6 +122,20 @@ pub fn init(cx: &mut App) {
             ProjectSearchView::search_in_new(workspace, action, window, cx)
         });
 
+        register_workspace_action_for_present_search(
+            workspace,
+            |workspace, action: &ToggleAllSearchResults, window, cx| {
+                if let Some(search_view) = workspace
+                    .active_item(cx)
+                    .and_then(|item| item.downcast::())
+                {
+                    search_view.update(cx, |search_view, cx| {
+                        search_view.toggle_all_search_results(action, window, cx);
+                    });
+                }
+            },
+        );
+
         register_workspace_action_for_present_search(
             workspace,
             |workspace, _: &menu::Cancel, window, cx| {
@@ -219,6 +235,7 @@ pub struct ProjectSearchView {
     replace_enabled: bool,
     included_opened_only: bool,
     regex_language: Option>,
+    results_collapsed: bool,
     _subscriptions: Vec,
 }
 
@@ -651,6 +668,44 @@ impl Item for ProjectSearchView {
     fn breadcrumbs(&self, theme: &theme::Theme, cx: &App) -> Option> {
         self.results_editor.breadcrumbs(theme, cx)
     }
+
+    fn breadcrumb_prefix(
+        &self,
+        _window: &mut Window,
+        cx: &mut Context,
+    ) -> Option {
+        if !self.has_matches() {
+            return None;
+        }
+
+        let is_collapsed = self.results_collapsed;
+
+        let (icon, tooltip_label) = if is_collapsed {
+            (IconName::ChevronUpDown, "Expand All Search Results")
+        } else {
+            (IconName::ChevronDownUp, "Collapse All Search Results")
+        };
+
+        let focus_handle = self.query_editor.focus_handle(cx);
+
+        Some(
+            IconButton::new("project-search-collapse-expand", icon)
+                .shape(IconButtonShape::Square)
+                .icon_size(IconSize::Small)
+                .tooltip(move |_, cx| {
+                    Tooltip::for_action_in(
+                        tooltip_label,
+                        &ToggleAllSearchResults,
+                        &focus_handle,
+                        cx,
+                    )
+                })
+                .on_click(cx.listener(|this, _, window, cx| {
+                    this.toggle_all_search_results(&ToggleAllSearchResults, window, cx);
+                }))
+                .into_any_element(),
+        )
+    }
 }
 
 impl ProjectSearchView {
@@ -753,6 +808,34 @@ impl ProjectSearchView {
         });
     }
 
+    fn toggle_all_search_results(
+        &mut self,
+        _: &ToggleAllSearchResults,
+        _window: &mut Window,
+        cx: &mut Context,
+    ) {
+        self.results_collapsed = !self.results_collapsed;
+        self.update_results_visibility(cx);
+    }
+
+    fn update_results_visibility(&mut self, cx: &mut Context) {
+        self.results_editor.update(cx, |editor, cx| {
+            let multibuffer = editor.buffer().read(cx);
+            let buffer_ids = multibuffer.excerpt_buffer_ids();
+
+            if self.results_collapsed {
+                for buffer_id in buffer_ids {
+                    editor.fold_buffer(buffer_id, cx);
+                }
+            } else {
+                for buffer_id in buffer_ids {
+                    editor.unfold_buffer(buffer_id, cx);
+                }
+            }
+        });
+        cx.notify();
+    }
+
     pub fn new(
         workspace: WeakEntity,
         entity: Entity,
@@ -911,8 +994,10 @@ impl ProjectSearchView {
             replace_enabled: false,
             included_opened_only: false,
             regex_language: None,
+            results_collapsed: false,
             _subscriptions: subscriptions,
         };
+
         this.entity_changed(window, cx);
         this
     }
@@ -1411,6 +1496,7 @@ impl ProjectSearchView {
 
     fn entity_changed(&mut self, window: &mut Window, cx: &mut Context) {
         let match_ranges = self.entity.read(cx).match_ranges.clone();
+
         if match_ranges.is_empty() {
             self.active_match_index = None;
             self.results_editor.update(cx, |editor, cx| {
@@ -1968,6 +2054,8 @@ impl Render for ProjectSearchBar {
             })
             .unwrap_or_else(|| "0/0".to_string());
 
+        let query_focus = search.query_editor.focus_handle(cx);
+
         let query_column = input_base_styles(InputPanel::Query)
             .on_action(cx.listener(|this, action, window, cx| this.confirm(action, window, cx)))
             .on_action(cx.listener(|this, action, window, cx| {
@@ -1997,11 +2085,9 @@ impl Render for ProjectSearchBar {
                     )),
             );
 
-        let query_focus = search.query_editor.focus_handle(cx);
-
         let matches_column = h_flex()
-            .pl_2()
-            .ml_2()
+            .ml_1()
+            .pl_1p5()
             .border_l_1()
             .border_color(theme_colors.border_variant)
             .child(render_action_button(
diff --git a/crates/search/src/search_bar.rs b/crates/search/src/search_bar.rs
index 14a5fefcf7341694260da96a8f2c43d149356074..61fa46ed9770fbaf49b43979d366655c1b658fc3 100644
--- a/crates/search/src/search_bar.rs
+++ b/crates/search/src/search_bar.rs
@@ -46,7 +46,6 @@ pub(crate) fn input_base_styles(border_color: Hsla, map: impl FnOnce(Div) -> Div
         .h_8()
         .pl_2()
         .pr_1()
-        .py_1()
         .border_1()
         .border_color(border_color)
         .rounded_md()
diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs
index b77075f92bf69dc292cf69ac7eac147043d7d8b7..ee9a10d9c5344cfa372bf88a95e46de1705ee093 100644
--- a/crates/workspace/src/item.rs
+++ b/crates/workspace/src/item.rs
@@ -296,6 +296,15 @@ pub trait Item: Focusable + EventEmitter + Render + Sized {
         None
     }
 
+    /// Returns optional elements to render to the left of the breadcrumb.
+    fn breadcrumb_prefix(
+        &self,
+        _window: &mut Window,
+        _cx: &mut Context,
+    ) -> Option {
+        None
+    }
+
     fn added_to_workspace(
         &mut self,
         _workspace: &mut Workspace,
@@ -479,6 +488,7 @@ pub trait ItemHandle: 'static + Send {
     fn to_searchable_item_handle(&self, cx: &App) -> Option>;
     fn breadcrumb_location(&self, cx: &App) -> ToolbarItemLocation;
     fn breadcrumbs(&self, theme: &Theme, cx: &App) -> Option>;
+    fn breadcrumb_prefix(&self, window: &mut Window, cx: &mut App) -> Option;
     fn show_toolbar(&self, cx: &App) -> bool;
     fn pixel_position_of_cursor(&self, cx: &App) -> Option>;
     fn downgrade_item(&self) -> Box;
@@ -979,6 +989,10 @@ impl ItemHandle for Entity {
         self.read(cx).breadcrumbs(theme, cx)
     }
 
+    fn breadcrumb_prefix(&self, window: &mut Window, cx: &mut App) -> Option {
+        self.update(cx, |item, cx| item.breadcrumb_prefix(window, cx))
+    }
+
     fn show_toolbar(&self, cx: &App) -> bool {
         self.read(cx).show_toolbar()
     }