vim fixes for find&replace (#2995)

Conrad Irwin created

* allow replacing with the empty string to delete
* fix <enter> for ReplaceNext (in vim mode)

Release Notes:

- allow replacement to be empty

Change summary

assets/keymaps/vim.json            |  2 +-
crates/project/src/search.rs       |  4 ++--
crates/search/src/buffer_search.rs | 27 +++++++++++++--------------
3 files changed, 16 insertions(+), 17 deletions(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -531,7 +531,7 @@
     }
   },
   {
-    "context": "BufferSearchBar > VimEnabled",
+    "context": "BufferSearchBar && !in_replace > VimEnabled",
     "bindings": {
       "enter": "vim::SearchSubmit",
       "escape": "buffer_search::Dismiss"

crates/project/src/search.rs 🔗

@@ -159,7 +159,7 @@ impl SearchQuery {
             )
         }
     }
-    pub fn with_replacement(mut self, new_replacement: Option<String>) -> Self {
+    pub fn with_replacement(mut self, new_replacement: String) -> Self {
         match self {
             Self::Text {
                 ref mut replacement,
@@ -169,7 +169,7 @@ impl SearchQuery {
                 ref mut replacement,
                 ..
             } => {
-                *replacement = new_replacement;
+                *replacement = Some(new_replacement);
                 self
             }
         }

crates/search/src/buffer_search.rs 🔗

@@ -774,8 +774,7 @@ impl BufferSearchBar {
                         Vec::new(),
                         Vec::new(),
                     ) {
-                        Ok(query) => query
-                            .with_replacement(Some(self.replacement(cx)).filter(|s| !s.is_empty())),
+                        Ok(query) => query.with_replacement(self.replacement(cx)),
                         Err(_) => {
                             self.query_contains_error = true;
                             cx.notify();
@@ -790,8 +789,7 @@ impl BufferSearchBar {
                         Vec::new(),
                         Vec::new(),
                     ) {
-                        Ok(query) => query
-                            .with_replacement(Some(self.replacement(cx)).filter(|s| !s.is_empty())),
+                        Ok(query) => query.with_replacement(self.replacement(cx)),
                         Err(_) => {
                             self.query_contains_error = true;
                             cx.notify();
@@ -904,6 +902,9 @@ impl BufferSearchBar {
                 if let Some(_) = &bar.active_searchable_item {
                     should_propagate = false;
                     bar.replace_is_active = !bar.replace_is_active;
+                    if bar.dismissed {
+                        bar.show(cx);
+                    }
                     cx.notify();
                 }
             });
@@ -921,14 +922,13 @@ impl BufferSearchBar {
                         .get(&searchable_item.downgrade())
                     {
                         if let Some(active_index) = self.active_match_index {
-                            let query = query.as_ref().clone().with_replacement(
-                                Some(self.replacement(cx)).filter(|rep| !rep.is_empty()),
-                            );
+                            let query = query
+                                .as_ref()
+                                .clone()
+                                .with_replacement(self.replacement(cx));
                             searchable_item.replace(&matches[active_index], &query, cx);
                             self.select_next_match(&SelectNextMatch, cx);
                         }
-
-                        self.focus_editor(&FocusEditor, cx);
                     }
                 }
             }
@@ -942,14 +942,13 @@ impl BufferSearchBar {
                         .searchable_items_with_matches
                         .get(&searchable_item.downgrade())
                     {
-                        let query = query.as_ref().clone().with_replacement(
-                            Some(self.replacement(cx)).filter(|rep| !rep.is_empty()),
-                        );
+                        let query = query
+                            .as_ref()
+                            .clone()
+                            .with_replacement(self.replacement(cx));
                         for m in matches {
                             searchable_item.replace(m, &query, cx);
                         }
-
-                        self.focus_editor(&FocusEditor, cx);
                     }
                 }
             }