agent panel: Bring back search within text threads (#29934)

Michael Sloan created

Release Notes:

- N/A

Change summary

Cargo.lock                          |  1 
crates/agent/Cargo.toml             |  3 
crates/agent/src/assistant_panel.rs | 64 ++++++++++++++++++++++++++++--
3 files changed, 62 insertions(+), 6 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -106,6 +106,7 @@ dependencies = [
  "rope",
  "rules_library",
  "schemars",
+ "search",
  "serde",
  "serde_json",
  "serde_json_lenient",

crates/agent/Cargo.toml 🔗

@@ -64,13 +64,14 @@ paths.workspace = true
 picker.workspace = true
 postage.workspace = true
 project.workspace = true
-rules_library.workspace = true
 prompt_store.workspace = true
 proto.workspace = true
 ref-cast.workspace = true
 release_channel.workspace = true
 rope.workspace = true
+rules_library.workspace = true
 schemars.workspace = true
+search.workspace = true
 serde.workspace = true
 serde_json.workspace = true
 serde_json_lenient.workspace = true

crates/agent/src/assistant_panel.rs 🔗

@@ -31,6 +31,7 @@ use project::Project;
 use prompt_store::{PromptBuilder, PromptStore, UserPromptId};
 use proto::Plan;
 use rules_library::{RulesLibrary, open_rules_library};
+use search::{BufferSearchBar, buffer_search::DivRegistrar};
 use settings::{Settings, update_settings_file};
 use time::UtcOffset;
 use ui::{
@@ -39,7 +40,7 @@ use ui::{
 };
 use util::ResultExt as _;
 use workspace::dock::{DockPosition, Panel, PanelEvent};
-use workspace::{CollaboratorId, Workspace};
+use workspace::{CollaboratorId, ToolbarItemView, Workspace};
 use zed_actions::agent::OpenConfiguration;
 use zed_actions::assistant::{OpenRulesLibrary, ToggleFocus};
 use zed_llm_client::UsageLimit;
@@ -151,6 +152,7 @@ enum ActiveView {
     PromptEditor {
         context_editor: Entity<ContextEditor>,
         title_editor: Entity<Editor>,
+        buffer_search_bar: Entity<BufferSearchBar>,
         _subscriptions: Vec<gpui::Subscription>,
     },
     History,
@@ -216,6 +218,7 @@ impl ActiveView {
 
     pub fn prompt_editor(
         context_editor: Entity<ContextEditor>,
+        language_registry: Arc<LanguageRegistry>,
         window: &mut Window,
         cx: &mut App,
     ) -> Self {
@@ -284,9 +287,16 @@ impl ActiveView {
             }),
         ];
 
+        let buffer_search_bar =
+            cx.new(|cx| BufferSearchBar::new(Some(language_registry), window, cx));
+        buffer_search_bar.update(cx, |buffer_search_bar, cx| {
+            buffer_search_bar.set_active_pane_item(Some(&context_editor), window, cx)
+        });
+
         Self::PromptEditor {
             context_editor,
             title_editor: editor,
+            buffer_search_bar,
             _subscriptions: subscriptions,
         }
     }
@@ -785,7 +795,12 @@ impl AssistantPanel {
         });
 
         self.set_active_view(
-            ActiveView::prompt_editor(context_editor.clone(), window, cx),
+            ActiveView::prompt_editor(
+                context_editor.clone(),
+                self.language_registry.clone(),
+                window,
+                cx,
+            ),
             window,
             cx,
         );
@@ -861,7 +876,12 @@ impl AssistantPanel {
                 });
 
                 this.set_active_view(
-                    ActiveView::prompt_editor(editor.clone(), window, cx),
+                    ActiveView::prompt_editor(
+                        editor.clone(),
+                        this.language_registry.clone(),
+                        window,
+                        cx,
+                    ),
                     window,
                     cx,
                 );
@@ -2314,8 +2334,42 @@ impl Render for AssistantPanel {
                     .child(h_flex().child(self.message_editor.clone()))
                     .children(self.render_last_error(cx)),
                 ActiveView::History => parent.child(self.history.clone()),
-                ActiveView::PromptEditor { context_editor, .. } => {
-                    parent.child(context_editor.clone())
+                ActiveView::PromptEditor {
+                    context_editor,
+                    buffer_search_bar,
+                    ..
+                } => {
+                    let mut registrar = DivRegistrar::new(
+                        |this, _, _cx| match &this.active_view {
+                            ActiveView::PromptEditor {
+                                buffer_search_bar, ..
+                            } => Some(buffer_search_bar.clone()),
+                            _ => None,
+                        },
+                        cx,
+                    );
+                    BufferSearchBar::register(&mut registrar);
+                    parent.child(
+                        registrar
+                            .into_div()
+                            .size_full()
+                            .map(|parent| {
+                                buffer_search_bar.update(cx, |buffer_search_bar, cx| {
+                                    if buffer_search_bar.is_dismissed() {
+                                        return parent;
+                                    }
+                                    parent.child(
+                                        div()
+                                            .p(DynamicSpacing::Base08.rems(cx))
+                                            .border_b_1()
+                                            .border_color(cx.theme().colors().border_variant)
+                                            .bg(cx.theme().colors().editor_background)
+                                            .child(buffer_search_bar.render(window, cx)),
+                                    )
+                                })
+                            })
+                            .child(context_editor.clone()),
+                    )
                 }
                 ActiveView::Configuration => parent.children(self.configuration.clone()),
             })