@@ -1102,6 +1102,35 @@ impl SearchableItem for Editor {
});
}
}
+ fn replace_all(
+ &mut self,
+ matches: &mut dyn Iterator<Item = &Self::Match>,
+ query: &SearchQuery,
+ cx: &mut ViewContext<Self>,
+ ) {
+ let text = self.buffer.read(cx);
+ let text = text.snapshot(cx);
+ let mut edits = vec![];
+ for m in matches {
+ let text = text.text_for_range(m.clone()).collect::<Vec<_>>();
+ let text: Cow<_> = if text.len() == 1 {
+ text.first().cloned().unwrap().into()
+ } else {
+ let joined_chunks = text.join("");
+ joined_chunks.into()
+ };
+
+ if let Some(replacement) = query.replacement_for(&text) {
+ edits.push((m.clone(), Arc::from(&*replacement)));
+ }
+ }
+
+ if !edits.is_empty() {
+ self.transact(cx, |this, cx| {
+ this.edit(edits, cx);
+ });
+ }
+ }
fn match_index_for_direction(
&mut self,
matches: &[Range<Anchor>],
@@ -1122,9 +1122,7 @@ impl BufferSearchBar {
.as_ref()
.clone()
.with_replacement(self.replacement(cx));
- for m in matches {
- searchable_item.replace(m, &query, cx);
- }
+ searchable_item.replace_all(&mut matches.iter(), &query, cx);
}
}
}
@@ -591,9 +591,7 @@ impl ProjectSearchView {
}
self.results_editor.update(cx, |editor, cx| {
- for item in &match_ranges {
- editor.replace(item, &query, cx);
- }
+ editor.replace_all(&mut match_ranges.iter(), &query, cx);
});
self.model.update(cx, |model, _cx| {
@@ -71,6 +71,16 @@ pub trait SearchableItem: Item + EventEmitter<SearchEvent> {
fn activate_match(&mut self, index: usize, matches: &[Self::Match], cx: &mut ViewContext<Self>);
fn select_matches(&mut self, matches: &[Self::Match], cx: &mut ViewContext<Self>);
fn replace(&mut self, _: &Self::Match, _: &SearchQuery, _: &mut ViewContext<Self>);
+ fn replace_all(
+ &mut self,
+ matches: &mut dyn Iterator<Item = &Self::Match>,
+ query: &SearchQuery,
+ cx: &mut ViewContext<Self>,
+ ) {
+ for item in matches {
+ self.replace(item, query, cx);
+ }
+ }
fn match_index_for_direction(
&mut self,
matches: &[Self::Match],
@@ -123,6 +133,12 @@ pub trait SearchableItemHandle: ItemHandle {
_: &SearchQuery,
_: &mut WindowContext,
);
+ fn replace_all(
+ &self,
+ matches: &mut dyn Iterator<Item = any_vec::element::ElementRef<'_, dyn Send>>,
+ query: &SearchQuery,
+ cx: &mut WindowContext,
+ );
fn match_index_for_direction(
&self,
matches: &AnyVec<dyn Send>,
@@ -241,6 +257,17 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
self.update(cx, |this, cx| this.replace(mat, query, cx))
}
+ fn replace_all(
+ &self,
+ matches: &mut dyn Iterator<Item = any_vec::element::ElementRef<'_, dyn Send>>,
+ query: &SearchQuery,
+ cx: &mut WindowContext,
+ ) {
+ self.update(cx, |this, cx| {
+ this.replace_all(&mut matches.map(|m| m.downcast_ref().unwrap()), query, cx);
+ })
+ }
+
fn search_bar_visibility_changed(&self, visible: bool, cx: &mut WindowContext) {
self.update(cx, |this, cx| {
this.search_bar_visibility_changed(visible, cx)