@@ -38,7 +38,7 @@ use gpui::{
};
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, ToOffset as _};
use project::Project;
-use search::{buffer_search::SearchActionsRegistrar, BufferSearchBar};
+use search::{buffer_search::DivRegistrar, BufferSearchBar};
use semantic_index::{SemanticIndex, SemanticIndexStatus};
use settings::{Settings, SettingsStore};
use std::{
@@ -1100,26 +1100,6 @@ fn build_api_key_editor(cx: &mut ViewContext<AssistantPanel>) -> View<Editor> {
})
}
-struct SearchRegistrar<'a, 'b> {
- div: Option<Div>,
- cx: &'a mut ViewContext<'b, AssistantPanel>,
-}
-
-impl SearchActionsRegistrar for SearchRegistrar<'_, '_> {
- fn register_handler<A: 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.toolbar
- .read(cx)
- .item_of_type::<BufferSearchBar>()
- .map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx)));
- }))
- });
- }
-}
impl Render for AssistantPanel {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
if let Some(api_key_editor) = self.api_key_editor.clone() {
@@ -1177,12 +1157,12 @@ impl Render for AssistantPanel {
});
let contents = if self.active_editor().is_some() {
- let mut registrar = SearchRegistrar {
- div: Some(div()),
+ let mut registrar = DivRegistrar::new(
+ |panel, cx| panel.toolbar.read(cx).item_of_type::<BufferSearchBar>(),
cx,
- };
+ );
BufferSearchBar::register_inner(&mut registrar);
- registrar.div.unwrap()
+ registrar.into_div()
} else {
div()
};
@@ -430,6 +430,46 @@ pub trait SearchActionsRegistrar {
);
}
+type GetSearchBar<T> =
+ for<'a, 'b> fn(&'a T, &'a mut ViewContext<'b, T>) -> Option<View<BufferSearchBar>>;
+
+/// Registers search actions on a div that can be taken out.
+pub struct DivRegistrar<'a, 'b, T: 'static> {
+ div: Option<Div>,
+ cx: &'a mut ViewContext<'b, T>,
+ search_getter: GetSearchBar<T>,
+}
+
+impl<'a, 'b, T: 'static> DivRegistrar<'a, 'b, T> {
+ pub fn new(search_getter: GetSearchBar<T>, cx: &'a mut ViewContext<'b, T>) -> Self {
+ Self {
+ div: Some(div()),
+ cx,
+ search_getter,
+ }
+ }
+ pub fn into_div(self) -> Div {
+ // This option is always Some; it's an option in the first place because we want to call methods
+ // on div that require ownership.
+ self.div.unwrap()
+ }
+}
+
+impl<T: 'static> SearchActionsRegistrar for DivRegistrar<'_, '_, T> {
+ fn register_handler<A: gpui::Action>(
+ &mut self,
+ callback: fn(&mut BufferSearchBar, &A, &mut ViewContext<BufferSearchBar>),
+ ) {
+ let getter = self.search_getter;
+ self.div = self.div.take().map(|div| {
+ div.on_action(self.cx.listener(move |this, action, cx| {
+ (getter)(this, cx)
+ .clone()
+ .map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx)));
+ }))
+ });
+ }
+}
impl BufferSearchBar {
pub fn register_inner(registrar: &mut impl SearchActionsRegistrar) {
registrar.register_handler(|this, action: &ToggleCaseSensitive, cx| {
@@ -3,13 +3,12 @@ use std::{path::PathBuf, sync::Arc};
use crate::TerminalView;
use db::kvp::KEY_VALUE_STORE;
use gpui::{
- 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,
+ actions, serde_json, AppContext, AsyncWindowContext, Entity, EventEmitter, ExternalPaths,
+ FocusHandle, FocusableView, IntoElement, ParentElement, Pixels, Render, Styled, Subscription,
+ Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use project::Fs;
-use search::{buffer_search::SearchActionsRegistrar, BufferSearchBar};
+use search::{buffer_search::DivRegistrar, BufferSearchBar};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
@@ -330,36 +329,21 @@ 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
+impl Render for TerminalPanel {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
+ let mut registrar = DivRegistrar::new(
+ |panel, cx| {
+ panel
+ .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 {
- let div = div();
- let mut registrar = ActionsRegistrar { div: Some(div), cx };
+ },
+ cx,
+ );
BufferSearchBar::register_inner(&mut registrar);
- registrar.div.unwrap().size_full().child(self.pane.clone())
+ registrar.into_div().size_full().child(self.pane.clone())
}
}