From d244e97c7bca77edb02bfdda162391c1ee464a63 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 3 Oct 2025 12:04:35 +0200 Subject: [PATCH] multi_buffer: Cleanup min/max excerpt id clipping --- crates/multi_buffer/src/multi_buffer.rs | 68 +++++++++++++------------ 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index aa7bbf3540353220c9ed34434db9d03d3d953f7f..197675aad46cd9fd8d0175c94cad240576a09df2 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -1306,8 +1306,10 @@ impl MultiBuffer { let snapshot = self.read(cx); let mut cursor = snapshot.excerpts.cursor::>(()); 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, ) { + 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::>()))) .collect::>(); - 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::>(()); @@ -4911,16 +4914,14 @@ impl MultiBufferSnapshot { let mut cursor = self .excerpts .cursor::, 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::, ExcerptDimension>>(()); + 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::>(()); + 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>