summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/text-edit
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/text-edit')
-rw-r--r--src/tools/rust-analyzer/crates/text-edit/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/text-edit/src/lib.rs52
2 files changed, 53 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/text-edit/Cargo.toml b/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
index 337cd2347..76d0ca5cc 100644
--- a/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
@@ -13,4 +13,4 @@ doctest = false
[dependencies]
itertools = "0.10.5"
-text-size = "1.1.0"
+text-size.workspace = true
diff --git a/src/tools/rust-analyzer/crates/text-edit/src/lib.rs b/src/tools/rust-analyzer/crates/text-edit/src/lib.rs
index 9bb4271b6..4705d1818 100644
--- a/src/tools/rust-analyzer/crates/text-edit/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/text-edit/src/lib.rs
@@ -176,6 +176,7 @@ impl TextEditBuilder {
pub fn finish(self) -> TextEdit {
let mut indels = self.indels;
assert_disjoint_or_equal(&mut indels);
+ indels = coalesce_indels(indels);
TextEdit { indels }
}
pub fn invalidates_offset(&self, offset: TextSize) -> bool {
@@ -205,6 +206,21 @@ where
indels.clone().zip(indels.skip(1)).all(|(l, r)| l.delete.end() <= r.delete.start() || l == r)
}
+fn coalesce_indels(indels: Vec<Indel>) -> Vec<Indel> {
+ indels
+ .into_iter()
+ .coalesce(|mut a, b| {
+ if a.delete.end() == b.delete.start() {
+ a.insert.push_str(&b.insert);
+ a.delete = TextRange::new(a.delete.start(), b.delete.end());
+ Ok(a)
+ } else {
+ Err((a, b))
+ }
+ })
+ .collect_vec()
+}
+
#[cfg(test)]
mod tests {
use super::{TextEdit, TextEditBuilder, TextRange};
@@ -261,4 +277,40 @@ mod tests {
let edit2 = TextEdit::delete(range(9, 13));
assert!(edit1.union(edit2).is_err());
}
+
+ #[test]
+ fn test_coalesce_disjoint() {
+ let mut builder = TextEditBuilder::default();
+ builder.replace(range(1, 3), "aa".into());
+ builder.replace(range(5, 7), "bb".into());
+ let edit = builder.finish();
+
+ assert_eq!(edit.indels.len(), 2);
+ }
+
+ #[test]
+ fn test_coalesce_adjacent() {
+ let mut builder = TextEditBuilder::default();
+ builder.replace(range(1, 3), "aa".into());
+ builder.replace(range(3, 5), "bb".into());
+
+ let edit = builder.finish();
+ assert_eq!(edit.indels.len(), 1);
+ assert_eq!(edit.indels[0].insert, "aabb");
+ assert_eq!(edit.indels[0].delete, range(1, 5));
+ }
+
+ #[test]
+ fn test_coalesce_adjacent_series() {
+ let mut builder = TextEditBuilder::default();
+ builder.replace(range(1, 3), "au".into());
+ builder.replace(range(3, 5), "www".into());
+ builder.replace(range(5, 8), "".into());
+ builder.replace(range(8, 9), "ub".into());
+
+ let edit = builder.finish();
+ assert_eq!(edit.indels.len(), 1);
+ assert_eq!(edit.indels[0].insert, "auwwwub");
+ assert_eq!(edit.indels[0].delete, range(1, 9));
+ }
}