Add an action to toggle the outline from the buffer search bar (#25225)

This was annoying.

Release Notes:

- Fixed a bug where you couldn't open the outline modal when focus was
in the buffer search bar.
This commit is contained in:
Mikayla Maki 2025-02-19 21:23:10 -08:00 committed by GitHub
parent 0c0201c79f
commit cc46a1fe30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 20 additions and 3 deletions

1
Cargo.lock generated
View file

@ -11845,6 +11845,7 @@ dependencies = [
"unindent", "unindent",
"util", "util",
"workspace", "workspace",
"zed_actions",
] ]
[[package]] [[package]]

View file

@ -286,7 +286,8 @@
"alt-enter": "search::SelectAllMatches", "alt-enter": "search::SelectAllMatches",
"cmd-f": "search::FocusSearch", "cmd-f": "search::FocusSearch",
"cmd-alt-f": "search::ToggleReplace", "cmd-alt-f": "search::ToggleReplace",
"cmd-alt-l": "search::ToggleSelection" "cmd-alt-l": "search::ToggleSelection",
"cmd-shift-o": "outline::Toggle"
} }
}, },
{ {

View file

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

View file

@ -28,6 +28,7 @@ use serde::Deserialize;
use settings::Settings; use settings::Settings;
use std::sync::Arc; use std::sync::Arc;
use theme::ThemeSettings; use theme::ThemeSettings;
use zed_actions::outline::ToggleOutline;
use ui::{ use ui::{
h_flex, prelude::*, utils::SearchInputWidth, IconButton, IconButtonShape, IconName, Tooltip, h_flex, prelude::*, utils::SearchInputWidth, IconButton, IconButtonShape, IconName, Tooltip,
@ -482,6 +483,11 @@ impl Render for BufferSearchBar {
.on_action(cx.listener(Self::dismiss)) .on_action(cx.listener(Self::dismiss))
.on_action(cx.listener(Self::select_next_match)) .on_action(cx.listener(Self::select_next_match))
.on_action(cx.listener(Self::select_prev_match)) .on_action(cx.listener(Self::select_prev_match))
.on_action(cx.listener(|this, _: &ToggleOutline, window, cx| {
if let Some(active_searchable_item) = &mut this.active_searchable_item {
active_searchable_item.relay_action(Box::new(ToggleOutline), window, cx);
}
}))
.when(self.supported_options(cx).replacement, |this| { .when(self.supported_options(cx).replacement, |this| {
this.on_action(cx.listener(Self::toggle_replace)) this.on_action(cx.listener(Self::toggle_replace))
.when(in_replace, |this| { .when(in_replace, |this| {

View file

@ -13,8 +13,8 @@ use client::{
}; };
use futures::{channel::mpsc, StreamExt}; use futures::{channel::mpsc, StreamExt};
use gpui::{ use gpui::{
AnyElement, AnyView, App, Context, Entity, EntityId, EventEmitter, FocusHandle, Focusable, Action, AnyElement, AnyView, App, Context, Entity, EntityId, EventEmitter, FocusHandle,
Font, HighlightStyle, Pixels, Point, Render, SharedString, Task, WeakEntity, Window, Focusable, Font, HighlightStyle, Pixels, Point, Render, SharedString, Task, WeakEntity, Window,
}; };
use project::{Project, ProjectEntryId, ProjectPath}; use project::{Project, ProjectEntryId, ProjectPath};
use schemars::JsonSchema; use schemars::JsonSchema;
@ -518,6 +518,7 @@ pub trait ItemHandle: 'static + Send {
fn workspace_settings<'a>(&self, cx: &'a App) -> &'a WorkspaceSettings; fn workspace_settings<'a>(&self, cx: &'a App) -> &'a WorkspaceSettings;
fn preserve_preview(&self, cx: &App) -> bool; fn preserve_preview(&self, cx: &App) -> bool;
fn include_in_nav_history(&self) -> bool; fn include_in_nav_history(&self) -> bool;
fn relay_action(&self, action: Box<dyn Action>, window: &mut Window, cx: &mut App);
} }
pub trait WeakItemHandle: Send + Sync { pub trait WeakItemHandle: Send + Sync {
@ -978,6 +979,13 @@ impl<T: Item> ItemHandle for Entity<T> {
fn include_in_nav_history(&self) -> bool { fn include_in_nav_history(&self) -> bool {
T::include_in_nav_history() T::include_in_nav_history()
} }
fn relay_action(&self, action: Box<dyn Action>, window: &mut Window, cx: &mut App) {
self.update(cx, |this, cx| {
this.focus_handle(cx).focus(window);
window.dispatch_action(action, cx);
})
}
} }
impl From<Box<dyn ItemHandle>> for AnyView { impl From<Box<dyn ItemHandle>> for AnyView {