diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 14703be7a22b5e6580202553976343e8e6a2c970..60e88e9d27b0d9fd29fcb08c77cf933522353b28 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -3,7 +3,8 @@ mod registrar; use crate::{ FocusSearch, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOptions, SelectAllMatches, SelectNextMatch, SelectPreviousMatch, ToggleCaseSensitive, ToggleRegex, - ToggleReplace, ToggleSelection, ToggleWholeWord, search_bar::render_nav_button, + ToggleReplace, ToggleSelection, ToggleWholeWord, + search_bar::{input_base_styles, render_nav_button, toggle_replace_button}, }; use any_vec::AnyVec; use anyhow::Context as _; @@ -238,18 +239,8 @@ impl Render for BufferSearchBar { let container_width = window.viewport_size().width; let input_width = SearchInputWidth::calc_width(container_width); - let input_base_styles = |border_color| { - h_flex() - .min_w_32() - .w(input_width) - .h_8() - .pl_2() - .pr_1() - .py_1() - .border_1() - .border_color(border_color) - .rounded_lg() - }; + let input_base_styles = + |border_color| input_base_styles(border_color, |div| div.w(input_width)); let search_line = h_flex() .gap_2() @@ -304,33 +295,14 @@ impl Render for BufferSearchBar { .gap_1() .min_w_64() .when(supported_options.replacement, |this| { - this.child( - IconButton::new( - "buffer-search-bar-toggle-replace-button", - IconName::Replace, - ) - .style(ButtonStyle::Subtle) - .shape(IconButtonShape::Square) - .when(self.replace_enabled, |button| { - button.style(ButtonStyle::Filled) - }) - .on_click(cx.listener(|this, _: &ClickEvent, window, cx| { + this.child(toggle_replace_button( + "buffer-search-bar-toggle-replace-button", + focus_handle.clone(), + self.replace_enabled, + cx.listener(|this, _: &ClickEvent, window, cx| { this.toggle_replace(&ToggleReplace, window, cx); - })) - .toggle_state(self.replace_enabled) - .tooltip({ - let focus_handle = focus_handle.clone(); - move |window, cx| { - Tooltip::for_action_in( - "Toggle Replace", - &ToggleReplace, - &focus_handle, - window, - cx, - ) - } }), - ) + )) }) .when(supported_options.selection, |this| { this.child( diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 96194cdad2d5f42146c28dfdd2730f2c848cd9a2..a1fa2931bbbb8deb0ca267ebd020f8712d3b0e0f 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1,7 +1,9 @@ use crate::{ BufferSearchBar, FocusSearch, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOptions, SelectNextMatch, SelectPreviousMatch, ToggleCaseSensitive, ToggleIncludeIgnored, - ToggleRegex, ToggleReplace, ToggleWholeWord, buffer_search::Deploy, + ToggleRegex, ToggleReplace, ToggleWholeWord, + buffer_search::Deploy, + search_bar::{input_base_styles, toggle_replace_button}, }; use anyhow::Context as _; use collections::{HashMap, HashSet}; @@ -1965,19 +1967,10 @@ impl Render for ProjectSearchBar { } let input_base_styles = |base_style: BaseStyle, panel: InputPanel| { - h_flex() - .min_w_32() - .map(|div| match base_style { - BaseStyle::SingleInput => div.w(input_width), - BaseStyle::MultipleInputs => div.flex_grow(), - }) - .h_8() - .pl_2() - .pr_1() - .py_1() - .border_1() - .border_color(search.border_color_for(panel, cx)) - .rounded_lg() + input_base_styles(search.border_color_for(panel, cx), |div| match base_style { + BaseStyle::SingleInput => div.w(input_width), + BaseStyle::MultipleInputs => div.flex_grow(), + }) }; let query_column = input_base_styles(BaseStyle::SingleInput, InputPanel::Query) @@ -2045,31 +2038,17 @@ impl Render for ProjectSearchBar { } }), ) - .child( - IconButton::new("project-search-toggle-replace", IconName::Replace) - .shape(IconButtonShape::Square) - .on_click(cx.listener(|this, _, window, cx| { - this.toggle_replace(&ToggleReplace, window, cx); - })) - .toggle_state( - self.active_project_search - .as_ref() - .map(|search| search.read(cx).replace_enabled) - .unwrap_or_default(), - ) - .tooltip({ - let focus_handle = focus_handle.clone(); - move |window, cx| { - Tooltip::for_action_in( - "Toggle Replace", - &ToggleReplace, - &focus_handle, - window, - cx, - ) - } - }), - ); + .child(toggle_replace_button( + "project-search-toggle-replace", + focus_handle.clone(), + self.active_project_search + .as_ref() + .map(|search| search.read(cx).replace_enabled) + .unwrap_or_default(), + cx.listener(|this, _, window, cx| { + this.toggle_replace(&ToggleReplace, window, cx); + }), + )); let limit_reached = search.entity.read(cx).limit_reached; diff --git a/crates/search/src/search_bar.rs b/crates/search/src/search_bar.rs index 805664c7942470e4acab1f3364902df0aa7619c5..60d98a3a9ff78b4734ff948bc918c55b666b680f 100644 --- a/crates/search/src/search_bar.rs +++ b/crates/search/src/search_bar.rs @@ -1,7 +1,9 @@ -use gpui::{Action, FocusHandle, IntoElement}; +use gpui::{Action, FocusHandle, Hsla, IntoElement}; use ui::{IconButton, IconButtonShape}; use ui::{Tooltip, prelude::*}; +use crate::ToggleReplace; + pub(super) fn render_nav_button( icon: ui::IconName, active: bool, @@ -26,3 +28,35 @@ pub(super) fn render_nav_button( .tooltip(move |window, cx| Tooltip::for_action_in(tooltip, action, &focus_handle, window, cx)) .disabled(!active) } + +pub(crate) fn input_base_styles(border_color: Hsla, map: impl FnOnce(Div) -> Div) -> Div { + h_flex() + .min_w_32() + .map(map) + .h_8() + .pl_2() + .pr_1() + .py_1() + .border_1() + .border_color(border_color) + .rounded_lg() +} + +pub(crate) fn toggle_replace_button( + id: &'static str, + focus_handle: FocusHandle, + replace_enabled: bool, + on_click: impl Fn(&gpui::ClickEvent, &mut Window, &mut App) + 'static, +) -> IconButton { + IconButton::new(id, IconName::Replace) + .shape(IconButtonShape::Square) + .style(ButtonStyle::Subtle) + .when(replace_enabled, |button| button.style(ButtonStyle::Filled)) + .on_click(on_click) + .toggle_state(replace_enabled) + .tooltip({ + move |window, cx| { + Tooltip::for_action_in("Toggle Replace", &ToggleReplace, &focus_handle, window, cx) + } + }) +}