mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Auto merge of #14380 - DropDemBits:coalesce-indels, r=Veykril
internal: Coalesce adjacent Indels Originally part of working on a structured snippet API (since sometimes the `$` bit of snippets would be broken off and would lead to it not being recognized), though since this is a pretty separate change, I thought it would make sense to put it into it's own PR. The implementation is relatively straight forward and not overly optimized, though it's pretty low hanging fruit to optimize it when need be.
This commit is contained in:
commit
68aa133108
1 changed files with 52 additions and 0 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue