From 5b5ebec440841ee98a0aa70b71a135d94f5ca077 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 May 2020 19:50:23 +0200 Subject: Formalize JoinLines protocol extension --- crates/ra_text_edit/src/lib.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'crates/ra_text_edit') diff --git a/crates/ra_text_edit/src/lib.rs b/crates/ra_text_edit/src/lib.rs index 199fd1096..25554f583 100644 --- a/crates/ra_text_edit/src/lib.rs +++ b/crates/ra_text_edit/src/lib.rs @@ -17,7 +17,7 @@ pub struct Indel { pub delete: TextRange, } -#[derive(Debug, Clone)] +#[derive(Default, Debug, Clone)] pub struct TextEdit { indels: Vec, } @@ -64,14 +64,6 @@ impl TextEdit { builder.finish() } - pub(crate) fn from_indels(mut indels: Vec) -> TextEdit { - indels.sort_by_key(|a| (a.delete.start(), a.delete.end())); - for (a1, a2) in indels.iter().zip(indels.iter().skip(1)) { - assert!(a1.delete.end() <= a2.delete.start()) - } - TextEdit { indels } - } - pub fn len(&self) -> usize { self.indels.len() } @@ -122,6 +114,17 @@ impl TextEdit { *text = buf } + pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> { + // FIXME: can be done without allocating intermediate vector + let mut all = self.iter().chain(other.iter()).collect::>(); + if !check_disjoint(&mut all) { + return Err(other); + } + self.indels.extend(other.indels); + assert!(check_disjoint(&mut self.indels)); + Ok(()) + } + pub fn apply_to_offset(&self, offset: TextSize) -> Option { let mut res = offset; for indel in self.indels.iter() { @@ -149,9 +152,19 @@ impl TextEditBuilder { self.indels.push(Indel::insert(offset, text)) } pub fn finish(self) -> TextEdit { - TextEdit::from_indels(self.indels) + let mut indels = self.indels; + assert!(check_disjoint(&mut indels)); + TextEdit { indels } } pub fn invalidates_offset(&self, offset: TextSize) -> bool { self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset)) } } + +fn check_disjoint(indels: &mut [impl std::borrow::Borrow]) -> bool { + indels.sort_by_key(|indel| (indel.borrow().delete.start(), indel.borrow().delete.end())); + indels + .iter() + .zip(indels.iter().skip(1)) + .all(|(l, r)| l.borrow().delete.end() <= r.borrow().delete.start()) +} -- cgit v1.2.3