Skip to content

Commit 28225cc

Browse files
committed
internal: Coalesce adjacent Indels
1 parent 924d277 commit 28225cc

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

crates/text-edit/src/lib.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ impl TextEditBuilder {
176176
pub fn finish(self) -> TextEdit {
177177
let mut indels = self.indels;
178178
assert_disjoint_or_equal(&mut indels);
179+
indels = coalesce_indels(indels);
179180
TextEdit { indels }
180181
}
181182
pub fn invalidates_offset(&self, offset: TextSize) -> bool {
@@ -205,6 +206,21 @@ where
205206
indels.clone().zip(indels.skip(1)).all(|(l, r)| l.delete.end() <= r.delete.start() || l == r)
206207
}
207208

209+
fn coalesce_indels(indels: Vec<Indel>) -> Vec<Indel> {
210+
indels
211+
.into_iter()
212+
.coalesce(|mut a, b| {
213+
if a.delete.end() == b.delete.start() {
214+
a.insert.push_str(&b.insert);
215+
a.delete = TextRange::new(a.delete.start(), b.delete.end());
216+
Ok(a)
217+
} else {
218+
Err((a, b))
219+
}
220+
})
221+
.collect_vec()
222+
}
223+
208224
#[cfg(test)]
209225
mod tests {
210226
use super::{TextEdit, TextEditBuilder, TextRange};
@@ -261,4 +277,40 @@ mod tests {
261277
let edit2 = TextEdit::delete(range(9, 13));
262278
assert!(edit1.union(edit2).is_err());
263279
}
280+
281+
#[test]
282+
fn test_coalesce_disjoint() {
283+
let mut builder = TextEditBuilder::default();
284+
builder.replace(range(1, 3), "aa".into());
285+
builder.replace(range(5, 7), "bb".into());
286+
let edit = builder.finish();
287+
288+
assert_eq!(edit.indels.len(), 2);
289+
}
290+
291+
#[test]
292+
fn test_coalesce_adjacent() {
293+
let mut builder = TextEditBuilder::default();
294+
builder.replace(range(1, 3), "aa".into());
295+
builder.replace(range(3, 5), "bb".into());
296+
297+
let edit = builder.finish();
298+
assert_eq!(edit.indels.len(), 1);
299+
assert_eq!(edit.indels[0].insert, "aabb");
300+
assert_eq!(edit.indels[0].delete, range(1, 5));
301+
}
302+
303+
#[test]
304+
fn test_coalesce_adjacent_series() {
305+
let mut builder = TextEditBuilder::default();
306+
builder.replace(range(1, 3), "au".into());
307+
builder.replace(range(3, 5), "www".into());
308+
builder.replace(range(5, 8), "".into());
309+
builder.replace(range(8, 9), "ub".into());
310+
311+
let edit = builder.finish();
312+
assert_eq!(edit.indels.len(), 1);
313+
assert_eq!(edit.indels[0].insert, "auwwwub");
314+
assert_eq!(edit.indels[0].delete, range(1, 9));
315+
}
264316
}

0 commit comments

Comments
 (0)