Detailed changes
@@ -212,7 +212,7 @@ impl AgentDiffPane {
self.multibuffer.update(cx, |multibuffer, cx| {
for path in paths_to_delete {
- multibuffer.remove_excerpts_for_path(path, cx);
+ multibuffer.remove_excerpts(path, cx);
}
});
@@ -442,10 +442,9 @@ impl InlineAssistant {
let newest_selection = newest_selection.unwrap();
let mut codegen_ranges = Vec::new();
- for (buffer, buffer_range, excerpt_id) in
- snapshot.ranges_to_buffer_ranges(selections.iter().map(|selection| {
- snapshot.anchor_before(selection.start)..snapshot.anchor_after(selection.end)
- }))
+ for (buffer, buffer_range, excerpt_id) in selections
+ .iter()
+ .map(|selection| selection.range_to_buffer_range(selection.start..selection.end))
{
let anchor_range = Anchor::range_in_buffer(
excerpt_id,
@@ -329,7 +329,7 @@ impl ProjectDiagnosticsEditor {
continue;
}
self.multibuffer.update(cx, |b, cx| {
- b.remove_excerpts_for_path(PathKey::for_buffer(&buffer, cx), cx);
+ b.remove_excerpts(PathKey::for_buffer(&buffer, cx), cx);
});
}
}
@@ -18550,7 +18550,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut TestAppContext) {
// Remove some excerpts.
leader.update(cx, |leader, cx| {
leader.buffer.update(cx, |multibuffer, cx| {
- multibuffer.remove_excerpts_for_path(
+ multibuffer.remove_excerpts(
PathKey::with_sort_prefix(1, rel_path("b.txt").into_arc()),
cx,
);
@@ -3060,7 +3060,7 @@ let c = 3;"#
editor
.update(cx, |editor, _, cx| {
editor.buffer().update(cx, |multibuffer, cx| {
- multibuffer.remove_excerpts_for_path(PathKey::sorted(1), cx);
+ multibuffer.remove_excerpts(PathKey::sorted(1), cx);
})
})
.unwrap();
@@ -1074,7 +1074,7 @@ impl SplittableEditor {
pub fn remove_excerpts_for_path(&mut self, path: PathKey, cx: &mut Context<Self>) {
let Some(lhs) = &self.lhs else {
self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| {
- rhs_multibuffer.remove_excerpts_for_path(path, cx);
+ rhs_multibuffer.remove_excerpts(path, cx);
});
return;
};
@@ -1095,10 +1095,10 @@ impl SplittableEditor {
}
self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| {
- rhs_multibuffer.remove_excerpts_for_path(path.clone(), cx);
+ rhs_multibuffer.remove_excerpts(path.clone(), cx);
});
lhs.multibuffer.update(cx, |lhs_multibuffer, cx| {
- lhs_multibuffer.remove_excerpts_for_path(path, cx);
+ lhs_multibuffer.remove_excerpts(path, cx);
});
}
@@ -1142,7 +1142,7 @@ impl SplittableEditor {
rhs_multibuffer.excerpts_for_path(&path).collect();
let Some(excerpt_id) = rhs_excerpt_ids.first().copied() else {
lhs.multibuffer.update(cx, |lhs_multibuffer, lhs_cx| {
- lhs_multibuffer.remove_excerpts_for_path(path, lhs_cx);
+ lhs_multibuffer.remove_excerpts(path, lhs_cx);
});
continue;
};
@@ -51,9 +51,9 @@ use std::{
sync::{Arc, OnceLock},
time::Duration,
};
-use sum_tree::{Bias, Cursor, Dimension, Dimensions, SumTree, TreeMap};
+use sum_tree::{Bias, Cursor, Dimension, Dimensions, Item as _, SumTree, TreeMap};
use text::{
- BufferId, Edit, LineIndent, TextSummary,
+ AnchorRangeExt as _, BufferId, Edit, LineIndent, TextSummary,
subscription::{Subscription, Topic},
};
use theme::SyntaxTheme;
@@ -98,12 +98,12 @@ pub struct PathKeyIndex(u64);
pub struct ExcerptInfo {
path_key_index: PathKeyIndex,
buffer_id: BufferId,
- range: ExcerptRange<text::Anchor>,
+ range: Range<text::Anchor>,
}
impl ExcerptInfo {
pub fn end_anchor(&self) -> Anchor {
- Anchor::in_buffer(self.path_key_index, self.range.context.end)
+ Anchor::in_buffer(self.path_key_index, self.range.end)
}
}
@@ -1883,27 +1883,17 @@ impl MultiBuffer {
let snapshot = buffer.read(cx).snapshot();
let text_anchor = snapshot.anchor_after(&point);
for excerpt in self.excerpts_for_buffer(snapshot.remote_id(), cx) {
- if excerpt.range.contains(&text_anchor, &snapshot) {
- found = Some(Anchor::in_buffer(excerpt.path_key_index, text_anchor));
- break;
- }
- if excerpt
- .range
- .context
- .start
- .cmp(&text_anchor, &snapshot)
- .is_gt()
- {
+ if excerpt.range.start.cmp(&text_anchor, &snapshot).is_gt() {
found = Some(Anchor::in_buffer(
excerpt.path_key_index,
- excerpt.range.context.start,
+ excerpt.range.start,
));
break;
+ } else if excerpt.range.end.cmp(&text_anchor, &snapshot).is_ge() {
+ found = Some(Anchor::in_buffer(excerpt.path_key_index, text_anchor));
+ break;
}
- found = Some(Anchor::in_buffer(
- excerpt.path_key_index,
- excerpt.range.context.end,
- ));
+ found = Some(Anchor::in_buffer(excerpt.path_key_index, excerpt.range.end));
}
found
@@ -1918,7 +1908,7 @@ impl MultiBuffer {
) -> Option<Anchor> {
let snapshot = buffer.read(cx).snapshot();
for excerpt in self.excerpts_for_buffer(snapshot.remote_id(), cx) {
- if excerpt.range.contains(&anchor, &snapshot) {
+ if excerpt.range.contains_anchor(anchor, &snapshot) {
return Some(Anchor::in_buffer(excerpt.path_key_index, anchor));
}
}
@@ -2509,7 +2499,6 @@ impl MultiBuffer {
return snapshot;
}
let edits = Self::sync_from_buffer_changes(snapshot, &self.buffers, &self.diffs, cx);
- dbg!(&edits);
if !edits.is_empty() {
self.subscriptions.publish(edits);
@@ -2588,10 +2577,6 @@ impl MultiBuffer {
let buffer_edited =
current_version.changed_since(last_snapshot.buffer_snapshot.version());
- dbg!(
- ¤t_version,
- last_snapshot.buffer_snapshot.version().clone()
- );
let buffer_non_text_state_updated = non_text_state_update_count
> last_snapshot.buffer_snapshot.non_text_state_update_count();
if buffer_edited || buffer_non_text_state_updated {
@@ -2622,15 +2607,14 @@ impl MultiBuffer {
}
paths_to_edit.sort_unstable_by_key(|(path, _, _)| path.clone());
+ dbg!(&paths_to_edit);
let mut edits = Vec::new();
let mut new_excerpts = SumTree::default();
let mut cursor = excerpts.cursor::<ExcerptSummary>(());
for (path, buffer, prev_version) in paths_to_edit {
- dbg!(&prev_version, buffer.read(cx).version());
new_excerpts.append(cursor.slice(&path, Bias::Left), ());
- let old_excerpt = cursor.item().unwrap();
let buffer = buffer.read(cx);
let buffer_id = buffer.remote_id();
@@ -2642,42 +2626,44 @@ impl MultiBuffer {
},
);
- let new_excerpt = if let Some(prev_version) = prev_version {
- edits.extend(
- buffer
- .edits_since_in_range::<usize>(
- &prev_version,
- dbg!(old_excerpt.range.context.clone()),
- )
- .map(|edit| {
- dbg!(&edit);
- let excerpt_old_start = cursor.start().len();
- let excerpt_new_start =
- ExcerptDimension(new_excerpts.summary().text.len);
- let old_start = excerpt_old_start + edit.old.start;
- let old_end = excerpt_old_start + edit.old.end;
- let new_start = excerpt_new_start + edit.new.start;
- let new_end = excerpt_new_start + edit.new.end;
- Edit {
- old: old_start..old_end,
- new: new_start..new_end,
- }
- }),
- );
+ if let Some(prev_version) = &prev_version {
+ while let Some(old_excerpt) = cursor.item()
+ && &old_excerpt.path_key == &path
+ {
+ edits.extend(
+ buffer
+ .edits_since_in_range::<usize>(
+ prev_version,
+ old_excerpt.range.context.clone(),
+ )
+ .map(|edit| {
+ let excerpt_old_start = cursor.start().len();
+ let excerpt_new_start =
+ ExcerptDimension(new_excerpts.summary().text.len);
+ let old_start = excerpt_old_start + edit.old.start;
+ let old_end = excerpt_old_start + edit.old.end;
+ let new_start = excerpt_new_start + edit.new.start;
+ let new_end = excerpt_new_start + edit.new.end;
+ Edit {
+ old: old_start..old_end,
+ new: new_start..new_end,
+ }
+ }),
+ );
- Excerpt::new(
- path,
- old_excerpt.path_key_index,
- &buffer.snapshot(),
- old_excerpt.range.clone(),
- old_excerpt.has_trailing_newline,
- )
+ let excerpt = Excerpt::new(
+ old_excerpt.path_key.clone(),
+ old_excerpt.path_key_index,
+ &buffer.snapshot(),
+ old_excerpt.range.clone(),
+ old_excerpt.has_trailing_newline,
+ );
+ new_excerpts.push(excerpt, ());
+ cursor.next();
+ }
} else {
- old_excerpt.clone()
+ new_excerpts.append(cursor.slice(&path, Bias::Right), ());
};
-
- new_excerpts.push(new_excerpt, ());
- cursor.next();
}
new_excerpts.append(cursor.suffix(), ());
@@ -2692,7 +2678,6 @@ impl MultiBuffer {
excerpt_edits: Vec<text::Edit<ExcerptOffset>>,
change_kind: DiffChangeKind,
) -> Vec<Edit<MultiBufferOffset>> {
- dbg!(&excerpt_edits);
if excerpt_edits.is_empty() {
return vec![];
}
@@ -3336,7 +3321,7 @@ impl MultiBuffer {
.path_key
.clone();
log::info!("Removing excerpts {:?}", path_key);
- self.remove_excerpts_for_path(path_key, cx);
+ self.remove_excerpts(path_key, cx);
}
}
}
@@ -3665,72 +3650,35 @@ impl MultiBufferSnapshot {
result
}
- pub fn ranges_to_buffer_ranges<T: ToOffset>(
- &self,
- ranges: impl Iterator<Item = Range<T>>,
- ) -> impl Iterator<Item = (&BufferSnapshot, Range<BufferOffset>)> {
- ranges.flat_map(|range| {
- self.range_to_buffer_ranges((Bound::Included(range.start), Bound::Included(range.end)))
- .into_iter()
- })
- }
-
// todo!() can we make this not RangeBounds
- pub fn range_to_buffer_ranges<R, T>(
+ pub fn range_to_buffer_ranges<T: ToOffset>(
&self,
- range: R,
- ) -> Vec<(&BufferSnapshot, Range<BufferOffset>)>
- where
- R: RangeBounds<T>,
- T: ToOffset,
- {
+ range: Range<T>,
+ ) -> Vec<(&BufferSnapshot, Range<BufferOffset>)> {
self.range_to_buffer_ranges_with_context(range)
.into_iter()
.map(|(buffer, range, _context)| (buffer, range))
.collect()
}
- pub fn range_to_buffer_ranges_with_context<R, T>(
+ pub fn range_to_buffer_ranges_with_context<T: ToOffset>(
&self,
- range: R,
- ) -> Vec<(&BufferSnapshot, Range<BufferOffset>, Range<text::Anchor>)>
- where
- R: RangeBounds<T>,
- T: ToOffset,
- {
- let start = match range.start_bound() {
- Bound::Included(start) => start.to_offset(self),
- Bound::Excluded(_) => panic!("excluded start bound not supported"),
- Bound::Unbounded => MultiBufferOffset::ZERO,
- };
- let end_bound = match range.end_bound() {
- Bound::Included(end) => Bound::Included(end.to_offset(self)),
- Bound::Excluded(end) => Bound::Excluded(end.to_offset(self)),
- Bound::Unbounded => Bound::Unbounded,
- };
- let bounds = (Bound::Included(start), end_bound);
-
+ range: Range<T>,
+ ) -> Vec<(&BufferSnapshot, Range<BufferOffset>, Range<text::Anchor>)> {
let mut cursor = self.cursor::<MultiBufferOffset, BufferOffset>();
+ let start = range.start.to_offset(self);
+ let end = range.end.to_offset(self);
cursor.seek(&start);
let mut result: Vec<(&BufferSnapshot, Range<BufferOffset>, Range<text::Anchor>)> =
Vec::new();
- let mut last_excerpt = None;
while let Some(region) = cursor.region() {
- let dominated_by_end_bound = match end_bound {
- Bound::Included(end) => region.range.start > end,
- Bound::Excluded(end) => region.range.start >= end,
- Bound::Unbounded => false,
- };
- if dominated_by_end_bound {
+ if region.range.start >= end {
break;
}
if region.is_main_buffer {
let start_overshoot = start.saturating_sub(region.range.start);
- let end_offset = match end_bound {
- Bound::Included(end) | Bound::Excluded(end) => end,
- Bound::Unbounded => region.range.end,
- };
+ let end_offset = end;
let end_overshoot = end_offset.saturating_sub(region.range.start);
let start = region
.buffer_range
@@ -3741,35 +3689,34 @@ impl MultiBufferSnapshot {
.end
.min(region.buffer_range.start + end_overshoot);
let context = region.excerpt.range.context.clone();
- if last_excerpt
- .as_ref()
- .is_some_and(|prev_excerpt| prev_excerpt == ®ion.excerpt.info())
- && let Some(prev) = result
- .last_mut()
- .filter(|(_, prev_range, _)| prev_range.end == start)
- {
+ if let Some(prev) = result.last_mut().filter(|(prev_buffer, prev_range, _)| {
+ prev_buffer.remote_id() == region.buffer.remote_id() && prev_range.end == start
+ }) {
prev.1.end = end;
} else {
result.push((region.buffer, start..end, context));
- // todo!() is there a better way to do this?
- last_excerpt = Some(region.excerpt.info())
}
}
cursor.next();
}
- if let Some(excerpt) = cursor.excerpt() {
- let dominated_by_prev_excerpt =
- last_excerpt.is_some_and(|last_excerpt| last_excerpt == excerpt.info());
- if !dominated_by_prev_excerpt && excerpt.text_summary.len == 0 {
- let excerpt_position = self.len();
- let buffer_snapshot = excerpt.buffer_snapshot(self);
- if bounds.contains(&excerpt_position) {
- let buffer_offset =
- BufferOffset(excerpt.range.context.start.to_offset(buffer_snapshot));
- let context = excerpt.range.context.clone();
- result.push((buffer_snapshot, buffer_offset..buffer_offset, context));
- }
+ // Handle empty trailing excerpt, which doesn't have a region
+ if let Some(excerpt) = cursor.excerpt()
+ && excerpt.text_summary.len == 0
+ && end == self.len()
+ {
+ let buffer_snapshot = excerpt.buffer_snapshot(self);
+
+ let buffer_offset =
+ BufferOffset(excerpt.range.context.start.to_offset(buffer_snapshot));
+ let context = excerpt.range.context.clone();
+ if result
+ .last_mut()
+ .is_none_or(|(prev_buffer, prev_range, _)| {
+ prev_buffer.remote_id() != excerpt.buffer_id || prev_range.end != buffer_offset
+ })
+ {
+ result.push((buffer_snapshot, buffer_offset..buffer_offset, context));
}
}
@@ -4231,7 +4178,6 @@ impl MultiBufferSnapshot {
}
pub fn row_infos(&self, start_row: MultiBufferRow) -> MultiBufferRows<'_> {
- dbg!(self.diff_transforms.is_empty());
let mut cursor = self.cursor::<Point, Point>();
cursor.seek(&Point::new(start_row.0, 0));
let mut result = MultiBufferRows {
@@ -5073,7 +5019,6 @@ impl MultiBufferSnapshot {
let mut summaries = Vec::new();
while let Some(anchor) = anchors.peek() {
- dbg!(&anchor);
let target = anchor.seek_target(self);
let excerpt_anchor = match anchor {
Anchor::Min => {
@@ -6476,7 +6421,7 @@ impl MultiBufferSnapshot {
.to_multi_buffer_debug_ranges(self)
.into_iter()
.flat_map(|range| {
- self.range_to_buffer_ranges(range.start..=range.end)
+ self.range_to_buffer_ranges(range)
.into_iter()
.map(|(buffer, range)| {
buffer.anchor_after(range.start)..buffer.anchor_before(range.end)
@@ -6653,8 +6598,7 @@ where
}
self.excerpts.seek(&excerpt_position, Bias::Right);
- if self.excerpts.item().is_none() && dbg!(excerpt_position) == *self.excerpts.start() {
- dbg!("NONE");
+ if self.excerpts.item().is_none() && excerpt_position == *self.excerpts.start() {
self.excerpts.prev();
}
}
@@ -6823,7 +6767,6 @@ where
fn build_region(&self) -> Option<MultiBufferRegion<'a, MBD, BD>> {
let excerpt = self.excerpts.item()?;
- dbg!("GOT EXCERPT");
match self.diff_transforms.item()? {
DiffTransform::DeletedHunk {
buffer_id,
@@ -6956,12 +6899,11 @@ impl Excerpt {
range: ExcerptRange<text::Anchor>,
has_trailing_newline: bool,
) -> Self {
- dbg!(&path_key, &range, has_trailing_newline);
Excerpt {
path_key,
path_key_index,
buffer_id: buffer_snapshot.remote_id(),
- max_buffer_row: range.context.end.to_point(&buffer_snapshot).row,
+ max_buffer_row: dbg!(range.context.end.to_point(&buffer_snapshot).row),
text_summary: buffer_snapshot.text_summary_for_range::<TextSummary, _>(
range.context.to_offset(&buffer_snapshot),
),
@@ -6988,7 +6930,7 @@ impl Excerpt {
ExcerptInfo {
path_key_index: self.path_key_index,
buffer_id: self.buffer_id,
- range: self.range.clone(),
+ range: self.range.context.clone(),
}
}
@@ -7615,13 +7557,11 @@ impl Iterator for MultiBufferRows<'_> {
}
let mut region = self.cursor.region()?.clone();
- dbg!("REGION");
while self.point >= region.range.end {
self.cursor.next();
if let Some(next_region) = self.cursor.region() {
region = next_region.clone();
- } else if dbg!(self.point) == dbg!(self.cursor.diff_transforms.end().output_dimension.0)
- {
+ } else if self.point == self.cursor.diff_transforms.end().output_dimension.0 {
let multibuffer_row = MultiBufferRow(self.point.row);
let last_excerpt = self
.cursor
@@ -319,7 +319,7 @@ fn test_excerpt_boundaries_and_clipping(cx: &mut App) {
);
let snapshot = multibuffer.update(cx, |multibuffer, cx| {
- multibuffer.remove_excerpts_for_path(PathKey::sorted(1), cx);
+ multibuffer.remove_excerpts(PathKey::sorted(1), cx);
multibuffer.snapshot(cx)
});
@@ -875,11 +875,11 @@ fn test_expand_excerpts(cx: &mut App) {
multibuffer.update(cx, |multibuffer, cx| {
let line_zero = multibuffer.snapshot(cx).anchor_before(Point::new(0, 0));
- multibuffer.expand_excerpts_with_paths(
+ multibuffer.expand_excerpts(
multibuffer
.snapshot(cx)
.excerpts()
- .map(|(_, info)| Anchor::in_buffer(info.path_key_index, info.range.context.end)),
+ .map(|(_, info)| Anchor::in_buffer(info.path_key_index, info.range.end)),
1,
ExpandExcerptDirection::UpAndDown,
cx,
@@ -1109,7 +1109,6 @@ fn test_singleton_multibuffer_anchors(cx: &mut App) {
buffer.edit([(0..0, "X")], None, cx);
buffer.edit([(5..5, "Y")], None, cx);
});
- dbg!("-------");
let new_snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(old_snapshot.text(), "abcd");
@@ -2294,7 +2293,7 @@ impl ReferenceExcerpt {
ExcerptInfo {
path_key_index: self.path_key_index,
buffer_id: self.buffer.read(cx).remote_id(),
- range: ExcerptRange::new(self.range.clone()),
+ range: self.range.clone(),
}
}
}
@@ -2345,7 +2344,8 @@ impl ReferenceMultibuffer {
path_key: path_key.clone(),
path_key_index,
buffer: buffer.clone(),
- range: buffer_snapshot.anchor_range_around(range.context),
+ range: buffer_snapshot.anchor_before(range.context.start)
+ ..buffer_snapshot.anchor_after(range.context.end),
}),
);
}
@@ -2669,7 +2669,7 @@ impl ReferenceMultibuffer {
expand_info: expand_direction.zip(region.excerpt_info.clone()).map(
|(direction, excerpt_info)| ExpandInfo {
direction,
- excerpt_range: excerpt_info.range.context,
+ excerpt_range: excerpt_info.range,
},
),
}
@@ -2787,8 +2787,8 @@ async fn test_random_set_ranges(cx: &mut TestAppContext, mut rng: StdRng) {
let mut seen_ranges = Vec::default();
for (buf, info) in snapshot.excerpts() {
- let start = info.range.context.start.to_point(buf);
- let end = info.range.context.end.to_point(buf);
+ let start = info.range.start.to_point(buf);
+ let end = info.range.end.to_point(buf);
seen_ranges.push(start..end);
if let Some(last_end) = last_end.take() {
@@ -2865,10 +2865,10 @@ async fn test_random_multibuffer(cx: &mut TestAppContext, mut rng: StdRng) {
})
.collect::<Vec<_>>();
log::info!("Expanding excerpts {excerpt_ixs:?} by {line_count} lines");
- multibuffer.expand_excerpts_with_paths(
- excerpts.iter().map(|info| {
- Anchor::in_buffer(info.path_key_index, info.range.context.end)
- }),
+ multibuffer.expand_excerpts(
+ excerpts
+ .iter()
+ .map(|info| Anchor::in_buffer(info.path_key_index, info.range.end)),
line_count,
ExpandExcerptDirection::UpAndDown,
cx,
@@ -3160,6 +3160,17 @@ fn check_multibuffer(
);
log::info!("Multibuffer content:\n{}", actual_diff);
+ dbg!(
+ snapshot
+ .excerpts()
+ .map(|(buffer_snapshot, excerpt)| {
+ (
+ buffer_snapshot.remote_id(),
+ excerpt.range.to_point(&buffer_snapshot),
+ )
+ })
+ .collect::<Vec<_>>()
+ );
assert_eq!(
actual_row_infos.len(),
@@ -3182,6 +3193,27 @@ fn check_multibuffer(
start_row
);
}
+ // dbg!(&expected_row_infos);
+
+ // dbg!(
+ // snapshot
+ // .excerpts()
+ // .map(|(buffer_snapshot, excerpt)| {
+ // (
+ // buffer_snapshot.remote_id(),
+ // excerpt.range.to_point(&buffer_snapshot),
+ // )
+ // })
+ // .collect::<Vec<_>>()
+ // );
+ // dbg!(&expected_row_infos);
+ // dbg!(
+ // reference
+ // .excerpts
+ // .iter()
+ // .map(|excerpt| { excerpt.range.to_point(&excerpt.buffer.read(cx).snapshot()) })
+ // .collect::<Vec<_>>()
+ // );
assert_eq!(
snapshot.widest_line_number(),
@@ -3623,7 +3655,6 @@ async fn test_summaries_for_anchors(cx: &mut TestAppContext) {
});
cx.run_until_parked();
- dbg!("BEFORE");
let multibuffer = cx.new(|cx| {
let mut multibuffer = MultiBuffer::new(Capability::ReadWrite);
multibuffer.set_all_diff_hunks_expanded(cx);
@@ -3646,12 +3677,10 @@ async fn test_summaries_for_anchors(cx: &mut TestAppContext) {
multibuffer
});
- dbg!("BEFORE");
let (mut snapshot, mut subscription) = multibuffer.update(cx, |multibuffer, cx| {
(multibuffer.snapshot(cx), multibuffer.subscribe())
});
- dbg!("BEFORE");
assert_new_snapshot(
&multibuffer,
&mut snapshot,
@@ -3668,7 +3697,6 @@ async fn test_summaries_for_anchors(cx: &mut TestAppContext) {
),
);
- dbg!("BEFORE");
let anchor_1 = multibuffer.read_with(cx, |multibuffer, cx| {
multibuffer
.buffer_anchor_to_anchor(
@@ -3678,11 +3706,9 @@ async fn test_summaries_for_anchors(cx: &mut TestAppContext) {
)
.unwrap()
});
- dbg!("BEFORE");
let point_1 = snapshot.summaries_for_anchors::<Point, _>([&anchor_1])[0];
assert_eq!(point_1, Point::new(0, 0));
- dbg!("BEFORE");
let anchor_2 = multibuffer.read_with(cx, |multibuffer, cx| {
multibuffer
.buffer_anchor_to_anchor(
@@ -3692,9 +3718,7 @@ async fn test_summaries_for_anchors(cx: &mut TestAppContext) {
)
.unwrap()
});
- dbg!("BEFORE");
let point_2 = snapshot.summaries_for_anchors::<Point, _>([&anchor_2])[0];
- dbg!("AFTER");
assert_eq!(point_2, Point::new(3, 0));
}
@@ -4181,7 +4205,7 @@ fn assert_excerpts_match(
multibuffer.read_with(cx, |multibuffer, cx| {
for (buffer, info) in multibuffer.snapshot(cx).excerpts() {
output.push_str("-----\n");
- output.extend(buffer.text_for_range(info.range.context));
+ output.extend(buffer.text_for_range(info.range));
if !output.ends_with('\n') {
output.push('\n');
}
@@ -4974,9 +4998,7 @@ fn test_excerpts_containment_functions(cx: &mut App) {
}
#[gpui::test]
-fn test_range_to_buffer_ranges_with_range_bounds(cx: &mut App) {
- use std::ops::Bound;
-
+fn test_range_to_buffer_ranges(cx: &mut App) {
let buffer_1 = cx.new(|cx| Buffer::local("aaa\nbbb", cx));
let buffer_2 = cx.new(|cx| Buffer::local("ccc", cx));
@@ -5011,52 +5033,6 @@ fn test_range_to_buffer_ranges_with_range_bounds(cx: &mut App) {
"Half-open range ending at excerpt start should EXCLUDE that excerpt"
);
assert_eq!(ranges_half_open[0].1, BufferOffset(0)..BufferOffset(7));
-
- let ranges_inclusive = snapshot.range_to_buffer_ranges(Point::zero()..=excerpt_2_start);
- assert_eq!(
- ranges_inclusive.len(),
- 2,
- "Inclusive range ending at excerpt start should INCLUDE that excerpt"
- );
- assert_eq!(ranges_half_open[0].1, BufferOffset(0)..BufferOffset(7));
- assert_eq!(
- ranges_half_open[0].0.remote_id(),
- buffer_1.read(cx).remote_id()
- );
- assert_eq!(ranges_half_open[1].1, BufferOffset(0)..BufferOffset(0));
- assert_eq!(
- ranges_half_open[1].0.remote_id(),
- buffer_2.read(cx).remote_id()
- );
-
- let ranges_unbounded =
- snapshot.range_to_buffer_ranges((Bound::Included(Point::zero()), Bound::Unbounded));
- assert_eq!(
- ranges_unbounded.len(),
- 2,
- "Unbounded end should include all excerpts"
- );
- assert_eq!(ranges_half_open[0].1, BufferOffset(0)..BufferOffset(7));
- assert_eq!(
- ranges_half_open[0].0.remote_id(),
- buffer_1.read(cx).remote_id()
- );
- assert_eq!(ranges_half_open[1].1, BufferOffset(0)..BufferOffset(3));
- assert_eq!(
- ranges_half_open[1].0.remote_id(),
- buffer_2.read(cx).remote_id()
- );
-
- let ranges_excluded_end = snapshot.range_to_buffer_ranges((
- Bound::Included(Point::zero()),
- Bound::Excluded(excerpt_2_start),
- ));
- assert_eq!(
- ranges_excluded_end.len(),
- 1,
- "Excluded end bound should exclude excerpt starting at that point"
- );
- assert_eq!(ranges_half_open[0].1, BufferOffset(0)..BufferOffset(7));
assert_eq!(
ranges_half_open[0].0.remote_id(),
buffer_1.read(cx).remote_id()
@@ -5096,36 +5072,10 @@ fn test_range_to_buffer_ranges_with_range_bounds(cx: &mut App) {
snapshot_trailing.range_to_buffer_ranges_with_context(Point::zero()..max_point);
assert_eq!(
ranges_half_open_max.len(),
- 1,
- "Half-open range to max_point should EXCLUDE trailing empty excerpt at max_point"
- );
- assert_eq!(ranges_half_open_max[0].2, te_excerpt_1_info.range.context);
-
- let ranges_inclusive_max =
- snapshot_trailing.range_to_buffer_ranges_with_context(Point::zero()..=max_point);
- assert_eq!(
- ranges_inclusive_max.len(),
2,
- "Inclusive range to max_point should INCLUDE trailing empty excerpt"
- );
- assert_eq!(ranges_inclusive_max[0].2, te_excerpt_1_info.range.context);
- assert_eq!(ranges_inclusive_max[1].2, te_excerpt_2_info.range.context);
-
- let ranges_unbounded_trailing = snapshot_trailing
- .range_to_buffer_ranges_with_context((Bound::Included(Point::zero()), Bound::Unbounded));
- assert_eq!(
- ranges_unbounded_trailing.len(),
- 2,
- "Unbounded end should include trailing empty excerpt"
- );
- assert_eq!(
- ranges_unbounded_trailing[0].2,
- te_excerpt_1_info.range.context
- );
- assert_eq!(
- ranges_unbounded_trailing[1].2,
- te_excerpt_2_info.range.context
+ "Should include trailing empty excerpts"
);
+ assert_eq!(ranges_half_open_max[0].2, te_excerpt_1_info.range);
}
#[gpui::test]
@@ -5177,8 +5127,8 @@ fn test_cannot_seek_backward_after_excerpt_replacement(cx: &mut TestAppContext)
let e_b2_info = excerpt_infos[1].clone();
let e_b3_info = excerpt_infos[2].clone();
- let anchor_b2 = Anchor::in_buffer(e_b2_info.path_key_index, e_b2_info.range.context.start);
- let anchor_b3 = Anchor::in_buffer(e_b3_info.path_key_index, e_b3_info.range.context.start);
+ let anchor_b2 = Anchor::in_buffer(e_b2_info.path_key_index, e_b2_info.range.start);
+ let anchor_b3 = Anchor::in_buffer(e_b3_info.path_key_index, e_b3_info.range.start);
(anchor_b2, anchor_b3)
});
@@ -69,7 +69,7 @@ impl MultiBuffer {
let excerpt = snapshot.excerpts_for_path(path).next()?;
Some(Anchor::in_buffer(
excerpt.path_key_index,
- excerpt.range.context.start,
+ excerpt.range.start,
))
}
@@ -178,7 +178,7 @@ impl MultiBuffer {
}
}
- pub(super) fn expand_excerpts_with_paths(
+ pub fn expand_excerpts(
&mut self,
anchors: impl IntoIterator<Item = Anchor>,
line_count: u32,
@@ -199,6 +199,11 @@ impl MultiBuffer {
.path_keys_by_index
.get(&path_index)
.expect("anchor from wrong multibuffer");
+
+ let mut excerpt_anchors = excerpt_anchors.peekable();
+ let mut ranges = Vec::new();
+
+ cursor.seek_forward(path, Bias::Left);
let Some((buffer, buffer_snapshot)) = cursor
.item()
.map(|excerpt| (excerpt.buffer(&self), excerpt.buffer_snapshot(&snapshot)))
@@ -206,10 +211,6 @@ impl MultiBuffer {
continue;
};
- let mut excerpt_anchors = excerpt_anchors.peekable();
- let mut ranges = Vec::new();
-
- cursor.seek_forward(path, Bias::Left);
while let Some(excerpt) = cursor.item()
&& &excerpt.path_key == path
{
@@ -324,11 +325,11 @@ impl MultiBuffer {
.path_for_buffer(buffer_snapshot.remote_id())
&& old_path_key != &path_key
{
- self.remove_excerpts_for_path(old_path_key.clone(), cx);
+ self.remove_excerpts(old_path_key.clone(), cx);
}
if to_insert.len() == 0 {
- self.remove_excerpts_for_path(path_key.clone(), cx);
+ self.remove_excerpts(path_key.clone(), cx);
return (false, path_key_index);
}
@@ -406,7 +407,10 @@ impl MultiBuffer {
path_key_index,
&buffer_snapshot,
next_excerpt.clone(),
- to_insert.peek().is_some() || cursor.item().is_some(),
+ to_insert.peek().is_some()
+ || cursor
+ .item()
+ .is_some_and(|item| item.path_key_index != path_key_index),
),
(),
);
@@ -437,7 +441,10 @@ impl MultiBuffer {
path_key_index,
&buffer_snapshot,
next_excerpt.clone(),
- to_insert.peek().is_some() || cursor.item().is_some(),
+ to_insert.peek().is_some()
+ || cursor
+ .item()
+ .is_some_and(|item| item.path_key_index != path_key_index),
),
(),
);
@@ -481,7 +488,7 @@ impl MultiBuffer {
let edits = Self::sync_diff_transforms(
&mut snapshot,
- dbg!(patch.into_inner()),
+ patch.into_inner(),
DiffChangeKind::BufferEdited,
);
if !edits.is_empty() {
@@ -506,10 +513,10 @@ impl MultiBuffer {
let Some(path) = snapshot.path_for_buffer(buffer).cloned() else {
return;
};
- self.remove_excerpts_for_path(path, cx);
+ self.remove_excerpts(path, cx);
}
- pub fn remove_excerpts_for_path(&mut self, path: PathKey, cx: &mut Context<Self>) {
+ pub fn remove_excerpts(&mut self, path: PathKey, cx: &mut Context<Self>) {
assert_eq!(self.history.transaction_depth(), 0);
self.sync_mut(cx);
@@ -216,6 +216,7 @@ where
pub trait AnchorRangeExt {
fn cmp(&self, b: &Range<Anchor>, buffer: &BufferSnapshot) -> Ordering;
fn overlaps(&self, b: &Range<Anchor>, buffer: &BufferSnapshot) -> bool;
+ fn contains_anchor(&self, b: Anchor, buffer: &BufferSnapshot) -> bool;
}
impl AnchorRangeExt for Range<Anchor> {
@@ -229,4 +230,8 @@ impl AnchorRangeExt for Range<Anchor> {
fn overlaps(&self, other: &Range<Anchor>, buffer: &BufferSnapshot) -> bool {
self.start.cmp(&other.end, buffer).is_lt() && other.start.cmp(&self.end, buffer).is_lt()
}
+
+ fn contains_anchor(&self, other: Anchor, buffer: &BufferSnapshot) -> bool {
+ self.start.cmp(&other, buffer).is_le() && self.end.cmp(&other, buffer).is_ge()
+ }
}