From b6655def70599bb3d6aa8d8985b1c2e104206a26 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:03:22 +0100 Subject: [PATCH] Add DivRegistrar to reduce code duplication --- crates/assistant/src/assistant_panel.rs | 30 +++------------ crates/search/src/buffer_search.rs | 40 ++++++++++++++++++++ crates/terminal_view/src/terminal_panel.rs | 44 +++++++--------------- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index 7ab6aba227dc1cccb9957afe02144d33981ab404..371cc9007a8c1f2bc5fd013573294bcb024cc1d9 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -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) -> View { }) } -struct SearchRegistrar<'a, 'b> { - div: Option
, - cx: &'a mut ViewContext<'b, AssistantPanel>, -} - -impl SearchActionsRegistrar for SearchRegistrar<'_, '_> { - fn register_handler( - &mut self, - callback: fn(&mut BufferSearchBar, &A, &mut ViewContext), - ) { - self.div = self.div.take().map(|div| { - div.on_action(self.cx.listener(move |this, action, cx| { - this.toolbar - .read(cx) - .item_of_type::() - .map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx))); - })) - }); - } -} impl Render for AssistantPanel { fn render(&mut self, cx: &mut ViewContext) -> 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::(), cx, - }; + ); BufferSearchBar::register_inner(&mut registrar); - registrar.div.unwrap() + registrar.into_div() } else { div() }; diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 6e44db60c54d3dd6b048894d841b0bc7bdbde55a..371037e0478f62d0edd084470388c331ef29d586 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -430,6 +430,46 @@ pub trait SearchActionsRegistrar { ); } +type GetSearchBar = + for<'a, 'b> fn(&'a T, &'a mut ViewContext<'b, T>) -> Option>; + +/// Registers search actions on a div that can be taken out. +pub struct DivRegistrar<'a, 'b, T: 'static> { + div: Option
, + cx: &'a mut ViewContext<'b, T>, + search_getter: GetSearchBar, +} + +impl<'a, 'b, T: 'static> DivRegistrar<'a, 'b, T> { + pub fn new(search_getter: GetSearchBar, 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 SearchActionsRegistrar for DivRegistrar<'_, '_, T> { + fn register_handler( + &mut self, + callback: fn(&mut BufferSearchBar, &A, &mut ViewContext), + ) { + 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| { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index ed228faba8c7810657d27e6274235dfaa2ae405b..82d7208ef88ba625d8430e8f5d314a9b00cb7719 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -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 for TerminalPanel {} -struct ActionsRegistrar<'a, 'b> -where - 'b: 'a, -{ - div: Option
, - cx: &'a mut ViewContext<'b, TerminalPanel>, -} -impl SearchActionsRegistrar for ActionsRegistrar<'_, '_> { - fn register_handler( - &mut self, - callback: fn(&mut BufferSearchBar, &A, &mut ViewContext), - ) { - 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) -> impl IntoElement { + let mut registrar = DivRegistrar::new( + |panel, cx| { + panel + .pane .read(cx) .toolbar() .read(cx) .item_of_type::() - .map(|search_bar| search_bar.update(cx, |this, cx| callback(this, action, cx))); - })) - }); - } -} -impl Render for TerminalPanel { - fn render(&mut self, cx: &mut ViewContext) -> 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()) } }