editor: Use less memory when replacing literal strings (#46092)

Found while profiling #38927

When the query is not a regex, the same replacement can be applied to
all matches. Previously, `replacement_for` allocated a new String on
every call, while `replacement` returns a reference.

Release Notes:

- N/A

---------

Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
This commit is contained in:
Marco Mihai Condrache 2026-01-06 00:14:31 +01:00 committed by GitHub
parent 778609f686
commit f35e67894d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1682,19 +1682,27 @@ impl SearchableItem for Editor {
let text = text.snapshot(cx);
let mut edits = vec![];
for m in matches {
let text = text.text_for_range(m.clone()).collect::<Vec<_>>();
// A regex might have replacement variables so we cannot apply
// the same replacement to all matches
if query.is_regex() {
edits = matches
.filter_map(|m| {
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()
};
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)));
}
query
.replacement_for(&text)
.map(|replacement| (m.clone(), Arc::from(&*replacement)))
})
.collect();
} else if let Some(replacement) = query.replacement().map(Arc::<str>::from) {
edits = matches.map(|m| (m.clone(), replacement.clone())).collect();
}
if !edits.is_empty() {