about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMoritz Vetter <mv@3yourmind.com>2022-02-26 15:50:09 +0100
committerMoritz Vetter <mv@3yourmind.com>2022-02-26 15:50:09 +0100
commit21d497b77366bdf90e6fcc9a35ee8f24344622ca (patch)
treeabe42db6637f1b5cead6d0e1e109b9de6a62d748
parentc541f3396cd8dc1c2c87434d1e07d6862a2e8584 (diff)
downloadrust-21d497b77366bdf90e6fcc9a35ee8f24344622ca.tar.gz
rust-21d497b77366bdf90e6fcc9a35ee8f24344622ca.zip
refact: edit text in place in TextEdit::apply
-rw-r--r--crates/text_edit/src/lib.rs28
1 files changed, 11 insertions, 17 deletions
diff --git a/crates/text_edit/src/lib.rs b/crates/text_edit/src/lib.rs
index f478e4dcf57..f9d3ff9b07f 100644
--- a/crates/text_edit/src/lib.rs
+++ b/crates/text_edit/src/lib.rs
@@ -90,28 +90,22 @@ impl TextEdit {
             _ => (),
         }
 
-        let mut total_len = TextSize::of(&*text);
+        let text_size = TextSize::of(&*text);
+        let mut total_len = text_size.clone();
         for indel in &self.indels {
             total_len += TextSize::of(&indel.insert);
-            total_len -= indel.delete.end() - indel.delete.start();
+            total_len -= indel.delete.len();
         }
-        let mut buf = String::with_capacity(total_len.into());
-        let mut prev = 0;
-        for indel in &self.indels {
-            let start: usize = indel.delete.start().into();
-            let end: usize = indel.delete.end().into();
-            if start > prev {
-                buf.push_str(&text[prev..start]);
-            }
-            buf.push_str(&indel.insert);
-            prev = end;
+
+        if let Some(additional) = total_len.checked_sub(text_size.into()) {
+            text.reserve(additional.into());
+        }
+
+        for indel in self.indels.iter().rev() {
+            indel.apply(text);
         }
-        buf.push_str(&text[prev..text.len()]);
-        assert_eq!(TextSize::of(&buf), total_len);
 
-        // FIXME: figure out a way to mutate the text in-place or reuse the
-        // memory in some other way
-        *text = buf;
+        assert_eq!(TextSize::of(&*text), total_len);
     }
 
     pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> {