From b5021411a84822cb3f1e3aeffad9550dd15bdeb6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 16 Sep 2018 12:54:24 +0300 Subject: rename all things --- crates/ra_editor/src/edit.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 crates/ra_editor/src/edit.rs (limited to 'crates/ra_editor/src/edit.rs') diff --git a/crates/ra_editor/src/edit.rs b/crates/ra_editor/src/edit.rs new file mode 100644 index 000000000..2839ac20a --- /dev/null +++ b/crates/ra_editor/src/edit.rs @@ -0,0 +1,84 @@ +use {TextRange, TextUnit}; +use ra_syntax::{ + AtomEdit, + text_utils::contains_offset_nonstrict, +}; + +#[derive(Debug, Clone)] +pub struct Edit { + atoms: Vec, +} + +#[derive(Debug)] +pub struct EditBuilder { + atoms: Vec +} + +impl EditBuilder { + pub fn new() -> EditBuilder { + EditBuilder { atoms: Vec::new() } + } + pub fn replace(&mut self, range: TextRange, replace_with: String) { + self.atoms.push(AtomEdit::replace(range, replace_with)) + } + pub fn delete(&mut self, range: TextRange) { + self.atoms.push(AtomEdit::delete(range)) + } + pub fn insert(&mut self, offset: TextUnit, text: String) { + self.atoms.push(AtomEdit::insert(offset, text)) + } + pub fn finish(self) -> Edit { + let mut atoms = self.atoms; + atoms.sort_by_key(|a| a.delete.start()); + for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) { + assert!(a1.delete.end() <= a2.delete.start()) + } + Edit { atoms } + } + pub fn invalidates_offset(&self, offset: TextUnit) -> bool { + self.atoms.iter().any(|atom| contains_offset_nonstrict(atom.delete, offset)) + } +} + +impl Edit { + pub fn into_atoms(self) -> Vec { + self.atoms + } + + pub fn apply(&self, text: &str) -> String { + let mut total_len = text.len(); + for atom in self.atoms.iter() { + total_len += atom.insert.len(); + total_len -= u32::from(atom.delete.end() - atom.delete.start()) as usize; + } + let mut buf = String::with_capacity(total_len); + let mut prev = 0; + for atom in self.atoms.iter() { + let start = u32::from(atom.delete.start()) as usize; + let end = u32::from(atom.delete.end()) as usize; + if start > prev { + buf.push_str(&text[prev..start]); + } + buf.push_str(&atom.insert); + prev = end; + } + buf.push_str(&text[prev..text.len()]); + assert_eq!(buf.len(), total_len); + buf + } + + pub fn apply_to_offset(&self, offset: TextUnit) -> Option { + let mut res = offset; + for atom in self.atoms.iter() { + if atom.delete.start() >= offset { + break; + } + if offset < atom.delete.end() { + return None + } + res += TextUnit::of_str(&atom.insert); + res -= atom.delete.len(); + } + Some(res) + } +} -- cgit v1.2.3