diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 7bf58d27a74cb9d096b987c25cef51486b266a29..4ea0a84518ae34141b724fd6ea82bcd0d86f17ef 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -341,6 +341,7 @@ struct Fragment { id: FragmentId, insertion: Arc, range_in_insertion: Range, + len: usize, deletions: HashSet, max_undos: time::Global, visible: bool, @@ -399,11 +400,8 @@ pub enum Operation { #[derive(Clone, Debug, Eq, PartialEq)] pub struct EditOperation { id: time::Local, - start_id: time::Local, - start_offset: usize, - end_id: time::Local, - end_offset: usize, - version_in_range: time::Global, + version: time::Global, + ranges: Vec>, new_text: Option, } @@ -1130,12 +1128,9 @@ impl Buffer { } => { if !self.version.observed(edit.id) { self.apply_edit( - edit.start_id, - edit.start_offset, - edit.end_id, - edit.end_offset, + edit.version, + edit.ranges, edit.new_text.as_deref(), - &edit.version_in_range, edit.id, lamport_timestamp, )?; @@ -1172,148 +1167,73 @@ impl Buffer { fn apply_edit( &mut self, - start_id: time::Local, - start_offset: usize, - end_id: time::Local, - end_offset: usize, + version: time::Global, + ranges: Vec>, mut new_text: Option<&str>, - version_in_range: &time::Global, local_timestamp: time::Local, lamport_timestamp: time::Lamport, ) -> Result<()> { - let start_fragment_id = self.resolve_fragment_id(start_id, start_offset)?; - let end_fragment_id = self.resolve_fragment_id(end_id, end_offset)?; - - let mut old_visible_text = Rope::new(); - let mut old_deleted_text = Rope::new(); - let mut old_fragments = SumTree::new(); - mem::swap(&mut old_visible_text, &mut self.visible_text); - mem::swap(&mut old_deleted_text, &mut self.deleted_text); - mem::swap(&mut old_fragments, &mut self.fragments); + let mut old_visible_text = mem::take(&mut self.visible_text); + let mut old_deleted_text = mem::take(&mut self.deleted_text); + let mut old_fragments = mem::take(&mut self.fragments); + let mut old_fragments = old_fragments.cursor::(); - let mut fragments_cursor = old_fragments.cursor::(); + let version = Some(version); - let mut new_fragments = fragments_cursor.slice( - &FragmentIdRef::new(&start_fragment_id), - SeekBias::Left, - &None, - ); + let mut new_fragments = SumTree::new(); let mut new_ropes = RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0)); - new_ropes.push_tree(new_fragments.summary().text); - - let start_fragment = fragments_cursor.item().unwrap(); - if start_offset == start_fragment.range_in_insertion.end { - let fragment = fragments_cursor.item().unwrap().clone(); - new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &None); - fragments_cursor.next(&None); - } - - while let Some(fragment) = fragments_cursor.item() { - if new_text.is_none() && fragment.id > end_fragment_id { - break; - } - - let mut fragment = fragment.clone(); - - if fragment.id == start_fragment_id || fragment.id == end_fragment_id { - let split_start = if start_fragment_id == fragment.id { - start_offset - } else { - fragment.range_in_insertion.start - }; - let split_end = if end_fragment_id == fragment.id { - end_offset - } else { - fragment.range_in_insertion.end - }; - let (before_range, within_range, after_range) = self.split_fragment( - fragments_cursor.prev_item().as_ref().unwrap(), - &fragment, - split_start..split_end, - ); - let insertion = if let Some(new_text) = new_text { - let prev_fragment = fragments_cursor.prev_item(); - Some(self.build_fragment_to_insert( - before_range.as_ref().or(prev_fragment).unwrap(), - within_range.as_ref().or(after_range.as_ref()), - new_text, - local_timestamp, - lamport_timestamp, - )) - } else { - None - }; - if let Some(fragment) = before_range { - new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &None); - } - if let Some(fragment) = insertion { - new_ropes.push_str(new_text.take().unwrap()); - new_fragments.push(fragment, &None); - } - if let Some(mut fragment) = within_range { - let fragment_was_visible = fragment.visible; - if fragment.was_visible(&version_in_range, &self.undo_map) { - fragment.deletions.insert(local_timestamp); - if fragment.visible { - fragment.visible = false; - } - } + let mut pending_fragment = None; + let mut pending_fragment_start_offset = 0; + + for range in ranges { + let preceding_fragments = old_fragments.slice( + &VersionedOffset::Offset(range.start), + SeekBias::Right, + &version, + ); + new_fragments.push_tree(preceding_fragments, &None); + new_ropes.push_tree(new_fragments.summary().text); - new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &None); - } - if let Some(fragment) = after_range { - new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &None); - } + let mut fragment_start_offset = old_fragments.start().offset(); + let mut fragment_end_offset = old_fragments.end(&version).offset(); + let mut fragment = if let Some(fragment) = old_fragments.item() { + fragment.clone() } else { - if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp { - let new_text = new_text.take().unwrap(); - let fragment = self.build_fragment_to_insert( - fragments_cursor.prev_item().as_ref().unwrap(), - Some(&fragment), - new_text, - local_timestamp, - lamport_timestamp, - ); - new_ropes.push_str(new_text); - new_fragments.push(fragment, &None); - } + todo!() + }; - let fragment_was_visible = fragment.visible; - if fragment.id < end_fragment_id - && fragment.was_visible(&version_in_range, &self.undo_map) - { - fragment.deletions.insert(local_timestamp); - if fragment.visible { - fragment.visible = false; - } - } + if fragment_start_offset < range.start { + let prefix_fragment = Fragment { + len: range.start - fragment_start_offset, + visible: fragment.visible, + deletions: fragment.deletions.clone(), + max_undos: fragment.max_undos.clone(), + + // TODO - remove + id: fragment.id.clone(), + insertion: fragment.insertion.clone(), + range_in_insertion: Default::default(), + }; - new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &None); + new_ropes.push_fragment(&prefix_fragment, prefix_fragment.visible); + new_fragments.push(prefix_fragment, &None); + fragment.len -= prefix_fragment.len; } - fragments_cursor.next(&None); - } + let suffix_fragment = if fragment_end_offset > range.end { + fragment.visible = false; - if let Some(new_text) = new_text { - let fragment = self.build_fragment_to_insert( - fragments_cursor.prev_item().as_ref().unwrap(), - None, - new_text, - local_timestamp, - lamport_timestamp, - ); - new_ropes.push_str(new_text); - new_fragments.push(fragment, &None); + // + + Some(Fragment {}); + } else { + None + }; } let (visible_text, deleted_text) = new_ropes.finish(); - new_fragments.push_tree(fragments_cursor.suffix(&None), &None); + new_fragments.push_tree(old_fragments.suffix(&None), &None); self.fragments = new_fragments; self.visible_text = visible_text; @@ -1323,6 +1243,134 @@ impl Buffer { Ok(()) } + // let mut new_fragments = fragments_cursor.slice( + // &VersionedOffset::Offset(range.start), + // SeekBias::Left, + // &version_cx, + // ); + // new_ropes.push_tree(new_fragments.summary().text); + + // if range.start == fragments_cursor.end(&version_cx).offset() { + // let fragment = fragments_cursor.item().unwrap().clone(); + // new_ropes.push_fragment(&fragment, fragment.visible); + // new_fragments.push(fragment, &None); + // fragments_cursor.next(&None); + // } + + // while let Some(fragment) = fragments_cursor.item() { + // let fragment_start_offset = fragments_cursor.start().offset(); + // let fragment_end_offset = fragments_cursor.end(&version_cx).offset(); + + // if new_text.is_none() && fragment_start_offset > range.end { + // break; + // } + + // if fragment_start_offset + + // if cursor_start_offset < range.start || cursor_end_offset > range.end { + // let split_start = if start_fragment_id == fragment.id { + // start_offset + // } else { + // fragment.range_in_insertion.start + // }; + // let split_end = if end_fragment_id == fragment.id { + // end_offset + // } else { + // fragment.range_in_insertion.end + // }; + // let (before_range, within_range, after_range) = self.split_fragment( + // fragments_cursor.prev_item().as_ref().unwrap(), + // &fragment, + // split_start..split_end, + // ); + // let insertion = if let Some(new_text) = new_text { + // let prev_fragment = fragments_cursor.prev_item(); + // Some(self.build_fragment_to_insert( + // before_range.as_ref().or(prev_fragment).unwrap(), + // within_range.as_ref().or(after_range.as_ref()), + // new_text, + // local_timestamp, + // lamport_timestamp, + // )) + // } else { + // None + // }; + // if let Some(fragment) = before_range { + // new_ropes.push_fragment(&fragment, fragment.visible); + // new_fragments.push(fragment, &None); + // } + // if let Some(fragment) = insertion { + // new_ropes.push_str(new_text.take().unwrap()); + // new_fragments.push(fragment, &None); + // } + // if let Some(mut fragment) = within_range { + // let fragment_was_visible = fragment.visible; + // if fragment.was_visible(&version_in_range, &self.undo_map) { + // fragment.deletions.insert(local_timestamp); + // if fragment.visible { + // fragment.visible = false; + // } + // } + // new_ropes.push_fragment(&fragment, fragment_was_visible); + // new_fragments.push(fragment, &None); + // } + // if let Some(fragment) = after_range { + // new_ropes.push_fragment(&fragment, fragment.visible); + // new_fragments.push(fragment, &None); + // } + // } else { + // if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp { + // let new_text = new_text.take().unwrap(); + // let fragment = self.build_fragment_to_insert( + // fragments_cursor.prev_item().as_ref().unwrap(), + // Some(&fragment), + // new_text, + // local_timestamp, + // lamport_timestamp, + // ); + // new_ropes.push_str(new_text); + // new_fragments.push(fragment, &None); + // } + + // let fragment_was_visible = fragment.visible; + // if fragment.id < end_fragment_id + // && fragment.was_visible(&version_in_range, &self.undo_map) + // { + // fragment.deletions.insert(local_timestamp); + // if fragment.visible { + // fragment.visible = false; + // } + // } + + // new_ropes.push_fragment(&fragment, fragment_was_visible); + // new_fragments.push(fragment, &None); + // } + // fragments_cursor.next(&None); + // } + + // if let Some(new_text) = new_text { + // let fragment = self.build_fragment_to_insert( + // fragments_cursor.prev_item().as_ref().unwrap(), + // None, + // new_text, + // local_timestamp, + // lamport_timestamp, + // ); + // new_ropes.push_str(new_text); + // new_fragments.push(fragment, &None); + // } + + // let (visible_text, deleted_text) = new_ropes.finish(); + // new_fragments.push_tree(fragments_cursor.suffix(&None), &None); + + // self.fragments = new_fragments; + // self.visible_text = visible_text; + // self.deleted_text = deleted_text; + // self.local_clock.observe(local_timestamp); + // self.lamport_clock.observe(lamport_timestamp); + // Ok(()) + // } + pub fn undo(&mut self, mut cx: Option<&mut ModelContext>) -> Vec { let was_dirty = self.is_dirty(); let old_version = self.version.clone(); @@ -1548,6 +1596,7 @@ impl Buffer { return Vec::new(); } + let version = &self.version; let mut ops = Vec::with_capacity(old_ranges.size_hint().0); let mut old_fragments = SumTree::new(); @@ -1682,11 +1731,8 @@ impl Buffer { ops.push(Operation::Edit { edit: EditOperation { id: local_timestamp, - start_id: start_id.unwrap(), - start_offset: start_offset.unwrap(), - end_id: end_id.unwrap(), - end_offset: end_offset.unwrap(), - version_in_range, + version, + range, new_text: new_text.clone(), }, lamport_timestamp, @@ -2047,8 +2093,7 @@ impl Buffer { &Some(version.clone()), ); let full_offset = cursor.start().1; - let visible_offset = cursor.start().0.offset(); - full_offset.0 + offset - visible_offset + full_offset.0 + offset - cursor.start().0.offset() } } }