diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 90a440a6447..8799e032bfa 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -298,6 +298,13 @@ "alt-r": "search::ToggleRegex", }, }, + { + "context": "AgentTerminalThread", + "use_key_equivalents": true, + "bindings": { + "ctrl-f": "agent::ToggleSearch", + }, + }, { "context": "AcpThreadSearchBar", "use_key_equivalents": true, diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 8b4e76dd81f..de0f8bd2b46 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -336,6 +336,13 @@ "alt-cmd-x": "search::ToggleRegex", }, }, + { + "context": "AgentTerminalThread", + "use_key_equivalents": true, + "bindings": { + "cmd-f": "agent::ToggleSearch", + }, + }, { "context": "AcpThreadSearchBar", "use_key_equivalents": true, diff --git a/assets/keymaps/default-windows.json b/assets/keymaps/default-windows.json index 08a9274c317..acc2a82e18e 100644 --- a/assets/keymaps/default-windows.json +++ b/assets/keymaps/default-windows.json @@ -299,6 +299,13 @@ "alt-r": "search::ToggleRegex", }, }, + { + "context": "AgentTerminalThread", + "use_key_equivalents": true, + "bindings": { + "ctrl-f": "agent::ToggleSearch", + }, + }, { "context": "AcpThreadSearchBar", "use_key_equivalents": true, diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index f22037c239a..40c15c71794 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -85,6 +85,7 @@ use project::{Project, ProjectPath, Worktree}; use settings::TerminalDockPosition; use settings::{NotifyWhenAgentWaiting, Settings, update_settings_file}; +use search::{BufferSearchBar, buffer_search::Deploy as DeployBufferSearch}; use terminal::{Event as TerminalEvent, terminal_settings::TerminalSettings}; use terminal_view::{TerminalView, terminal_panel::TerminalPanel}; use text::OffsetRangeExt; @@ -96,9 +97,9 @@ use ui::{ use util::ResultExt as _; use workspace::{ CollaboratorId, DraggedSelection, DraggedTab, MultiWorkspace, PathList, SerializedPathList, - ToggleWorkspaceSidebar, ToggleZoom, Workspace, WorkspaceId, + ToggleWorkspaceSidebar, ToggleZoom, ToolbarItemView, Workspace, WorkspaceId, dock::{DockPosition, Panel, PanelEvent}, - item::ItemEvent, + item::{ItemEvent, ItemHandle}, }; const AGENT_PANEL_KEY: &str = "agent_panel"; @@ -991,6 +992,7 @@ struct AgentTerminal { working_directory: Option, created_at: DateTime, has_notification: bool, + search_bar: Option>, notification_windows: Vec>, notification_subscriptions: Vec, _subscriptions: Vec, @@ -2174,6 +2176,7 @@ impl AgentPanel { working_directory, created_at: created_at.unwrap_or_else(Utc::now), has_notification: false, + search_bar: None, notification_windows: Vec::new(), notification_subscriptions: Vec::new(), _subscriptions: vec![view_subscription, terminal_subscription], @@ -3949,6 +3952,37 @@ impl AgentPanel { } } + fn toggle_terminal_thread_search( + &mut self, + _: &crate::ToggleSearch, + window: &mut Window, + cx: &mut Context, + ) { + let Some(terminal) = self + .active_terminal_id() + .and_then(|terminal_id| self.terminals.get_mut(&terminal_id)) + else { + cx.propagate(); + return; + }; + + let terminal_view = terminal.view.clone(); + let search_bar = terminal + .search_bar + .get_or_insert_with(|| cx.new(|cx| BufferSearchBar::new(None, window, cx))) + .clone(); + let deployed = search_bar.update(cx, |search_bar, cx| { + let terminal_item: &dyn ItemHandle = &terminal_view; + search_bar.set_active_pane_item(Some(terminal_item), window, cx); + search_bar.deploy(&DeployBufferSearch::find(), None, window, cx) + }); + if deployed { + cx.stop_propagation(); + } else { + cx.propagate(); + } + } + pub fn conversation_view_for_id( &self, thread_id: &ThreadId, @@ -6415,6 +6449,7 @@ impl Render for AgentPanel { .on_action(cx.listener(Self::decrease_font_size)) .on_action(cx.listener(Self::reset_font_size)) .on_action(cx.listener(Self::toggle_zoom)) + .on_action(cx.listener(Self::toggle_terminal_thread_search)) .on_action(cx.listener(|this, _: &ReauthenticateAgent, window, cx| { if let Some(conversation_view) = this.active_conversation_view() { conversation_view.update(cx, |conversation_view, cx| { @@ -6439,9 +6474,35 @@ impl Render for AgentPanel { VisibleSurface::AgentThread(conversation_view) => parent .child(conversation_view.clone()) .child(self.render_drag_target(cx)), - VisibleSurface::Terminal(terminal_view) => parent - .child(terminal_view.clone()) - .child(self.render_drag_target(cx)), + VisibleSurface::Terminal(terminal_view) => { + let search_bar = self + .active_terminal_id() + .and_then(|terminal_id| self.terminals.get(&terminal_id)) + .and_then(|terminal| terminal.search_bar.clone()); + let terminal_content = v_flex() + .key_context("AgentTerminalThread") + .size_full() + .when_some(search_bar, |this, search_bar| { + this.when(!search_bar.read(cx).is_dismissed(), |this| { + this.child( + v_flex() + .group("toolbar") + .relative() + .py(DynamicSpacing::Base06.rems(cx)) + .px(DynamicSpacing::Base08.rems(cx)) + .border_b_1() + .border_color(cx.theme().colors().border_variant) + .bg(cx.theme().colors().toolbar_background) + .child(search_bar), + ) + }) + }) + .child(terminal_view.clone()); + + parent + .child(terminal_content) + .child(self.render_drag_target(cx)) + } }) .children(self.render_trial_end_upsell(window, cx));