From c67cfd7fe1142214939ceba879aff25a211f16e0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 11 Mar 2022 12:41:05 +0100 Subject: [PATCH 1/7] Respect excerpt's range when comparing two anchors both belonging to it --- crates/editor/src/display_map/fold_map.rs | 8 ++++++ crates/editor/src/multi_buffer.rs | 14 ++++------ crates/editor/src/multi_buffer/anchor.rs | 32 +++++++++++------------ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index daafbee57b..4f25f32e21 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -241,6 +241,14 @@ impl FoldMap { self.buffer.lock().len(), "transform tree does not match buffer's length" ); + + let mut folds = self.folds.iter().peekable(); + while let Some(fold) = folds.next() { + if let Some(next_fold) = folds.peek() { + let comparison = fold.0.cmp(&next_fold.0, &self.buffer.lock()).unwrap(); + assert!(comparison.is_le()); + } + } } } diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 3678f8f116..fd2ed744ba 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -1998,10 +1998,9 @@ impl MultiBufferSnapshot { pub fn can_resolve(&self, anchor: &Anchor) -> bool { if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() { true - } else if let Some((buffer_id, buffer_snapshot)) = - self.buffer_snapshot_for_excerpt(&anchor.excerpt_id) - { - anchor.buffer_id == Some(buffer_id) && buffer_snapshot.can_resolve(&anchor.text_anchor) + } else if let Some(excerpt) = self.excerpt(&anchor.excerpt_id) { + anchor.buffer_id == Some(excerpt.buffer_id) + && excerpt.buffer.can_resolve(&anchor.text_anchor) } else { false } @@ -2231,15 +2230,12 @@ impl MultiBufferSnapshot { )) } - fn buffer_snapshot_for_excerpt<'a>( - &'a self, - excerpt_id: &'a ExcerptId, - ) -> Option<(usize, &'a BufferSnapshot)> { + fn excerpt<'a>(&'a self, excerpt_id: &'a ExcerptId) -> Option<&'a Excerpt> { let mut cursor = self.excerpts.cursor::>(); cursor.seek(&Some(excerpt_id), Bias::Left, &()); if let Some(excerpt) = cursor.item() { if excerpt.id == *excerpt_id { - return Some((excerpt.buffer_id, &excerpt.buffer)); + return Some(excerpt); } } None diff --git a/crates/editor/src/multi_buffer/anchor.rs b/crates/editor/src/multi_buffer/anchor.rs index c51eb2a4c7..3de03fb123 100644 --- a/crates/editor/src/multi_buffer/anchor.rs +++ b/crates/editor/src/multi_buffer/anchor.rs @@ -40,17 +40,19 @@ impl Anchor { if excerpt_id_cmp.is_eq() { if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() { Ok(Ordering::Equal) - } else if let Some((buffer_id, buffer_snapshot)) = - snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) - { + } else if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { // Even though the anchor refers to a valid excerpt the underlying buffer might have // changed. In that case, treat the anchor as if it were at the start of that // excerpt. - if self.buffer_id == Some(buffer_id) && other.buffer_id == Some(buffer_id) { - self.text_anchor.cmp(&other.text_anchor, buffer_snapshot) - } else if self.buffer_id == Some(buffer_id) { + if self.buffer_id == Some(excerpt.buffer_id) + && other.buffer_id == Some(excerpt.buffer_id) + { + let self_anchor = excerpt.clip_anchor(self.text_anchor.clone()); + let other_anchor = excerpt.clip_anchor(other.text_anchor.clone()); + self_anchor.cmp(&other_anchor, &excerpt.buffer) + } else if self.buffer_id == Some(excerpt.buffer_id) { Ok(Ordering::Greater) - } else if other.buffer_id == Some(buffer_id) { + } else if other.buffer_id == Some(excerpt.buffer_id) { Ok(Ordering::Less) } else { Ok(Ordering::Equal) @@ -65,14 +67,12 @@ impl Anchor { pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor { if self.text_anchor.bias != Bias::Left { - if let Some((buffer_id, buffer_snapshot)) = - snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) - { - if self.buffer_id == Some(buffer_id) { + if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { + if self.buffer_id == Some(excerpt.buffer_id) { return Self { buffer_id: self.buffer_id, excerpt_id: self.excerpt_id.clone(), - text_anchor: self.text_anchor.bias_left(buffer_snapshot), + text_anchor: self.text_anchor.bias_left(&excerpt.buffer), }; } } @@ -82,14 +82,12 @@ impl Anchor { pub fn bias_right(&self, snapshot: &MultiBufferSnapshot) -> Anchor { if self.text_anchor.bias != Bias::Right { - if let Some((buffer_id, buffer_snapshot)) = - snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) - { - if self.buffer_id == Some(buffer_id) { + if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { + if self.buffer_id == Some(excerpt.buffer_id) { return Self { buffer_id: self.buffer_id, excerpt_id: self.excerpt_id.clone(), - text_anchor: self.text_anchor.bias_right(buffer_snapshot), + text_anchor: self.text_anchor.bias_right(&excerpt.buffer), }; } } From 134496ce8fe262970cf8f25e34d23dcc29b6c679 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 11 Mar 2022 08:24:42 -0700 Subject: [PATCH 2/7] Remove dead code Co-Authored-By: Antonio Scandurra --- crates/language/src/proto.rs | 44 ------------------------------------ crates/text/src/locator.rs | 5 ---- 2 files changed, 49 deletions(-) diff --git a/crates/language/src/proto.rs b/crates/language/src/proto.rs index f5e797bca7..19bfc10cd0 100644 --- a/crates/language/src/proto.rs +++ b/crates/language/src/proto.rs @@ -4,7 +4,6 @@ use crate::{ }; use anyhow::{anyhow, Result}; use clock::ReplicaId; -use collections::HashSet; use lsp::DiagnosticSeverity; use rpc::proto; use std::{ops::Range, sync::Arc}; @@ -100,26 +99,6 @@ pub fn serialize_undo_map_entry( } } -pub fn serialize_buffer_fragment(fragment: &text::Fragment) -> proto::BufferFragment { - proto::BufferFragment { - replica_id: fragment.insertion_timestamp.replica_id as u32, - local_timestamp: fragment.insertion_timestamp.local, - lamport_timestamp: fragment.insertion_timestamp.lamport, - insertion_offset: fragment.insertion_offset as u32, - len: fragment.len as u32, - visible: fragment.visible, - deletions: fragment - .deletions - .iter() - .map(|clock| proto::VectorClockEntry { - replica_id: clock.replica_id as u32, - timestamp: clock.value, - }) - .collect(), - max_undos: serialize_version(&fragment.max_undos), - } -} - pub fn serialize_selections(selections: &Arc<[Selection]>) -> Vec { selections .iter() @@ -290,29 +269,6 @@ pub fn deserialize_undo_map_entry( ) } -pub fn deserialize_buffer_fragment( - message: proto::BufferFragment, - ix: usize, - count: usize, -) -> Fragment { - Fragment { - id: locator::Locator::from_index(ix, count), - insertion_timestamp: InsertionTimestamp { - replica_id: message.replica_id as ReplicaId, - local: message.local_timestamp, - lamport: message.lamport_timestamp, - }, - insertion_offset: message.insertion_offset as usize, - len: message.len as usize, - visible: message.visible, - deletions: HashSet::from_iter(message.deletions.into_iter().map(|entry| clock::Local { - replica_id: entry.replica_id as ReplicaId, - value: entry.timestamp, - })), - max_undos: deserialize_version(message.max_undos), - } -} - pub fn deserialize_selections(selections: Vec) -> Arc<[Selection]> { Arc::from( selections diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index cb1e78153c..e4feaf99ac 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -19,11 +19,6 @@ impl Locator { Self(smallvec![u64::MAX]) } - pub fn from_index(ix: usize, count: usize) -> Self { - let id = (1 + ix as u64) * (u64::MAX / (count as u64 + 2)); - Self(smallvec![id]) - } - pub fn assign(&mut self, other: &Self) { self.0.resize(other.0.len(), 0); self.0.copy_from_slice(&other.0); From 5407f25c941c1e0016882bd889698a81aa227ecb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 11 Mar 2022 08:50:50 -0700 Subject: [PATCH 3/7] Don't reuse excerpt ids in MultiBuffer This prevents anchors from swapping their ordering, which was causing issues in FoldMap. Co-Authored-By: Antonio Scandurra --- crates/editor/src/multi_buffer.rs | 12 ++++++++++-- crates/text/src/locator.rs | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index fd2ed744ba..766acd717e 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -36,6 +36,7 @@ pub type ExcerptId = Locator; pub struct MultiBuffer { snapshot: RefCell, buffers: RefCell>, + used_excerpt_ids: SumTree, subscriptions: Topic, singleton: bool, replica_id: ReplicaId, @@ -155,6 +156,7 @@ impl MultiBuffer { Self { snapshot: Default::default(), buffers: Default::default(), + used_excerpt_ids: Default::default(), subscriptions: Default::default(), singleton: false, replica_id, @@ -192,6 +194,7 @@ impl MultiBuffer { Self { snapshot: RefCell::new(self.snapshot.borrow().clone()), buffers: RefCell::new(buffers), + used_excerpt_ids: Default::default(), subscriptions: Default::default(), singleton: self.singleton, replica_id: self.replica_id, @@ -759,13 +762,18 @@ impl MultiBuffer { ); let mut next_id = ExcerptId::max(); - if let Some(next_excerpt) = cursor.item() { - next_id = next_excerpt.id.clone(); + { + let mut used_cursor = self.used_excerpt_ids.cursor::(); + used_cursor.seek(&prev_id, Bias::Right, &()); + if let Some(used_id) = used_cursor.item() { + next_id = used_id.clone(); + } } let mut ids = Vec::new(); while let Some(range) = ranges.next() { let id = ExcerptId::between(&prev_id, &next_id); + self.used_excerpt_ids.insert_or_replace(id.clone(), &()); if let Err(ix) = buffer_state.excerpts.binary_search(&id) { buffer_state.excerpts.insert(ix, id.clone()); } diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index e4feaf99ac..f98f050339 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -49,6 +49,30 @@ impl Default for Locator { } } +impl sum_tree::Item for Locator { + type Summary = Locator; + + fn summary(&self) -> Self::Summary { + self.clone() + } +} + +impl sum_tree::KeyedItem for Locator { + type Key = Locator; + + fn key(&self) -> Self::Key { + self.clone() + } +} + +impl sum_tree::Summary for Locator { + type Context = (); + + fn add_summary(&mut self, summary: &Self, _: &()) { + self.assign(summary); + } +} + #[cfg(test)] mod tests { use super::*; From a74b602f1832784e3a9170d836d2f913d428a3ba Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 11 Mar 2022 17:03:13 +0100 Subject: [PATCH 4/7] Assume the anchor is valid if we can find an excerpt that contains it --- crates/editor/src/multi_buffer.rs | 42 ++++++++++++++---------- crates/editor/src/multi_buffer/anchor.rs | 41 +++++++---------------- 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 766acd717e..1b567d6993 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -971,10 +971,13 @@ impl MultiBuffer { ) -> Option<(ModelHandle, language::Anchor)> { let snapshot = self.read(cx); let anchor = snapshot.anchor_before(position); - Some(( - self.buffers.borrow()[&anchor.buffer_id?].buffer.clone(), - anchor.text_anchor, - )) + let buffer = self + .buffers + .borrow() + .get(&anchor.buffer_id?)? + .buffer + .clone(); + Some((buffer, anchor.text_anchor)) } fn on_buffer_event( @@ -1028,14 +1031,19 @@ impl MultiBuffer { let snapshot = self.snapshot(cx); let anchor = snapshot.anchor_before(position); - anchor.buffer_id.map_or(false, |buffer_id| { - let buffer = self.buffers.borrow()[&buffer_id].buffer.clone(); - buffer - .read(cx) - .completion_triggers() - .iter() - .any(|string| string == text) - }) + anchor + .buffer_id + .and_then(|buffer_id| { + let buffer = self.buffers.borrow().get(&buffer_id)?.buffer.clone(); + Some( + buffer + .read(cx) + .completion_triggers() + .iter() + .any(|string| string == text), + ) + }) + .unwrap_or(false) } pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc> { @@ -1765,7 +1773,7 @@ impl MultiBufferSnapshot { let mut position = D::from_text_summary(&cursor.start().text); if let Some(excerpt) = cursor.item() { - if excerpt.id == anchor.excerpt_id && Some(excerpt.buffer_id) == anchor.buffer_id { + if excerpt.id == anchor.excerpt_id { let excerpt_buffer_start = excerpt.range.start.summary::(&excerpt.buffer); let excerpt_buffer_end = excerpt.range.end.summary::(&excerpt.buffer); let buffer_position = cmp::min( @@ -1796,10 +1804,9 @@ impl MultiBufferSnapshot { let mut summaries = Vec::new(); while let Some(anchor) = anchors.peek() { let excerpt_id = &anchor.excerpt_id; - let buffer_id = anchor.buffer_id; let excerpt_anchors = iter::from_fn(|| { let anchor = anchors.peek()?; - if anchor.excerpt_id == *excerpt_id && anchor.buffer_id == buffer_id { + if anchor.excerpt_id == *excerpt_id { Some(&anchors.next().unwrap().text_anchor) } else { None @@ -1813,7 +1820,7 @@ impl MultiBufferSnapshot { let position = D::from_text_summary(&cursor.start().text); if let Some(excerpt) = cursor.item() { - if excerpt.id == *excerpt_id && Some(excerpt.buffer_id) == buffer_id { + if excerpt.id == *excerpt_id { let excerpt_buffer_start = excerpt.range.start.summary::(&excerpt.buffer); let excerpt_buffer_end = excerpt.range.end.summary::(&excerpt.buffer); summaries.extend( @@ -2007,8 +2014,7 @@ impl MultiBufferSnapshot { if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() { true } else if let Some(excerpt) = self.excerpt(&anchor.excerpt_id) { - anchor.buffer_id == Some(excerpt.buffer_id) - && excerpt.buffer.can_resolve(&anchor.text_anchor) + excerpt.buffer.can_resolve(&anchor.text_anchor) } else { false } diff --git a/crates/editor/src/multi_buffer/anchor.rs b/crates/editor/src/multi_buffer/anchor.rs index 3de03fb123..33147ce285 100644 --- a/crates/editor/src/multi_buffer/anchor.rs +++ b/crates/editor/src/multi_buffer/anchor.rs @@ -41,22 +41,7 @@ impl Anchor { if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() { Ok(Ordering::Equal) } else if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { - // Even though the anchor refers to a valid excerpt the underlying buffer might have - // changed. In that case, treat the anchor as if it were at the start of that - // excerpt. - if self.buffer_id == Some(excerpt.buffer_id) - && other.buffer_id == Some(excerpt.buffer_id) - { - let self_anchor = excerpt.clip_anchor(self.text_anchor.clone()); - let other_anchor = excerpt.clip_anchor(other.text_anchor.clone()); - self_anchor.cmp(&other_anchor, &excerpt.buffer) - } else if self.buffer_id == Some(excerpt.buffer_id) { - Ok(Ordering::Greater) - } else if other.buffer_id == Some(excerpt.buffer_id) { - Ok(Ordering::Less) - } else { - Ok(Ordering::Equal) - } + self.text_anchor.cmp(&other.text_anchor, &excerpt.buffer) } else { Ok(Ordering::Equal) } @@ -68,13 +53,11 @@ impl Anchor { pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor { if self.text_anchor.bias != Bias::Left { if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { - if self.buffer_id == Some(excerpt.buffer_id) { - return Self { - buffer_id: self.buffer_id, - excerpt_id: self.excerpt_id.clone(), - text_anchor: self.text_anchor.bias_left(&excerpt.buffer), - }; - } + return Self { + buffer_id: self.buffer_id, + excerpt_id: self.excerpt_id.clone(), + text_anchor: self.text_anchor.bias_left(&excerpt.buffer), + }; } } self.clone() @@ -83,13 +66,11 @@ impl Anchor { pub fn bias_right(&self, snapshot: &MultiBufferSnapshot) -> Anchor { if self.text_anchor.bias != Bias::Right { if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) { - if self.buffer_id == Some(excerpt.buffer_id) { - return Self { - buffer_id: self.buffer_id, - excerpt_id: self.excerpt_id.clone(), - text_anchor: self.text_anchor.bias_right(&excerpt.buffer), - }; - } + return Self { + buffer_id: self.buffer_id, + excerpt_id: self.excerpt_id.clone(), + text_anchor: self.text_anchor.bias_right(&excerpt.buffer), + }; } } self.clone() From 71aa5e5360d97bd8a84b4ac136a957d4b6638ce9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 11 Mar 2022 17:13:28 +0100 Subject: [PATCH 5/7] :lipstick: --- crates/editor/src/multi_buffer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 1b567d6993..756d21e9b5 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -36,7 +36,7 @@ pub type ExcerptId = Locator; pub struct MultiBuffer { snapshot: RefCell, buffers: RefCell>, - used_excerpt_ids: SumTree, + used_excerpt_ids: SumTree, subscriptions: Topic, singleton: bool, replica_id: ReplicaId, From cd4a9f317822d10c7f2aaf268ec301c0a05c3320 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 12 Mar 2022 13:03:45 +0100 Subject: [PATCH 6/7] Fix bug in selection position maintenance while renaming symbol We were resolving the selection with the wrong buffer, which now causes a panic because we don't check the anchor's `buffer_id` anymore. --- crates/editor/src/editor.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0544355359..ba16522972 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4517,25 +4517,32 @@ impl Editor { self.remove_blocks([rename.block_id].into_iter().collect(), cx); self.clear_highlighted_ranges::(cx); - let editor = rename.editor.read(cx); - let snapshot = self.buffer.read(cx).snapshot(cx); - let selection = editor.newest_selection_with_snapshot::(&snapshot); + let selection_in_rename_editor = rename.editor.read(cx).newest_selection::(cx); // Update the selection to match the position of the selection inside // the rename editor. + let snapshot = self.buffer.read(cx).read(cx); let rename_range = rename.range.to_offset(&snapshot); let start = snapshot - .clip_offset(rename_range.start + selection.start, Bias::Left) + .clip_offset( + rename_range.start + selection_in_rename_editor.start, + Bias::Left, + ) .min(rename_range.end); let end = snapshot - .clip_offset(rename_range.start + selection.end, Bias::Left) + .clip_offset( + rename_range.start + selection_in_rename_editor.end, + Bias::Left, + ) .min(rename_range.end); + drop(snapshot); + self.update_selections( vec![Selection { id: self.newest_anchor_selection().id, start, end, - reversed: selection.reversed, + reversed: selection_in_rename_editor.reversed, goal: SelectionGoal::None, }], None, From dd1711d53f56a29127b1c08db88df5ef6e678efe Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 12 Mar 2022 17:50:09 +0100 Subject: [PATCH 7/7] Account for all excerpts ever inserted when determining new excerpt ID --- crates/editor/src/multi_buffer.rs | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 756d21e9b5..cc4241cc6b 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -751,29 +751,31 @@ impl MultiBuffer { let mut cursor = snapshot.excerpts.cursor::>(); let mut new_excerpts = cursor.slice(&Some(prev_excerpt_id), Bias::Right, &()); - let mut prev_id = ExcerptId::min(); let edit_start = new_excerpts.summary().text.bytes; new_excerpts.update_last( |excerpt| { excerpt.has_trailing_newline = true; - prev_id = excerpt.id.clone(); }, &(), ); - let mut next_id = ExcerptId::max(); - { - let mut used_cursor = self.used_excerpt_ids.cursor::(); - used_cursor.seek(&prev_id, Bias::Right, &()); - if let Some(used_id) = used_cursor.item() { - next_id = used_id.clone(); - } - } + let mut used_cursor = self.used_excerpt_ids.cursor::(); + used_cursor.seek(prev_excerpt_id, Bias::Right, &()); + let mut prev_id = if let Some(excerpt_id) = used_cursor.prev_item() { + excerpt_id.clone() + } else { + ExcerptId::min() + }; + let next_id = if let Some(excerpt_id) = used_cursor.item() { + excerpt_id.clone() + } else { + ExcerptId::max() + }; + drop(used_cursor); let mut ids = Vec::new(); while let Some(range) = ranges.next() { let id = ExcerptId::between(&prev_id, &next_id); - self.used_excerpt_ids.insert_or_replace(id.clone(), &()); if let Err(ix) = buffer_state.excerpts.binary_search(&id) { buffer_state.excerpts.insert(ix, id.clone()); } @@ -790,6 +792,10 @@ impl MultiBuffer { prev_id = id.clone(); ids.push(id); } + self.used_excerpt_ids.edit( + ids.iter().cloned().map(sum_tree::Edit::Insert).collect(), + &(), + ); let edit_end = new_excerpts.summary().text.bytes; @@ -3223,8 +3229,8 @@ mod tests { let snapshot_2 = multibuffer.read(cx).snapshot(cx); assert_eq!(snapshot_2.text(), "ABCD\nGHIJ\nMNOP"); - // The old excerpt id has been reused. - assert_eq!(excerpt_id_2, excerpt_id_1); + // The old excerpt id doesn't get reused. + assert_ne!(excerpt_id_2, excerpt_id_1); // Resolve some anchors from the previous snapshot in the new snapshot. // Although there is still an excerpt with the same id, it is for @@ -3276,7 +3282,7 @@ mod tests { ]; assert_eq!( snapshot_3.summaries_for_anchors::(&anchors), - &[0, 2, 9, 13] + &[0, 2, 5, 13] ); let new_anchors = snapshot_3.refresh_anchors(&anchors);