WIP

Max Brunsfeld created

Change summary

zed/src/editor/buffer.rs | 583 ++++++++++++-----------------------------
1 file changed, 175 insertions(+), 408 deletions(-)

Detailed changes

zed/src/editor/buffer.rs 🔗

@@ -28,7 +28,7 @@ use std::{
     cell::RefCell,
     cmp,
     hash::BuildHasher,
-    iter::{self, Iterator},
+    iter::Iterator,
     mem,
     ops::{Deref, DerefMut, Range},
     str,
@@ -109,7 +109,6 @@ pub struct Buffer {
     fragments: SumTree<Fragment>,
     visible_text: Rope,
     deleted_text: Rope,
-    insertion_splits: HashMap<time::Local, SumTree<InsertionSplit>>,
     pub version: time::Global,
     saved_version: time::Global,
     saved_mtime: SystemTime,
@@ -338,9 +337,7 @@ pub struct Insertion {
 
 #[derive(Eq, PartialEq, Clone, Debug)]
 struct Fragment {
-    id: FragmentId,
-    insertion: Arc<Insertion>,
-    range_in_insertion: Range<usize>,
+    insertion_id: time::Local,
     len: usize,
     deletions: HashSet<time::Local>,
     max_undos: time::Global,
@@ -350,7 +347,6 @@ struct Fragment {
 #[derive(Eq, PartialEq, Clone, Debug)]
 pub struct FragmentSummary {
     text: FragmentTextSummary,
-    max_fragment_id: FragmentId,
     max_version: time::Global,
     min_insertion_version: time::Global,
     max_insertion_version: time::Global,
@@ -369,17 +365,6 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
     }
 }
 
-#[derive(Eq, PartialEq, Clone, Debug)]
-struct InsertionSplit {
-    extent: usize,
-    fragment_id: FragmentId,
-}
-
-#[derive(Eq, PartialEq, Clone, Debug)]
-struct InsertionSplitSummary {
-    extent: usize,
-}
-
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum Operation {
     Edit {
@@ -474,52 +459,20 @@ impl Buffer {
             saved_mtime = UNIX_EPOCH;
         }
 
-        let mut visible_text = Rope::new();
-        let mut insertion_splits = HashMap::default();
         let mut fragments = SumTree::new();
 
-        let base_text = Rope::from(history.base_text.as_ref());
-        let base_insertion = Arc::new(Insertion {
-            id: time::Local::default(),
-            parent_id: time::Local::default(),
-            offset_in_parent: 0,
-            lamport_timestamp: time::Lamport::default(),
-        });
+        let visible_text = Rope::from(history.base_text.as_ref());
+        let mut local_clock = time::Local::new(replica_id);
 
-        insertion_splits.insert(
-            base_insertion.id,
-            SumTree::from_item(
-                InsertionSplit {
-                    fragment_id: FragmentId::min_value().clone(),
-                    extent: 0,
-                },
-                &(),
-            ),
-        );
-        fragments.push(
-            Fragment::new(
-                FragmentId::min_value().clone(),
-                base_insertion.clone(),
-                0..0,
-            ),
-            &None,
-        );
-
-        if base_text.len() > 0 {
-            let base_fragment_id =
-                FragmentId::between(&FragmentId::min_value(), &FragmentId::max_value());
-            let range_in_insertion = 0..base_text.len();
-
-            visible_text = base_text.clone();
-            insertion_splits.get_mut(&base_insertion.id).unwrap().push(
-                InsertionSplit {
-                    fragment_id: base_fragment_id.clone(),
-                    extent: range_in_insertion.end,
-                },
-                &(),
-            );
+        if visible_text.len() > 0 {
             fragments.push(
-                Fragment::new(base_fragment_id, base_insertion, range_in_insertion.clone()),
+                Fragment {
+                    insertion_id: local_clock.tick(),
+                    len: visible_text.len(),
+                    deletions: Default::default(),
+                    max_undos: Default::default(),
+                    visible: true,
+                },
                 &None,
             );
         }
@@ -528,7 +481,6 @@ impl Buffer {
             visible_text,
             deleted_text: Rope::new(),
             fragments,
-            insertion_splits,
             version: time::Global::new(),
             saved_version: time::Global::new(),
             last_edit: time::Local::default(),
@@ -544,7 +496,7 @@ impl Buffer {
             deferred_ops: OperationQueue::new(),
             deferred_replicas: HashSet::default(),
             replica_id,
-            local_clock: time::Local::new(replica_id),
+            local_clock,
             lamport_clock: time::Lamport::new(replica_id),
         };
         result.reparse(cx);
@@ -1205,7 +1157,7 @@ impl Buffer {
             if let Some(fragment) = fragment {
                 // Was this fragment visible in the edit's base version? If not, push it into
                 // the new fragments, skip it, and continue the loop.
-                if !version.observed(fragment.insertion.id) {
+                if !version.observed(fragment.insertion_id) {
                     new_ropes.push_fragment(fragment, fragment.visible);
                     new_fragments.push(fragment.clone(), &None);
                     old_fragments.next(&old_fragments_cx);
@@ -1222,10 +1174,7 @@ impl Buffer {
                             deletions: fragment.deletions.clone(),
                             max_undos: fragment.max_undos.clone(),
                             visible: fragment.visible,
-                            // DELETE
-                            id: Default::default(),
-                            insertion: fragment.insertion.clone(),
-                            range_in_insertion: Default::default(),
+                            insertion_id: fragment.insertion_id,
                         };
                         new_ropes.push_fragment(&suffix, fragment.visible);
                         new_fragments.push(suffix, &None);
@@ -1249,11 +1198,7 @@ impl Buffer {
                         deletions: fragment.deletions.clone(),
                         max_undos: fragment.max_undos.clone(),
                         visible: fragment.visible,
-
-                        // TODO: Delete these
-                        id: Default::default(),
-                        insertion: fragment.insertion.clone(),
-                        range_in_insertion: Default::default(),
+                        insertion_id: fragment.insertion_id,
                     };
                     fragment_start_offset += prefix.len;
                     new_ropes.push_fragment(&prefix, fragment.visible);
@@ -1273,11 +1218,7 @@ impl Buffer {
                         deletions,
                         max_undos: fragment.max_undos.clone(),
                         visible: false,
-
-                        // TODO: Delete these
-                        id: Default::default(),
-                        insertion: fragment.insertion.clone(),
-                        range_in_insertion: Default::default(),
+                        insertion_id: fragment.insertion_id,
                     };
                     fragment_start_offset += deleted.len;
                     new_ropes.push_fragment(&deleted, fragment.visible);
@@ -1293,11 +1234,7 @@ impl Buffer {
                             deletions: Default::default(),
                             max_undos: Default::default(), // TODO: Is this right?
                             visible: true,
-
-                            // TODO: Delete these
-                            id: Default::default(),
-                            insertion: fragment.insertion.clone(),
-                            range_in_insertion: Default::default(),
+                            insertion_id: local_timestamp,
                         },
                         &None,
                     );
@@ -1326,16 +1263,13 @@ impl Buffer {
                     deletions: fragment.deletions.clone(),
                     max_undos: fragment.max_undos.clone(),
                     visible: fragment.visible,
-                    // DELETE
-                    id: Default::default(),
-                    insertion: fragment.insertion.clone(),
-                    range_in_insertion: Default::default(),
+                    insertion_id: fragment.insertion_id,
                 };
                 new_ropes.push_fragment(&suffix, fragment.visible);
                 new_fragments.push(suffix, &None);
             }
 
-            let suffix_fragments = old_fragments.suffix(&None);
+            let suffix_fragments = old_fragments.suffix(&old_fragments_cx);
             new_ropes.push_tree(suffix_fragments.summary().text);
             new_fragments.push_tree(suffix_fragments, &None);
         }
@@ -1420,95 +1354,129 @@ impl Buffer {
     }
 
     fn apply_undo(&mut self, undo: UndoOperation) -> Result<()> {
+        let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
+
+        let mut new_fragments = SumTree::new();
+        let mut new_ropes =
+            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
+
+        self.undo_map.insert(undo);
+        let edit = &self.history.ops[&undo.edit_id];
+
+        let version = Some(edit.version.clone());
+        for range in &edit.ranges {
+            let preceding_fragments = old_fragments.slice(
+                &VersionedOffset::Offset(range.start),
+                SeekBias::Right,
+                &version,
+            );
+            new_ropes.push_tree(preceding_fragments.summary().text);
+            new_fragments.push_tree(preceding_fragments, &None);
+
+            while old_fragments.end(&version).offset() < range.end {
+                if let Some(fragment) = old_fragments.item() {
+                    let mut fragment = fragment.clone();
+                    let fragment_was_visible = fragment.visible;
+                    if edit.version.observed(fragment.insertion_id) {
+                        fragment.visible = fragment.is_visible(&self.undo_map);
+                        fragment.max_undos.observe(undo.id);
+                    }
+                    new_ropes.push_fragment(&fragment, fragment_was_visible);
+                    new_fragments.push(fragment, &None);
+
+                    // Skip over any fragments that were not present when the edit occurred.
+                    let newer_fragments = old_fragments.slice(
+                        &old_fragments.end(&version),
+                        SeekBias::Right,
+                        &version,
+                    );
+                    new_ropes.push_tree(newer_fragments.summary().text);
+                    new_fragments.push_tree(newer_fragments, &None);
+                } else {
+                    break;
+                }
+            }
+        }
+
+        let suffix = old_fragments.suffix(&version);
+        new_ropes.push_tree(suffix.summary().text);
+        new_fragments.push_tree(suffix, &None);
+
+        drop(old_fragments);
+        let (visible_text, deleted_text) = new_ropes.finish();
+        self.fragments = new_fragments;
+        self.visible_text = visible_text;
+        self.deleted_text = deleted_text;
+
+        // if edit.start_id == edit.end_id && edit.start_offset == edit.end_offset {
+        //     let splits = &self.insertion_splits[&undo.edit_id];
+        //     let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
+
+        //     let first_split_id = insertion_splits.next().unwrap();
+        //     new_fragments =
+        //         fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &None);
+        //     new_ropes.push_tree(new_fragments.summary().text);
+
+        //     loop {
+        //         let mut fragment = fragments_cursor.item().unwrap().clone();
+        //         let was_visible = fragment.visible;
+        //         fragment.visible = fragment.is_visible(&self.undo_map);
+        //         fragment.max_undos.observe(undo.id);
+
+        //         new_ropes.push_fragment(&fragment, was_visible);
+        //         new_fragments.push(fragment.clone(), &None);
+
+        //         fragments_cursor.next(&None);
+        //         if let Some(split_id) = insertion_splits.next() {
+        //             let slice = fragments_cursor.slice(
+        //                 &FragmentIdRef::new(split_id),
+        //                 SeekBias::Left,
+        //                 &None,
+        //             );
+        //             new_ropes.push_tree(slice.summary().text);
+        //             new_fragments.push_tree(slice, &None);
+        //         } else {
+        //             break;
+        //         }
+        //     }
+        // } else {
+        //     new_fragments = fragments_cursor.slice(
+        //         &FragmentIdRef::new(&edit.),
+        //         SeekBias::Left,
+        //         &None,
+        //     );
+        //     new_ropes.push_tree(new_fragments.summary().text);
+
+        //     while let Some(fragment) = fragments_cursor.item() {
+        //         if fragment.id > end_fragment_id {
+        //             break;
+        //         } else {
+        //             let mut fragment = fragment.clone();
+        //             let fragment_was_visible = fragment.visible;
+        //             if edit.version_in_range.observed(fragment.insertion.id)
+        //                 || fragment.insertion.id == undo.edit_id
+        //             {
+        //                 fragment.visible = fragment.is_visible(&self.undo_map);
+        //                 fragment.max_undos.observe(undo.id);
+        //             }
+
+        //             new_ropes.push_fragment(&fragment, fragment_was_visible);
+        //             new_fragments.push(fragment, &None);
+        //             fragments_cursor.next(&None);
+        //         }
+        //     }
+        // }
+
+        // new_fragments.push_tree(fragments_cursor.suffix(&None), &None);
+        // let (visible_text, deleted_text) = new_ropes.finish();
+        // drop(fragments_cursor);
+        // self.fragments = new_fragments;
+        // self.visible_text = visible_text;
+        // self.deleted_text = deleted_text;
+
         Ok(())
     }
 
-    // {
-    //     let mut new_fragments;
-    //     let mut old_visible_text = Rope::new();
-    //     let mut old_deleted_text = Rope::new();
-    //     mem::swap(&mut old_visible_text, &mut self.visible_text);
-    //     mem::swap(&mut old_deleted_text, &mut self.deleted_text);
-    //     let mut new_ropes =
-    //         RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0));
-
-    //     self.undo_map.insert(undo);
-    //     let edit = &self.history.ops[&undo.edit_id];
-    //     let start_fragment_id = self.resolve_fragment_id(edit.start_id, edit.start_offset)?;
-    //     let end_fragment_id = self.resolve_fragment_id(edit.end_id, edit.end_offset)?;
-
-    //     let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, ()>();
-
-    //     if edit.start_id == edit.end_id && edit.start_offset == edit.end_offset {
-    //         let splits = &self.insertion_splits[&undo.edit_id];
-    //         let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
-
-    //         let first_split_id = insertion_splits.next().unwrap();
-    //         new_fragments =
-    //             fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &None);
-    //         new_ropes.push_tree(new_fragments.summary().text);
-
-    //         loop {
-    //             let mut fragment = fragments_cursor.item().unwrap().clone();
-    //             let was_visible = fragment.visible;
-    //             fragment.visible = fragment.is_visible(&self.undo_map);
-    //             fragment.max_undos.observe(undo.id);
-
-    //             new_ropes.push_fragment(&fragment, was_visible);
-    //             new_fragments.push(fragment.clone(), &None);
-
-    //             fragments_cursor.next(&None);
-    //             if let Some(split_id) = insertion_splits.next() {
-    //                 let slice = fragments_cursor.slice(
-    //                     &FragmentIdRef::new(split_id),
-    //                     SeekBias::Left,
-    //                     &None,
-    //                 );
-    //                 new_ropes.push_tree(slice.summary().text);
-    //                 new_fragments.push_tree(slice, &None);
-    //             } else {
-    //                 break;
-    //             }
-    //         }
-    //     } else {
-    //         new_fragments = fragments_cursor.slice(
-    //             &FragmentIdRef::new(&start_fragment_id),
-    //             SeekBias::Left,
-    //             &None,
-    //         );
-    //         new_ropes.push_tree(new_fragments.summary().text);
-
-    //         while let Some(fragment) = fragments_cursor.item() {
-    //             if fragment.id > end_fragment_id {
-    //                 break;
-    //             } else {
-    //                 let mut fragment = fragment.clone();
-    //                 let fragment_was_visible = fragment.visible;
-    //                 if edit.version_in_range.observed(fragment.insertion.id)
-    //                     || fragment.insertion.id == undo.edit_id
-    //                 {
-    //                     fragment.visible = fragment.is_visible(&self.undo_map);
-    //                     fragment.max_undos.observe(undo.id);
-    //                 }
-
-    //                 new_ropes.push_fragment(&fragment, fragment_was_visible);
-    //                 new_fragments.push(fragment, &None);
-    //                 fragments_cursor.next(&None);
-    //             }
-    //         }
-    //     }
-
-    //     new_fragments.push_tree(fragments_cursor.suffix(&None), &None);
-    //     let (visible_text, deleted_text) = new_ropes.finish();
-    //     drop(fragments_cursor);
-
-    //     self.fragments = new_fragments;
-    //     self.visible_text = visible_text;
-    //     self.deleted_text = deleted_text;
-
-    //     Ok(())
-    // }
-
     fn flush_deferred_ops(&mut self) -> Result<()> {
         self.deferred_replicas.clear();
         let mut deferred_ops = Vec::new();
@@ -1588,14 +1556,6 @@ impl Buffer {
             let mut fragment_end = fragment_start + fragment.visible_len();
             let fragment_was_visible = fragment.visible;
 
-            let old_split_tree = self
-                .insertion_splits
-                .remove(&fragment.insertion.id)
-                .unwrap();
-            let mut splits_cursor = old_split_tree.cursor::<usize, ()>();
-            let mut new_split_tree =
-                splits_cursor.slice(&fragment.range_in_insertion.start, SeekBias::Right, &());
-
             // Find all splices that start or end within the current fragment. Then, split the
             // fragment and reassemble it in both trees accounting for the deleted and the newly
             // inserted text.
@@ -1603,33 +1563,23 @@ impl Buffer {
                 let range = cur_range.clone().unwrap();
                 if range.start > fragment_start {
                     let mut prefix = fragment.clone();
-                    prefix.range_in_insertion.end =
-                        prefix.range_in_insertion.start + (range.start - fragment_start);
-                    prefix.id =
-                        FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
-                    fragment.range_in_insertion.start = prefix.range_in_insertion.end;
+                    prefix.len = range.start - fragment_start;
+                    fragment.len -= prefix.len;
 
                     new_ropes.push_fragment(&prefix, prefix.visible);
                     new_fragments.push(prefix.clone(), &None);
-                    new_split_tree.push(
-                        InsertionSplit {
-                            extent: prefix.range_in_insertion.end - prefix.range_in_insertion.start,
-                            fragment_id: prefix.id,
-                        },
-                        &(),
-                    );
                     fragment_start = range.start;
                 }
 
                 if range.start == fragment_start {
                     if let Some(new_text) = new_text.clone() {
-                        let new_fragment = self.build_fragment_to_insert(
-                            &new_fragments.last().unwrap(),
-                            Some(&fragment),
-                            &new_text,
-                            edit_id,
-                            lamport_timestamp,
-                        );
+                        let new_fragment = Fragment {
+                            len: new_text.len(),
+                            insertion_id: edit_id,
+                            deletions: Default::default(),
+                            max_undos: Default::default(),
+                            visible: true,
+                        };
 
                         new_ropes.push_str(&new_text);
                         new_fragments.push(new_fragment, &None);
@@ -1639,25 +1589,14 @@ impl Buffer {
                 if range.end < fragment_end {
                     if range.end > fragment_start {
                         let mut prefix = fragment.clone();
-                        prefix.range_in_insertion.end =
-                            prefix.range_in_insertion.start + (range.end - fragment_start);
-                        prefix.id =
-                            FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
+                        prefix.len = range.end - fragment_start;
                         if prefix.visible {
                             prefix.deletions.insert(edit_id);
                             prefix.visible = false;
                         }
-                        fragment.range_in_insertion.start = prefix.range_in_insertion.end;
+                        fragment.len -= prefix.len;
                         new_ropes.push_fragment(&prefix, fragment_was_visible);
                         new_fragments.push(prefix.clone(), &None);
-                        new_split_tree.push(
-                            InsertionSplit {
-                                extent: prefix.range_in_insertion.end
-                                    - prefix.range_in_insertion.start,
-                                fragment_id: prefix.id,
-                            },
-                            &(),
-                        );
                         fragment_start = range.end;
                     }
                 } else {
@@ -1676,20 +1615,6 @@ impl Buffer {
                     break;
                 }
             }
-            new_split_tree.push(
-                InsertionSplit {
-                    extent: fragment.range_in_insertion.end - fragment.range_in_insertion.start,
-                    fragment_id: fragment.id.clone(),
-                },
-                &(),
-            );
-            splits_cursor.next(&());
-            new_split_tree.push_tree(
-                splits_cursor.slice(&old_split_tree.extent::<usize>(&()), SeekBias::Right, &()),
-                &(),
-            );
-            self.insertion_splits
-                .insert(fragment.insertion.id, new_split_tree);
 
             new_ropes.push_fragment(&fragment, fragment_was_visible);
             new_fragments.push(fragment, &None);
@@ -1740,16 +1665,15 @@ impl Buffer {
         // multiple because ranges must be disjoint.
         if cur_range.is_some() {
             debug_assert_eq!(old_ranges.next(), None);
-            let last_fragment = new_fragments.last().unwrap();
 
             if let Some(new_text) = new_text {
-                let new_fragment = self.build_fragment_to_insert(
-                    &last_fragment,
-                    None,
-                    &new_text,
-                    edit_id,
-                    lamport_timestamp,
-                );
+                let new_fragment = Fragment {
+                    len: new_text.len(),
+                    insertion_id: edit_id,
+                    deletions: Default::default(),
+                    max_undos: Default::default(),
+                    visible: true,
+                };
 
                 new_ropes.push_str(&new_text);
                 new_fragments.push(new_fragment, &None);
@@ -1764,44 +1688,6 @@ impl Buffer {
         self.deleted_text = deleted_text;
     }
 
-    fn build_fragment_to_insert(
-        &mut self,
-        prev_fragment: &Fragment,
-        next_fragment: Option<&Fragment>,
-        text: &str,
-        insertion_id: time::Local,
-        lamport_timestamp: time::Lamport,
-    ) -> Fragment {
-        let new_fragment_id = FragmentId::between(
-            &prev_fragment.id,
-            next_fragment
-                .map(|f| &f.id)
-                .unwrap_or(&FragmentId::max_value()),
-        );
-
-        let range_in_insertion = 0..text.len();
-        let mut split_tree = SumTree::new();
-        split_tree.push(
-            InsertionSplit {
-                extent: range_in_insertion.len(),
-                fragment_id: new_fragment_id.clone(),
-            },
-            &(),
-        );
-        self.insertion_splits.insert(insertion_id, split_tree);
-
-        Fragment::new(
-            new_fragment_id,
-            Arc::new(Insertion {
-                id: insertion_id,
-                parent_id: prev_fragment.insertion.id,
-                offset_in_parent: prev_fragment.range_in_insertion.end,
-                lamport_timestamp,
-            }),
-            range_in_insertion,
-        )
-    }
-
     pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
         self.anchor_at(position, AnchorBias::Left)
     }
@@ -1905,7 +1791,6 @@ impl Clone for Buffer {
             fragments: self.fragments.clone(),
             visible_text: self.visible_text.clone(),
             deleted_text: self.deleted_text.clone(),
-            insertion_splits: self.insertion_splits.clone(),
             version: self.version.clone(),
             saved_version: self.saved_version.clone(),
             saved_mtime: self.saved_mtime,
@@ -2015,7 +1900,7 @@ impl<'a> RopeBuilder<'a> {
     }
 
     fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
-        self.push(fragment.len(), was_visible, fragment.visible)
+        self.push(fragment.len, was_visible, fragment.visible)
     }
 
     fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
@@ -2071,38 +1956,38 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
             if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
                 if let Some(ref mut change) = change {
                     if change.new_range.end == new_offset {
-                        change.new_range.end += fragment.len();
-                        self.delta += fragment.len() as isize;
+                        change.new_range.end += fragment.len;
+                        self.delta += fragment.len as isize;
                     } else {
                         break;
                     }
                 } else {
                     change = Some(Edit {
                         old_range: old_offset..old_offset,
-                        new_range: new_offset..new_offset + fragment.len(),
+                        new_range: new_offset..new_offset + fragment.len,
                         old_lines: Point::zero(),
                     });
-                    self.delta += fragment.len() as isize;
+                    self.delta += fragment.len as isize;
                 }
             } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
                 let deleted_start = self.cursor.start().deleted;
-                let old_lines = self.deleted_text.to_point(deleted_start + fragment.len())
+                let old_lines = self.deleted_text.to_point(deleted_start + fragment.len)
                     - self.deleted_text.to_point(deleted_start);
                 if let Some(ref mut change) = change {
                     if change.new_range.end == new_offset {
-                        change.old_range.end += fragment.len();
+                        change.old_range.end += fragment.len;
                         change.old_lines += &old_lines;
-                        self.delta -= fragment.len() as isize;
+                        self.delta -= fragment.len as isize;
                     } else {
                         break;
                     }
                 } else {
                     change = Some(Edit {
-                        old_range: old_offset..old_offset + fragment.len(),
+                        old_range: old_offset..old_offset + fragment.len,
                         new_range: new_offset..new_offset,
                         old_lines,
                     });
-                    self.delta -= fragment.len() as isize;
+                    self.delta -= fragment.len as isize;
                 }
             }
 
@@ -2233,85 +2118,22 @@ impl<'a> Iterator for HighlightedChunks<'a> {
     }
 }
 
-#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
-struct FragmentId(Arc<[u16]>);
-
-lazy_static! {
-    static ref FRAGMENT_ID_EMPTY: FragmentId = FragmentId(Arc::from([]));
-    static ref FRAGMENT_ID_MIN_VALUE: FragmentId = FragmentId(Arc::from([0 as u16]));
-    static ref FRAGMENT_ID_MAX_VALUE: FragmentId = FragmentId(Arc::from([u16::max_value()]));
-}
-
-impl Default for FragmentId {
-    fn default() -> Self {
-        FRAGMENT_ID_EMPTY.clone()
-    }
-}
-
-impl FragmentId {
-    fn min_value() -> &'static Self {
-        &FRAGMENT_ID_MIN_VALUE
-    }
-
-    fn max_value() -> &'static Self {
-        &FRAGMENT_ID_MAX_VALUE
-    }
-
-    fn between(left: &Self, right: &Self) -> Self {
-        Self::between_with_max(left, right, u16::max_value())
-    }
-
-    fn between_with_max(left: &Self, right: &Self, max_value: u16) -> Self {
-        let mut new_entries = Vec::new();
-
-        let left_entries = left.0.iter().cloned().chain(iter::repeat(0));
-        let right_entries = right.0.iter().cloned().chain(iter::repeat(max_value));
-        for (l, r) in left_entries.zip(right_entries) {
-            let interval = r - l;
-            if interval > 1 {
-                new_entries.push(l + cmp::max(1, cmp::min(8, interval / 2)));
-                break;
-            } else {
-                new_entries.push(l);
-            }
-        }
-
-        FragmentId(Arc::from(new_entries))
-    }
-}
-
 impl Fragment {
-    fn new(id: FragmentId, insertion: Arc<Insertion>, range_in_insertion: Range<usize>) -> Self {
-        Self {
-            id,
-            insertion,
-            len: range_in_insertion.len(),
-            range_in_insertion,
-            deletions: Default::default(),
-            max_undos: Default::default(),
-            visible: true,
-        }
-    }
-
     fn is_visible(&self, undos: &UndoMap) -> bool {
-        !undos.is_undone(self.insertion.id) && self.deletions.iter().all(|d| undos.is_undone(*d))
+        !undos.is_undone(self.insertion_id) && self.deletions.iter().all(|d| undos.is_undone(*d))
     }
 
     fn was_visible(&self, version: &time::Global, undos: &UndoMap) -> bool {
-        (version.observed(self.insertion.id) && !undos.was_undone(self.insertion.id, version))
+        (version.observed(self.insertion_id) && !undos.was_undone(self.insertion_id, version))
             && self
                 .deletions
                 .iter()
                 .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
     }
 
-    fn len(&self) -> usize {
-        self.range_in_insertion.len()
-    }
-
     fn visible_len(&self) -> usize {
         if self.visible {
-            self.range_in_insertion.len()
+            self.len
         } else {
             0
         }
@@ -2323,22 +2145,21 @@ impl sum_tree::Item for Fragment {
 
     fn summary(&self) -> Self::Summary {
         let mut max_version = time::Global::new();
-        max_version.observe(self.insertion.id);
+        max_version.observe(self.insertion_id);
         for deletion in &self.deletions {
             max_version.observe(*deletion);
         }
         max_version.join(&self.max_undos);
 
         let mut min_insertion_version = time::Global::new();
-        min_insertion_version.observe(self.insertion.id);
+        min_insertion_version.observe(self.insertion_id);
         let max_insertion_version = min_insertion_version.clone();
         if self.visible {
             FragmentSummary {
                 text: FragmentTextSummary {
-                    visible: self.len(),
+                    visible: self.len,
                     deleted: 0,
                 },
-                max_fragment_id: self.id.clone(),
                 max_version,
                 min_insertion_version,
                 max_insertion_version,
@@ -2347,9 +2168,8 @@ impl sum_tree::Item for Fragment {
             FragmentSummary {
                 text: FragmentTextSummary {
                     visible: 0,
-                    deleted: self.len(),
+                    deleted: self.len,
                 },
-                max_fragment_id: self.id.clone(),
                 max_version,
                 min_insertion_version,
                 max_insertion_version,
@@ -2364,8 +2184,6 @@ impl sum_tree::Summary for FragmentSummary {
     fn add_summary(&mut self, other: &Self, _: &Self::Context) {
         self.text.visible += &other.text.visible;
         self.text.deleted += &other.text.deleted;
-        debug_assert!(self.max_fragment_id <= other.max_fragment_id);
-        self.max_fragment_id = other.max_fragment_id.clone();
         self.max_version.join(&other.max_version);
         self.min_insertion_version
             .meet(&other.min_insertion_version);
@@ -2378,7 +2196,6 @@ impl Default for FragmentSummary {
     fn default() -> Self {
         FragmentSummary {
             text: FragmentTextSummary::default(),
-            max_fragment_id: FragmentId::min_value().clone(),
             max_version: time::Global::new(),
             min_insertion_version: time::Global::new(),
             max_insertion_version: time::Global::new(),
@@ -2392,36 +2209,6 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
     }
 }
 
-impl sum_tree::Item for InsertionSplit {
-    type Summary = InsertionSplitSummary;
-
-    fn summary(&self) -> Self::Summary {
-        InsertionSplitSummary {
-            extent: self.extent,
-        }
-    }
-}
-
-impl sum_tree::Summary for InsertionSplitSummary {
-    type Context = ();
-
-    fn add_summary(&mut self, other: &Self, _: &()) {
-        self.extent += other.extent;
-    }
-}
-
-impl Default for InsertionSplitSummary {
-    fn default() -> Self {
-        InsertionSplitSummary { extent: 0 }
-    }
-}
-
-impl<'a> sum_tree::Dimension<'a, InsertionSplitSummary> for usize {
-    fn add_summary(&mut self, summary: &InsertionSplitSummary, _: &()) {
-        *self += summary.extent;
-    }
-}
-
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 enum VersionedOffset {
     Offset(usize),
@@ -2847,26 +2634,6 @@ mod tests {
         });
     }
 
-    #[test]
-    fn test_fragment_ids() {
-        for seed in 0..10 {
-            let rng = &mut StdRng::seed_from_u64(seed);
-
-            let mut ids = vec![FragmentId(Arc::from([0])), FragmentId(Arc::from([4]))];
-            for _i in 0..100 {
-                let index = rng.gen_range(1..ids.len());
-
-                let left = ids[index - 1].clone();
-                let right = ids[index].clone();
-                ids.insert(index, FragmentId::between_with_max(&left, &right, 4));
-
-                let mut sorted_ids = ids.clone();
-                sorted_ids.sort();
-                assert_eq!(ids, sorted_ids);
-            }
-        }
-    }
-
     #[gpui::test]
     fn test_anchors(cx: &mut gpui::MutableAppContext) {
         cx.add_model(|cx| {