diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 19a09a85ef..c7f22149d9 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -43,7 +43,7 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; -use sum_tree::{Bias, Cursor, SumTree, TreeMap}; +use sum_tree::{Bias, Cursor, Dimension, SumTree, Summary, TreeMap}; use text::{ BufferId, Edit, LineIndent, TextSummary, locator::Locator, @@ -417,8 +417,7 @@ struct Excerpt { #[derive(Clone)] pub struct MultiBufferExcerpt<'a> { excerpt: &'a Excerpt, - diff_transforms: - sum_tree::Cursor<'a, DiffTransform, (OutputDimension, ExcerptDimension)>, + diff_transforms: sum_tree::Cursor<'a, DiffTransform, DiffTransforms>, offset: usize, excerpt_offset: ExcerptDimension, buffer_offset: usize, @@ -506,10 +505,36 @@ pub struct ReversedMultiBufferBytes<'a> { chunk: &'a [u8], } +#[derive(Clone)] +struct DiffTransforms { + output_dimension: OutputDimension, + excerpt_dimension: ExcerptDimension, +} + +impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransforms { + fn zero(cx: &::Context) -> Self { + Self { + output_dimension: OutputDimension::zero(cx), + excerpt_dimension: as Dimension<'a, DiffTransformSummary>>::zero( + cx, + ), + } + } + + fn add_summary( + &mut self, + summary: &'a DiffTransformSummary, + cx: &::Context, + ) { + self.output_dimension.add_summary(summary, cx); + self.excerpt_dimension.add_summary(summary, cx); + } +} + #[derive(Clone)] struct MultiBufferCursor<'a, D: TextDimension> { excerpts: Cursor<'a, Excerpt, ExcerptDimension>, - diff_transforms: Cursor<'a, DiffTransform, (OutputDimension, ExcerptDimension)>, + diff_transforms: Cursor<'a, DiffTransform, DiffTransforms>, diffs: &'a TreeMap, cached_region: Option>, } @@ -5267,18 +5292,16 @@ impl MultiBufferSnapshot { excerpts.seek(&Some(start_locator), Bias::Left, &()); excerpts.prev(&()); - let mut diff_transforms = self - .diff_transforms - .cursor::<(OutputDimension, ExcerptDimension)>(&()); + let mut diff_transforms = self.diff_transforms.cursor::>(&()); diff_transforms.seek(&excerpts.start().1, Bias::Left, &()); - if diff_transforms.end(&()).1 < excerpts.start().1 { + if diff_transforms.end(&()).excerpt_dimension < excerpts.start().1 { diff_transforms.next(&()); } let excerpt = excerpts.item()?; Some(MultiBufferExcerpt { excerpt, - offset: diff_transforms.start().0.0, + offset: diff_transforms.start().output_dimension.0, buffer_offset: excerpt.range.context.start.to_offset(&excerpt.buffer), excerpt_offset: excerpts.start().1.clone(), diff_transforms, @@ -6386,13 +6409,15 @@ where self.cached_region.take(); self.diff_transforms .seek(&OutputDimension(*position), Bias::Right, &()); - if self.diff_transforms.item().is_none() && *position == self.diff_transforms.start().0.0 { + if self.diff_transforms.item().is_none() + && *position == self.diff_transforms.start().output_dimension.0 + { self.diff_transforms.prev(&()); } - let mut excerpt_position = self.diff_transforms.start().1.0; + let mut excerpt_position = self.diff_transforms.start().excerpt_dimension.0; if let Some(DiffTransform::BufferContent { .. }) = self.diff_transforms.item() { - let overshoot = *position - self.diff_transforms.start().0.0; + let overshoot = *position - self.diff_transforms.start().output_dimension.0; excerpt_position.add_assign(&overshoot); } @@ -6407,12 +6432,14 @@ where self.cached_region.take(); self.diff_transforms .seek_forward(&OutputDimension(*position), Bias::Right, &()); - if self.diff_transforms.item().is_none() && *position == self.diff_transforms.start().0.0 { + if self.diff_transforms.item().is_none() + && *position == self.diff_transforms.start().output_dimension.0 + { self.diff_transforms.prev(&()); } - let overshoot = *position - self.diff_transforms.start().0.0; - let mut excerpt_position = self.diff_transforms.start().1.0; + let overshoot = *position - self.diff_transforms.start().output_dimension.0; + let mut excerpt_position = self.diff_transforms.start().excerpt_dimension.0; if let Some(DiffTransform::BufferContent { .. }) = self.diff_transforms.item() { excerpt_position.add_assign(&overshoot); } @@ -6438,8 +6465,8 @@ where self.cached_region.take(); self.diff_transforms .seek(self.excerpts.start(), Bias::Left, &()); - if self.diff_transforms.end(&()).1 == *self.excerpts.start() - && self.diff_transforms.start().1 < *self.excerpts.start() + if self.diff_transforms.end(&()).excerpt_dimension == *self.excerpts.start() + && self.diff_transforms.start().excerpt_dimension < *self.excerpts.start() && self.diff_transforms.next_item().is_some() { self.diff_transforms.next(&()); @@ -6448,12 +6475,17 @@ where fn next(&mut self) { self.cached_region.take(); - match self.diff_transforms.end(&()).1.cmp(&self.excerpts.end(&())) { + match self + .diff_transforms + .end(&()) + .excerpt_dimension + .cmp(&self.excerpts.end(&())) + { cmp::Ordering::Less => self.diff_transforms.next(&()), cmp::Ordering::Greater => self.excerpts.next(&()), cmp::Ordering::Equal => { self.diff_transforms.next(&()); - if self.diff_transforms.end(&()).1 > self.excerpts.end(&()) + if self.diff_transforms.end(&()).excerpt_dimension > self.excerpts.end(&()) || self.diff_transforms.item().is_none() { self.excerpts.next(&()); @@ -6474,12 +6506,17 @@ where fn prev(&mut self) { self.cached_region.take(); - match self.diff_transforms.start().1.cmp(self.excerpts.start()) { + match self + .diff_transforms + .start() + .excerpt_dimension + .cmp(self.excerpts.start()) + { cmp::Ordering::Less => self.excerpts.prev(&()), cmp::Ordering::Greater => self.diff_transforms.prev(&()), cmp::Ordering::Equal => { self.diff_transforms.prev(&()); - if self.diff_transforms.start().1 < *self.excerpts.start() + if self.diff_transforms.start().excerpt_dimension < *self.excerpts.start() || self.diff_transforms.item().is_none() { self.excerpts.prev(&()); @@ -6496,9 +6533,9 @@ where } fn is_at_start_of_excerpt(&mut self) -> bool { - if self.diff_transforms.start().1 > *self.excerpts.start() { + if self.diff_transforms.start().excerpt_dimension > *self.excerpts.start() { return false; - } else if self.diff_transforms.start().1 < *self.excerpts.start() { + } else if self.diff_transforms.start().excerpt_dimension < *self.excerpts.start() { return true; } @@ -6512,9 +6549,9 @@ where } fn is_at_end_of_excerpt(&mut self) -> bool { - if self.diff_transforms.end(&()).1 < self.excerpts.end(&()) { + if self.diff_transforms.end(&()).excerpt_dimension < self.excerpts.end(&()) { return false; - } else if self.diff_transforms.end(&()).1 > self.excerpts.end(&()) + } else if self.diff_transforms.end(&()).excerpt_dimension > self.excerpts.end(&()) || self.diff_transforms.item().is_none() { return true; @@ -6535,7 +6572,7 @@ where let buffer = &excerpt.buffer; let buffer_context_start = excerpt.range.context.start.summary::(buffer); let mut buffer_start = buffer_context_start; - let overshoot = self.diff_transforms.end(&()).1.0 - self.excerpts.start().0; + let overshoot = self.diff_transforms.end(&()).excerpt_dimension.0 - self.excerpts.start().0; buffer_start.add_assign(&overshoot); Some(buffer_start) } @@ -6557,8 +6594,8 @@ where let buffer_range_len = rope_cursor.summary::(base_text_byte_range.end); let mut buffer_end = buffer_start; buffer_end.add_assign(&buffer_range_len); - let start = self.diff_transforms.start().0.0; - let end = self.diff_transforms.end(&()).0.0; + let start = self.diff_transforms.start().output_dimension.0; + let end = self.diff_transforms.end(&()).output_dimension.0; return Some(MultiBufferRegion { buffer, excerpt, @@ -6577,28 +6614,32 @@ where let buffer = &excerpt.buffer; let buffer_context_start = excerpt.range.context.start.summary::(buffer); - let mut start = self.diff_transforms.start().0.0; + let mut start = self.diff_transforms.start().output_dimension.0; let mut buffer_start = buffer_context_start; - if self.diff_transforms.start().1 < *self.excerpts.start() { - let overshoot = self.excerpts.start().0 - self.diff_transforms.start().1.0; + if self.diff_transforms.start().excerpt_dimension < *self.excerpts.start() { + let overshoot = + self.excerpts.start().0 - self.diff_transforms.start().excerpt_dimension.0; start.add_assign(&overshoot); } else { - let overshoot = self.diff_transforms.start().1.0 - self.excerpts.start().0; + let overshoot = + self.diff_transforms.start().excerpt_dimension.0 - self.excerpts.start().0; buffer_start.add_assign(&overshoot); } let mut end; let mut buffer_end; let has_trailing_newline; - if self.diff_transforms.end(&()).1.0 < self.excerpts.end(&()).0 { - let overshoot = self.diff_transforms.end(&()).1.0 - self.excerpts.start().0; - end = self.diff_transforms.end(&()).0.0; + if self.diff_transforms.end(&()).excerpt_dimension.0 < self.excerpts.end(&()).0 { + let overshoot = + self.diff_transforms.end(&()).excerpt_dimension.0 - self.excerpts.start().0; + end = self.diff_transforms.end(&()).output_dimension.0; buffer_end = buffer_context_start; buffer_end.add_assign(&overshoot); has_trailing_newline = false; } else { - let overshoot = self.excerpts.end(&()).0 - self.diff_transforms.start().1.0; - end = self.diff_transforms.start().0.0; + let overshoot = + self.excerpts.end(&()).0 - self.diff_transforms.start().excerpt_dimension.0; + end = self.diff_transforms.start().output_dimension.0; end.add_assign(&overshoot); buffer_end = excerpt.range.context.end.summary::(buffer); has_trailing_newline = excerpt.has_trailing_newline; @@ -6994,9 +7035,9 @@ impl<'a> MultiBufferExcerpt<'a> { } fn map_offset_to_buffer_internal(&self, offset: usize) -> usize { - let mut excerpt_offset = self.diff_transforms.start().1.clone(); + let mut excerpt_offset = self.diff_transforms.start().excerpt_dimension.clone(); if let Some(DiffTransform::BufferContent { .. }) = self.diff_transforms.item() { - excerpt_offset.0 += offset - self.diff_transforms.start().0.0; + excerpt_offset.0 += offset - self.diff_transforms.start().output_dimension.0; }; let offset_in_excerpt = excerpt_offset.0.saturating_sub(self.excerpt_offset.0); self.buffer_offset + offset_in_excerpt @@ -7019,22 +7060,22 @@ impl<'a> MultiBufferExcerpt<'a> { let overshoot = buffer_range.start - self.buffer_offset; let excerpt_offset = ExcerptDimension(self.excerpt_offset.0 + overshoot); self.diff_transforms.seek(&excerpt_offset, Bias::Right, &()); - if excerpt_offset.0 < self.diff_transforms.start().1.0 { + if excerpt_offset.0 < self.diff_transforms.start().excerpt_dimension.0 { log::warn!( "Attempting to map a range from a buffer offset that starts before the current buffer offset" ); return buffer_range; } - let overshoot = excerpt_offset.0 - self.diff_transforms.start().1.0; - let start = self.diff_transforms.start().0.0 + overshoot; + let overshoot = excerpt_offset.0 - self.diff_transforms.start().excerpt_dimension.0; + let start = self.diff_transforms.start().output_dimension.0 + overshoot; let end = if buffer_range.end > buffer_range.start { let overshoot = buffer_range.end - self.buffer_offset; let excerpt_offset = ExcerptDimension(self.excerpt_offset.0 + overshoot); self.diff_transforms .seek_forward(&excerpt_offset, Bias::Right, &()); - let overshoot = excerpt_offset.0 - self.diff_transforms.start().1.0; - self.diff_transforms.start().0.0 + overshoot + let overshoot = excerpt_offset.0 - self.diff_transforms.start().excerpt_dimension.0; + self.diff_transforms.start().output_dimension.0 + overshoot } else { start }; @@ -7201,7 +7242,7 @@ impl sum_tree::Summary for ExcerptSummary { fn add_summary(&mut self, summary: &Self, _: &()) { debug_assert!(summary.excerpt_locator > self.excerpt_locator); self.excerpt_locator = summary.excerpt_locator.clone(); - self.text.add_summary(&summary.text, &()); + Summary::add_summary(&mut self.text, &summary.text, &()); self.widest_line_number = cmp::max(self.widest_line_number, summary.widest_line_number); } } @@ -7310,16 +7351,11 @@ impl sum_tree::SeekTarget<'_, DiffTransformSummary, Diff } } -impl - sum_tree::SeekTarget<'_, DiffTransformSummary, (OutputDimension, ExcerptDimension)> +impl sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms> for ExcerptDimension { - fn cmp( - &self, - cursor_location: &(OutputDimension, ExcerptDimension), - _: &(), - ) -> cmp::Ordering { - Ord::cmp(&self.0, &cursor_location.1.0) + fn cmp(&self, cursor_location: &DiffTransforms, _: &()) -> cmp::Ordering { + Ord::cmp(&self.0, &cursor_location.excerpt_dimension.0) } } @@ -7333,6 +7369,14 @@ impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for Exc } } +impl sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms> + for OutputDimension +{ + fn cmp(&self, cursor_location: &DiffTransforms, _: &()) -> cmp::Ordering { + Ord::cmp(&self.0, &cursor_location.output_dimension.0) + } +} + impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for OutputDimension { fn zero(_: &()) -> Self { OutputDimension(D::default()) @@ -7401,7 +7445,7 @@ impl Iterator for MultiBufferRows<'_> { if let Some(next_region) = self.cursor.region() { region = next_region; } else { - if self.point == self.cursor.diff_transforms.end(&()).0.0 { + if self.point == self.cursor.diff_transforms.end(&()).output_dimension.0 { let multibuffer_row = MultiBufferRow(self.point.row); let last_excerpt = self .cursor