multi_buffer: Refactor diff_transforms field into a separate struct (#32237)
A minor refactor ~needed to unblock #22546; it's pretty hard to add an extra field to `diff_transforms` dimension, as it is a 2-tuple (which uses a blanket impl) Release Notes: - N/A
This commit is contained in:
parent
cd0ef4b982
commit
7afee64119
1 changed files with 98 additions and 54 deletions
|
@ -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<usize>, ExcerptDimension<usize>)>,
|
||||
diff_transforms: sum_tree::Cursor<'a, DiffTransform, DiffTransforms<usize>>,
|
||||
offset: usize,
|
||||
excerpt_offset: ExcerptDimension<usize>,
|
||||
buffer_offset: usize,
|
||||
|
@ -506,10 +505,36 @@ pub struct ReversedMultiBufferBytes<'a> {
|
|||
chunk: &'a [u8],
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DiffTransforms<D> {
|
||||
output_dimension: OutputDimension<D>,
|
||||
excerpt_dimension: ExcerptDimension<D>,
|
||||
}
|
||||
|
||||
impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransforms<D> {
|
||||
fn zero(cx: &<DiffTransformSummary as sum_tree::Summary>::Context) -> Self {
|
||||
Self {
|
||||
output_dimension: OutputDimension::zero(cx),
|
||||
excerpt_dimension: <ExcerptDimension<D> as Dimension<'a, DiffTransformSummary>>::zero(
|
||||
cx,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_summary(
|
||||
&mut self,
|
||||
summary: &'a DiffTransformSummary,
|
||||
cx: &<DiffTransformSummary as sum_tree::Summary>::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<D>>,
|
||||
diff_transforms: Cursor<'a, DiffTransform, (OutputDimension<D>, ExcerptDimension<D>)>,
|
||||
diff_transforms: Cursor<'a, DiffTransform, DiffTransforms<D>>,
|
||||
diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>,
|
||||
cached_region: Option<MultiBufferRegion<'a, D>>,
|
||||
}
|
||||
|
@ -5267,18 +5292,16 @@ impl MultiBufferSnapshot {
|
|||
excerpts.seek(&Some(start_locator), Bias::Left, &());
|
||||
excerpts.prev(&());
|
||||
|
||||
let mut diff_transforms = self
|
||||
.diff_transforms
|
||||
.cursor::<(OutputDimension<usize>, ExcerptDimension<usize>)>(&());
|
||||
let mut diff_transforms = self.diff_transforms.cursor::<DiffTransforms<usize>>(&());
|
||||
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::<D>(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::<D>(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::<D>(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::<D>(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<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, Diff
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: TextDimension + Ord>
|
||||
sum_tree::SeekTarget<'_, DiffTransformSummary, (OutputDimension<D>, ExcerptDimension<D>)>
|
||||
impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>>
|
||||
for ExcerptDimension<D>
|
||||
{
|
||||
fn cmp(
|
||||
&self,
|
||||
cursor_location: &(OutputDimension<D>, ExcerptDimension<D>),
|
||||
_: &(),
|
||||
) -> cmp::Ordering {
|
||||
Ord::cmp(&self.0, &cursor_location.1.0)
|
||||
fn cmp(&self, cursor_location: &DiffTransforms<D>, _: &()) -> 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<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>>
|
||||
for OutputDimension<D>
|
||||
{
|
||||
fn cmp(&self, cursor_location: &DiffTransforms<D>, _: &()) -> cmp::Ordering {
|
||||
Ord::cmp(&self.0, &cursor_location.output_dimension.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for OutputDimension<D> {
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue