Respect excerpt's range when comparing two anchors both belonging to it

This commit is contained in:
Antonio Scandurra 2022-03-11 12:41:05 +01:00
parent a067150b5a
commit c67cfd7fe1
3 changed files with 28 additions and 26 deletions

View file

@ -241,6 +241,14 @@ impl FoldMap {
self.buffer.lock().len(), self.buffer.lock().len(),
"transform tree does not match buffer's length" "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());
}
}
} }
} }

View file

@ -1998,10 +1998,9 @@ impl MultiBufferSnapshot {
pub fn can_resolve(&self, anchor: &Anchor) -> bool { pub fn can_resolve(&self, anchor: &Anchor) -> bool {
if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() { if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() {
true true
} else if let Some((buffer_id, buffer_snapshot)) = } else if let Some(excerpt) = self.excerpt(&anchor.excerpt_id) {
self.buffer_snapshot_for_excerpt(&anchor.excerpt_id) anchor.buffer_id == Some(excerpt.buffer_id)
{ && excerpt.buffer.can_resolve(&anchor.text_anchor)
anchor.buffer_id == Some(buffer_id) && buffer_snapshot.can_resolve(&anchor.text_anchor)
} else { } else {
false false
} }
@ -2231,15 +2230,12 @@ impl MultiBufferSnapshot {
)) ))
} }
fn buffer_snapshot_for_excerpt<'a>( fn excerpt<'a>(&'a self, excerpt_id: &'a ExcerptId) -> Option<&'a Excerpt> {
&'a self,
excerpt_id: &'a ExcerptId,
) -> Option<(usize, &'a BufferSnapshot)> {
let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>(); let mut cursor = self.excerpts.cursor::<Option<&ExcerptId>>();
cursor.seek(&Some(excerpt_id), Bias::Left, &()); cursor.seek(&Some(excerpt_id), Bias::Left, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
if excerpt.id == *excerpt_id { if excerpt.id == *excerpt_id {
return Some((excerpt.buffer_id, &excerpt.buffer)); return Some(excerpt);
} }
} }
None None

View file

@ -40,17 +40,19 @@ impl Anchor {
if excerpt_id_cmp.is_eq() { if excerpt_id_cmp.is_eq() {
if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() { if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() {
Ok(Ordering::Equal) Ok(Ordering::Equal)
} else if let Some((buffer_id, buffer_snapshot)) = } else if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) {
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id)
{
// Even though the anchor refers to a valid excerpt the underlying buffer might have // 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 // changed. In that case, treat the anchor as if it were at the start of that
// excerpt. // excerpt.
if self.buffer_id == Some(buffer_id) && other.buffer_id == Some(buffer_id) { if self.buffer_id == Some(excerpt.buffer_id)
self.text_anchor.cmp(&other.text_anchor, buffer_snapshot) && other.buffer_id == Some(excerpt.buffer_id)
} else if self.buffer_id == Some(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) Ok(Ordering::Greater)
} else if other.buffer_id == Some(buffer_id) { } else if other.buffer_id == Some(excerpt.buffer_id) {
Ok(Ordering::Less) Ok(Ordering::Less)
} else { } else {
Ok(Ordering::Equal) Ok(Ordering::Equal)
@ -65,14 +67,12 @@ impl Anchor {
pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor { pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
if self.text_anchor.bias != Bias::Left { if self.text_anchor.bias != Bias::Left {
if let Some((buffer_id, buffer_snapshot)) = if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) {
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) if self.buffer_id == Some(excerpt.buffer_id) {
{
if self.buffer_id == Some(buffer_id) {
return Self { return Self {
buffer_id: self.buffer_id, buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(), 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 { pub fn bias_right(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
if self.text_anchor.bias != Bias::Right { if self.text_anchor.bias != Bias::Right {
if let Some((buffer_id, buffer_snapshot)) = if let Some(excerpt) = snapshot.excerpt(&self.excerpt_id) {
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) if self.buffer_id == Some(excerpt.buffer_id) {
{
if self.buffer_id == Some(buffer_id) {
return Self { return Self {
buffer_id: self.buffer_id, buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(), excerpt_id: self.excerpt_id.clone(),
text_anchor: self.text_anchor.bias_right(buffer_snapshot), text_anchor: self.text_anchor.bias_right(&excerpt.buffer),
}; };
} }
} }