vim: Reset search range after substitute (#28403)

Dino created

Update the `Vim::replace_command` method so as to reset the range in the
`BufferSearchBar` after running the replacement in order to fix the
issue where the number of matches in the search bar would be incorrect
after the replacement was done, as it would only take into consideration
the range in which the replacement happened, instead of the whole
buffer.

In order to get this working a new
`BufferSearchBar::clear_search_within_ranges` method is introduced in
these changes.

Release Notes:

- Fixed the number of matches displayed in the search bar after running
vim's substitute command.

Change summary

crates/search/src/buffer_search.rs | 10 ++++++++++
crates/vim/src/normal/search.rs    | 14 +++-----------
2 files changed, 13 insertions(+), 11 deletions(-)

Detailed changes

crates/search/src/buffer_search.rs 🔗

@@ -987,6 +987,16 @@ impl BufferSearchBar {
         cx.notify();
     }
 
+    pub fn clear_search_within_ranges(
+        &mut self,
+        search_options: SearchOptions,
+        cx: &mut Context<Self>,
+    ) {
+        self.search_options = search_options;
+        self.adjust_query_regex_language(cx);
+        cx.notify();
+    }
+
     fn select_next_match(
         &mut self,
         _: &SelectNextMatch,

crates/vim/src/normal/search.rs 🔗

@@ -4,7 +4,7 @@ use language::Point;
 use schemars::JsonSchema;
 use search::{BufferSearchBar, SearchOptions, buffer_search};
 use serde_derive::Deserialize;
-use std::{iter::Peekable, str::Chars, time::Duration};
+use std::{iter::Peekable, str::Chars};
 use util::serde::default_true;
 use workspace::{notifications::NotifyResultExt, searchable::Direction};
 
@@ -484,16 +484,8 @@ impl Vim {
                 search_bar.update_in(cx, |search_bar, window, cx| {
                     search_bar.select_last_match(window, cx);
                     search_bar.replace_all(&Default::default(), window, cx);
-
-                    cx.spawn(async move |_, cx| {
-                        cx.background_executor()
-                            .timer(Duration::from_millis(200))
-                            .await;
-                        editor
-                            .update(cx, |editor, cx| editor.clear_search_within_ranges(cx))
-                            .ok();
-                    })
-                    .detach();
+                    editor.update(cx, |editor, cx| editor.clear_search_within_ranges(cx));
+                    let _ = search_bar.search(&search_bar.query(cx), None, window, cx);
                     vim.update(cx, |vim, cx| {
                         vim.move_cursor(
                             Motion::StartOfLine {