search_bar: Add toggle_replace_on_a_pane. (#2966)

Piotr Osiewicz created

This allows users to add a keybind to ToggleReplace from Editor/Pane
contexts.

Release Notes:
- Fixed replace in buffer not reacting to keyboard shortcuts outside of
search bar<preview-only>.

Change summary

crates/search/src/buffer_search.rs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

Detailed changes

crates/search/src/buffer_search.rs 🔗

@@ -56,6 +56,7 @@ pub fn init(cx: &mut AppContext) {
     cx.add_action(BufferSearchBar::replace_all_on_pane);
     cx.add_action(BufferSearchBar::replace_next_on_pane);
     cx.add_action(BufferSearchBar::toggle_replace);
+    cx.add_action(BufferSearchBar::toggle_replace_on_a_pane);
     add_toggle_option_action::<ToggleCaseSensitive>(SearchOptions::CASE_SENSITIVE, cx);
     add_toggle_option_action::<ToggleWholeWord>(SearchOptions::WHOLE_WORD, cx);
 }
@@ -889,6 +890,21 @@ impl BufferSearchBar {
             cx.notify();
         }
     }
+    fn toggle_replace_on_a_pane(pane: &mut Pane, _: &ToggleReplace, cx: &mut ViewContext<Pane>) {
+        let mut should_propagate = true;
+        if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
+            search_bar.update(cx, |bar, cx| {
+                if let Some(_) = &bar.active_searchable_item {
+                    should_propagate = false;
+                    bar.replace_is_active = !bar.replace_is_active;
+                    cx.notify();
+                }
+            });
+        }
+        if should_propagate {
+            cx.propagate_action();
+        }
+    }
     fn replace_next(&mut self, _: &ReplaceNext, cx: &mut ViewContext<Self>) {
         if !self.dismissed && self.active_search.is_some() {
             if let Some(searchable_item) = self.active_searchable_item.as_ref() {
@@ -934,12 +950,16 @@ impl BufferSearchBar {
     fn replace_next_on_pane(pane: &mut Pane, action: &ReplaceNext, cx: &mut ViewContext<Pane>) {
         if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
             search_bar.update(cx, |bar, cx| bar.replace_next(action, cx));
+            return;
         }
+        cx.propagate_action();
     }
     fn replace_all_on_pane(pane: &mut Pane, action: &ReplaceAll, cx: &mut ViewContext<Pane>) {
         if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
             search_bar.update(cx, |bar, cx| bar.replace_all(action, cx));
+            return;
         }
+        cx.propagate_action();
     }
 }