From 68238479787073a2d4e4219ac06205f6d0ea7197 Mon Sep 17 00:00:00 2001
From: Josh Piasecki <138541977+FloppyDisco@users.noreply.github.com>
Date: Mon, 27 Oct 2025 21:37:37 -0500
Subject: [PATCH] Add buffer_search_deployed key context (#41193)
Release Notes:
- Pane key context now includes 'buffer_search_deployed' identifier
The goal of this PR is to add a new identifier in the key context that
will let the user target when the BufferSearchBar is deployed even if
they are not focused on it.
requested in #36930
Same rational as #40454 this will allow users to make more flexible
keybindings, by including some additional information higher up the key
context tree.
i thought adding this context to `Pane` seemed more appropriate than
`Editor` since `Terminal` also has a `BufferSearchBar`; however, I ran
into some import issues between BufferSearchBar, Search, Pane, and
Workspace which made it difficult to implement adding this context
directly inside `Pane`'s render function.
instead i added a new method called `contributes_context` to
`ToolbarItem` which will allow any toolbar item to add additional
context to the `Pane` level, which feels like it might come in handy.
here are some screen shots of the context being displayed in the Editor
and the Terminal
---
crates/search/src/buffer_search.rs | 6 ++++++
crates/workspace/src/pane.rs | 4 ++++
crates/workspace/src/toolbar.rs | 19 +++++++++++++++++--
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs
index 49c1fc5b297aedcf86c66140d0d803901b18c52a..25697bb45ac5f617b586d7a4346ee8761b7a4ed3 100644
--- a/crates/search/src/buffer_search.rs
+++ b/crates/search/src/buffer_search.rs
@@ -468,6 +468,12 @@ impl Focusable for BufferSearchBar {
}
impl ToolbarItemView for BufferSearchBar {
+ fn contribute_context(&self, context: &mut KeyContext, _cx: &App) {
+ if !self.dismissed {
+ context.add("buffer_search_deployed");
+ }
+ }
+
fn set_active_pane_item(
&mut self,
item: Option<&dyn ItemHandle>,
diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs
index 9b6767086adffde00a0486b6a9cae62aaa8d41df..c2c79b6a5fc3cc337f6dd7273d529fd40f04c8a1 100644
--- a/crates/workspace/src/pane.rs
+++ b/crates/workspace/src/pane.rs
@@ -3702,6 +3702,10 @@ impl Render for Pane {
key_context.add("EmptyPane");
}
+ self.toolbar
+ .read(cx)
+ .contribute_context(&mut key_context, cx);
+
let should_display_tab_bar = self.should_display_tab_bar.clone();
let display_tab_bar = should_display_tab_bar(window, cx);
let Some(project) = self.project.upgrade() else {
diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs
index 9d6626af80fbab9b7bf8439a3c5f628263892bc6..6e26be6dc7a09dd1ed8963579ae27d8f6cc8c50c 100644
--- a/crates/workspace/src/toolbar.rs
+++ b/crates/workspace/src/toolbar.rs
@@ -1,7 +1,7 @@
use crate::ItemHandle;
use gpui::{
- AnyView, App, Context, Entity, EntityId, EventEmitter, ParentElement as _, Render, Styled,
- Window,
+ AnyView, App, Context, Entity, EntityId, EventEmitter, KeyContext, ParentElement as _, Render,
+ Styled, Window,
};
use ui::prelude::*;
use ui::{h_flex, v_flex};
@@ -25,6 +25,8 @@ pub trait ToolbarItemView: Render + EventEmitter {
_cx: &mut Context,
) {
}
+
+ fn contribute_context(&self, _context: &mut KeyContext, _cx: &App) {}
}
trait ToolbarItemViewHandle: Send {
@@ -37,6 +39,7 @@ trait ToolbarItemViewHandle: Send {
cx: &mut App,
) -> ToolbarItemLocation;
fn focus_changed(&mut self, pane_focused: bool, window: &mut Window, cx: &mut App);
+ fn contribute_context(&self, context: &mut KeyContext, cx: &App);
}
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -236,6 +239,14 @@ impl Toolbar {
pub fn hidden(&self) -> bool {
self.hidden
}
+
+ pub fn contribute_context(&self, context: &mut KeyContext, cx: &App) {
+ for (item, location) in &self.items {
+ if *location != ToolbarItemLocation::Hidden {
+ item.contribute_context(context, cx);
+ }
+ }
+ }
}
impl ToolbarItemViewHandle for Entity {
@@ -264,4 +275,8 @@ impl ToolbarItemViewHandle for Entity {
cx.notify();
});
}
+
+ fn contribute_context(&self, context: &mut KeyContext, cx: &App) {
+ self.read(cx).contribute_context(context, cx)
+ }
}