mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-03 06:30:00 -06:00
Keep paragraph styles aligned in Find and Replace with line breaks
Found while testing crates/engine/src/cmd/typemenu.rs:668 (find_replace / edit_runs) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Haiku 5.5
parent
f14f8d8eb7
commit
ee6cd6de55
@@ -665,16 +665,39 @@ fn find_replace(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if total == 0 {
|
||||
return Ok(json!({ "count": 0 }));
|
||||
}
|
||||
edit_runs::<()>(s, "Replace", &ids, |text, _| {
|
||||
let mut out = String::with_capacity(text.len());
|
||||
let mut last = 0;
|
||||
for (a, b) in find_all(text, &find, mc, ww) {
|
||||
out.push_str(&text[last..a]);
|
||||
out.push_str(&rep);
|
||||
last = b;
|
||||
super::overprint::edit_counted(s, "Replace", |d| {
|
||||
let mut changed = 0;
|
||||
for id in &ids {
|
||||
let Some(NodeKind::Text(t)) = d.node_mut(*id).map(|n| &mut n.kind) else { continue };
|
||||
// Matches as (run, start, end) with offsets inside the run. Inline graphics are art, not
|
||||
// characters to rewrite.
|
||||
let mut hits = vec![];
|
||||
let mut base = 0;
|
||||
for (ri, r) in t.runs.iter().enumerate() {
|
||||
if r.inline.is_none() {
|
||||
for (a, b) in find_all(&r.text, &find, mc, ww) {
|
||||
if r.text.get(a..b) != Some(rep.as_str()) {
|
||||
hits.push((ri, base + a, base + b, a, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
base += r.text.len();
|
||||
}
|
||||
if hits.is_empty() {
|
||||
continue;
|
||||
}
|
||||
// Last match first, so the offsets of earlier ones stay valid. The paragraph styles follow
|
||||
// each edit, as `text.editRange` does.
|
||||
for (ri, ta, tb, a, b) in hits.into_iter().rev() {
|
||||
t.splice_paras(ta, tb, &rep);
|
||||
if let Some(r) = t.runs.get_mut(ri) {
|
||||
r.text.replace_range(a..b, &rep);
|
||||
}
|
||||
}
|
||||
changed += 1;
|
||||
refresh_bounds(t);
|
||||
}
|
||||
out.push_str(&text[last..]);
|
||||
out
|
||||
Ok(changed)
|
||||
})?;
|
||||
Ok(json!({ "count": total }))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user