Explore registrar-based API for search bar.

This commit adds a Registrar trait for use by search crate. Registrar can register actions on some target and search can utilize that trait to opaquely add actions on that target.
Notably, search is now opt-in (it always was in zed2 actually). Having editor doesn't make it searchable straight out of the gate. You might have to call BufferSearchBar::new a bunch more.
This commit is contained in:
Piotr Osiewicz 2024-01-04 14:56:35 +01:00
parent cd0b15e23d
commit f70eddc988
2 changed files with 125 additions and 69 deletions

View file

@ -3,11 +3,13 @@ use std::{path::PathBuf, sync::Arc};
use crate::TerminalView;
use db::kvp::KEY_VALUE_STORE;
use gpui::{
actions, div, serde_json, AppContext, AsyncWindowContext, Entity, EventEmitter, ExternalPaths,
FocusHandle, FocusableView, IntoElement, ParentElement, Pixels, Render, Styled, Subscription,
Task, View, ViewContext, VisualContext, WeakView, WindowContext,
actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter,
ExternalPaths, FocusHandle, FocusableView, InteractiveElement, IntoElement, ParentElement,
Pixels, Render, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
WindowContext,
};
use project::Fs;
use search::{buffer_search::SearchActionsRegistrar, BufferSearchBar};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
@ -17,6 +19,7 @@ use workspace::{
dock::{DockPosition, Panel, PanelEvent},
item::Item,
pane,
searchable::SearchableItem,
ui::Icon,
Pane, Workspace,
};
@ -328,9 +331,36 @@ impl TerminalPanel {
impl EventEmitter<PanelEvent> for TerminalPanel {}
struct ActionsRegistrar<'a, 'b>
where
'b: 'a,
{
div: Option<Div>,
cx: &'a mut ViewContext<'b, TerminalPanel>,
}
impl SearchActionsRegistrar for ActionsRegistrar<'_, '_> {
fn register_handler<A: gpui::Action>(
&mut self,
callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
) {
self.div = self.div.take().map(|div| {
div.on_action(self.cx.listener(move |this, action, cx| {
this.pane
.read(cx)
.toolbar()
.read(cx)
.item_of_type::<BufferSearchBar>()
.map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx)));
}))
});
}
}
impl Render for TerminalPanel {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
div().size_full().child(self.pane.clone())
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let div = div();
let mut registrar = ActionsRegistrar { div: Some(div), cx };
BufferSearchBar::register_inner(&mut registrar, &TerminalView::supported_options());
registrar.div.unwrap().size_full().child(self.pane.clone())
}
}