mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 20:11:49 +03:00
search: Improve performance of replace_all
(#13654)
Previously replace_all amounted to what could be achieved by repeatedly mashing "Replace" button, which had a bunch of overhead related to buffer state syncing. This commit gets rid of the automated button mashing, processing all of the replacements in one go. Fixes #13455 Release Notes: - Improved performance of "replace all" in buffer search and project search
This commit is contained in:
parent
b616f9c27f
commit
0761383752
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user