Compare commits

...

1 Commits

Author SHA1 Message Date
Lukas Wirth
d244e97c7b multi_buffer: Cleanup min/max excerpt id clipping 2025-10-03 12:54:46 +02:00

View File

@@ -1306,8 +1306,10 @@ impl MultiBuffer {
let snapshot = self.read(cx);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
for selection in selections {
let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id);
let end_locator = snapshot.excerpt_locator_for_id(selection.end.excerpt_id);
let start_id = snapshot.clip_excerpt_id(selection.start.excerpt_id);
let start_locator = snapshot.excerpt_locator_for_id(start_id);
let end_id = snapshot.clip_excerpt_id(selection.end.excerpt_id);
let end_locator = snapshot.excerpt_locator_for_id(end_id);
cursor.seek(&Some(start_locator), Bias::Left);
while let Some(excerpt) = cursor.item()
@@ -1315,10 +1317,10 @@ impl MultiBuffer {
{
let mut start = excerpt.range.context.start;
let mut end = excerpt.range.context.end;
if excerpt.id == selection.start.excerpt_id {
if excerpt.id == start_id {
start = selection.start.text_anchor;
}
if excerpt.id == selection.end.excerpt_id {
if excerpt.id == end_id {
end = selection.end.text_anchor;
}
selections_by_buffer
@@ -1501,13 +1503,14 @@ impl MultiBuffer {
direction: ExpandExcerptDirection,
cx: &mut Context<Self>,
) {
let snapshot = self.snapshot(cx);
let grouped = ids
.into_iter()
.map(|id| snapshot.clip_excerpt_id(id))
.chunk_by(|id| self.paths_by_excerpt.get(id).cloned())
.into_iter()
.flat_map(|(k, v)| Some((k?, v.into_iter().collect::<Vec<_>>())))
.collect::<Vec<_>>();
let snapshot = self.snapshot(cx);
for (path, ids) in grouped.into_iter() {
let Some(excerpt_ids) = self.excerpts_by_path.get(&path) else {
@@ -1951,7 +1954,7 @@ impl MultiBuffer {
});
let mut snapshot = self.snapshot.borrow_mut();
let prev_excerpt_id = snapshot.clip_excerpt_id(prev_excerpt_id);
let mut prev_locator = snapshot.excerpt_locator_for_id(prev_excerpt_id).clone();
let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
@@ -4911,16 +4914,14 @@ impl MultiBufferSnapshot {
let mut cursor = self
.excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
let locator = self.excerpt_locator_for_id(anchor.excerpt_id);
let excerpt_id = self.clip_excerpt_id(anchor.excerpt_id);
let locator = self.excerpt_locator_for_id(excerpt_id);
cursor.seek(&Some(locator), Bias::Left);
if cursor.item().is_none() && anchor.excerpt_id == ExcerptId::max() {
cursor.prev();
}
let mut position = cursor.start().1;
if let Some(excerpt) = cursor.item()
&& (excerpt.id == anchor.excerpt_id || anchor.excerpt_id == ExcerptId::max())
&& excerpt.id == excerpt_id
{
let excerpt_buffer_start = excerpt
.buffer
@@ -4958,21 +4959,19 @@ impl MultiBufferSnapshot {
let mut summaries = Vec::new();
while let Some(anchor) = anchors.peek() {
let excerpt_id = self.latest_excerpt_id(anchor.excerpt_id);
let excerpt_id = self.clip_excerpt_id(anchor.excerpt_id);
let excerpt_id = self.latest_excerpt_id(excerpt_id);
let excerpt_anchors = anchors.peeking_take_while(|anchor| {
self.latest_excerpt_id(anchor.excerpt_id) == excerpt_id
self.latest_excerpt_id(self.clip_excerpt_id(anchor.excerpt_id)) == excerpt_id
});
let locator = self.excerpt_locator_for_id(excerpt_id);
cursor.seek_forward(locator, Bias::Left);
if cursor.item().is_none() && excerpt_id == ExcerptId::max() {
cursor.prev();
}
let excerpt_start_position = D::from_text_summary(&cursor.start().text);
if let Some(excerpt) = cursor.item() {
if excerpt.id != excerpt_id && excerpt_id != ExcerptId::max() {
if excerpt.id != excerpt_id {
let position = self.resolve_summary_for_anchor(
&Anchor::min(),
excerpt_start_position,
@@ -6197,14 +6196,9 @@ impl MultiBufferSnapshot {
let mut cursor = self
.excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptDimension<Point>>>(());
let excerpt_id = self.clip_excerpt_id(excerpt_id);
let locator = self.excerpt_locator_for_id(excerpt_id);
let mut sought_exact = cursor.seek(&Some(locator), Bias::Left);
if cursor.item().is_none() && excerpt_id == ExcerptId::max() {
sought_exact = true;
cursor.prev();
} else if excerpt_id == ExcerptId::min() {
sought_exact = true;
}
let sought_exact = cursor.seek(&Some(locator), Bias::Left);
if sought_exact {
let start = cursor.start().1.clone();
let end = cursor.end().1;
@@ -6225,17 +6219,10 @@ impl MultiBufferSnapshot {
fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
let excerpt_id = self.clip_excerpt_id(excerpt_id);
let locator = self.excerpt_locator_for_id(excerpt_id);
cursor.seek(&Some(locator), Bias::Left);
if let Some(excerpt) = cursor.item()
&& excerpt.id == excerpt_id
{
return Some(excerpt);
} else if cursor.item().is_none() && excerpt_id == ExcerptId::max() {
cursor.prev();
return cursor.item();
}
None
cursor.item().filter(|excerpt| excerpt.id == excerpt_id)
}
/// Returns the excerpt containing range and its offset start within the multibuffer or none if `range` spans multiple excerpts
@@ -6445,6 +6432,21 @@ impl MultiBufferSnapshot {
prev_transform = Some(item);
}
}
fn clip_excerpt_id(&self, excerpt_id: ExcerptId) -> ExcerptId {
// todo, are first and last always valid?
if excerpt_id == ExcerptId::min() {
self.excerpts
.first()
.map_or(excerpt_id, |excerpt| excerpt.id)
} else if excerpt_id == ExcerptId::max() {
self.excerpts
.last()
.map_or(excerpt_id, |excerpt| excerpt.id)
} else {
excerpt_id
}
}
}
impl<'a, D> MultiBufferCursor<'a, D>