diff --git a/crates/agent_ui/src/mention_set.rs b/crates/agent_ui/src/mention_set.rs index 3b2a65372de957ec57577108e4acea1ab2e9944e..72b43f5391db57b784ac8be0aefcac709477513e 100644 --- a/crates/agent_ui/src/mention_set.rs +++ b/crates/agent_ui/src/mention_set.rs @@ -670,7 +670,7 @@ pub(crate) async fn insert_images_as_context( let text_anchor = cursor_anchor.bias_left(&buffer_snapshot); let multibuffer_anchor = snapshot .buffer_snapshot() - .anchor_in_excerpt(excerpt_id, text_anchor); + .anchor_in_buffer(excerpt_id, text_anchor); editor.insert(&format!("{replacement_text} "), window, cx); (excerpt_id, text_anchor, multibuffer_anchor) }) @@ -816,7 +816,7 @@ pub(crate) fn insert_crease_for_mention( let crease_id = editor.update(cx, |editor, cx| { let snapshot = editor.buffer().read(cx).snapshot(cx); - let start = snapshot.anchor_in_excerpt(excerpt_id, anchor)?; + let start = snapshot.anchor_in_buffer(excerpt_id, anchor)?; let start = start.bias_right(&snapshot); let end = snapshot.anchor_before(start.to_offset(&snapshot) + content_len); diff --git a/crates/agent_ui/src/text_thread_editor.rs b/crates/agent_ui/src/text_thread_editor.rs index cf6a13161f8f325ddd50e6990410dabe0ba26fed..356807fa8b66afe20c86368fbeedc90c223c27ab 100644 --- a/crates/agent_ui/src/text_thread_editor.rs +++ b/crates/agent_ui/src/text_thread_editor.rs @@ -1237,7 +1237,7 @@ impl TextThreadEditor { style: BlockStyle::Sticky, placement: BlockPlacement::Above( buffer - .anchor_in_excerpt(excerpt_id, message.anchor_range.start) + .anchor_in_buffer(excerpt_id, message.anchor_range.start) .unwrap(), ), priority: usize::MAX, @@ -2048,7 +2048,7 @@ impl TextThreadEditor { ) .filter_map(|(anchor, render_image)| { const MAX_HEIGHT_IN_LINES: u32 = 8; - let anchor = buffer.anchor_in_excerpt(excerpt_id, anchor).unwrap(); + let anchor = buffer.anchor_in_buffer(excerpt_id, anchor).unwrap(); let image = render_image; anchor.is_valid(&buffer).then(|| BlockProperties { placement: BlockPlacement::Above(anchor), diff --git a/crates/edit_prediction_ui/src/rate_prediction_modal.rs b/crates/edit_prediction_ui/src/rate_prediction_modal.rs index d07dbe9bad72c2252ee2e33c8a014778d1331e96..f0a8f942aee8c135dec87268b983aa1ee39b07db 100644 --- a/crates/edit_prediction_ui/src/rate_prediction_modal.rs +++ b/crates/edit_prediction_ui/src/rate_prediction_modal.rs @@ -378,7 +378,7 @@ impl RatePredictionsModal { let cursor_anchor = buffer_snapshot.anchor_after(cursor_offset); if let Some(anchor) = - multibuffer_snapshot.anchor_in_excerpt(excerpt_id, cursor_anchor) + multibuffer_snapshot.anchor_in_buffer(excerpt_id, cursor_anchor) { editor.splice_inlays( &[InlayId::EditPrediction(0)], diff --git a/crates/editor/src/bracket_colorization.rs b/crates/editor/src/bracket_colorization.rs index bf71d5c71c9580d04e0c61047215992c5cbd4a26..3ee2b1222b0f27ec08e27f303457b1b764e7fb6a 100644 --- a/crates/editor/src/bracket_colorization.rs +++ b/crates/editor/src/bracket_colorization.rs @@ -27,8 +27,9 @@ impl Editor { let anchors_in_multi_buffer = |current_excerpt: ExcerptId, text_anchors: [text::Anchor; 4]| -> Option<[Option<_>; 4]> { + // todo!() move filtering out. multi_buffer_snapshot - .anchors_in_excerpt(current_excerpt, text_anchors)? + .anchors_in_buffer(current_excerpt, text_anchors)? .collect_array() }; diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 494dc8c3ef2f6860a1ab642f4268f066c2b57c5c..9aefb6082935256622495e415c5b624c7b3dfad1 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8630,7 +8630,7 @@ impl Editor { } let cursor_position = predicted_cursor_position.and_then(|predicted| { - let anchor = multibuffer.anchor_in_excerpt(excerpt_id, predicted.anchor)?; + let anchor = multibuffer.anchor_in_buffer(excerpt_id, predicted.anchor)?; Some((anchor, predicted.offset)) }); @@ -11848,7 +11848,7 @@ impl Editor { if breakpoint_row == row { snapshot .buffer_snapshot() - .anchor_in_excerpt(enclosing_excerpt, bp.position) + .anchor_in_buffer(enclosing_excerpt, bp.position) .map(|position| (position, bp.bp.clone())) } else { None @@ -17114,7 +17114,7 @@ impl Editor { if snapshot.remote_id() == buffer_snapshot.remote_id() { display_snapshot .buffer_snapshot() - .anchor_in_excerpt(excerpt_id, location.target.range.start) + .anchor_in_buffer(excerpt_id, location.target.range.start) } else { None } @@ -22861,7 +22861,7 @@ impl Editor { continue; } let snapshot = self.buffer.read(cx).snapshot(cx); - let multibuffer_anchor = snapshot.anchor_in_excerpt(id, position)?; + let multibuffer_anchor = snapshot.anchor_in_buffer(id, position)?; handled = true; self.clear_row_highlights::(); diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index 01f67be06d5effed50a6a83a3574d3403dfa90f3..2a402c3727e25172380107eaf3e7c013ef99eba9 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -686,7 +686,7 @@ impl<'snap, 'a> MutableSelectionsCollection<'snap, 'a> { .excerpts() .find(|(_, buffer, _)| buffer.remote_id() == buffer_id) .and_then(|(excerpt_id, _, range)| { - buffer_snapshot.anchor_in_excerpt(excerpt_id, range.context.start) + buffer_snapshot.anchor_in_buffer(excerpt_id, range.context.start) }) .unwrap_or_else(|| self.snapshot.anchor_before(MultiBufferOffset(0))); self.collection.disjoint = Arc::from([Selection { diff --git a/crates/git_ui/src/conflict_view.rs b/crates/git_ui/src/conflict_view.rs index 16ea6f5c6cf037a495b2e6271544722b4fc03eeb..9fb677935a0ecc769f67f08520bc84d1e99b4a78 100644 --- a/crates/git_ui/src/conflict_view.rs +++ b/crates/git_ui/src/conflict_view.rs @@ -282,7 +282,7 @@ fn conflicts_updated( update_conflict_highlighting(editor, conflict, &snapshot, excerpt_id, cx); - let Some(anchor) = snapshot.anchor_in_excerpt(excerpt_id, conflict.range.start) else { + let Some(anchor) = snapshot.anchor_in_buffer(excerpt_id, conflict.range.start) else { continue; }; diff --git a/crates/language_tools/src/highlights_tree_view.rs b/crates/language_tools/src/highlights_tree_view.rs index 9796c1c07375956184bdd28fbd8f5bb52bff2a32..f43cffc8c3ce9062b5f3fc4d40fd64c64bb63f36 100644 --- a/crates/language_tools/src/highlights_tree_view.rs +++ b/crates/language_tools/src/highlights_tree_view.rs @@ -425,8 +425,8 @@ impl HighlightsTreeView { let start_anchor = buffer_snapshot.anchor_before(capture.node.start_byte()); let end_anchor = buffer_snapshot.anchor_after(capture.node.end_byte()); - let start = multi_buffer_snapshot.anchor_in_excerpt(excerpt_id, start_anchor); - let end = multi_buffer_snapshot.anchor_in_excerpt(excerpt_id, end_anchor); + let start = multi_buffer_snapshot.anchor_in_buffer(excerpt_id, start_anchor); + let end = multi_buffer_snapshot.anchor_in_buffer(excerpt_id, end_anchor); let (start, end) = match (start, end) { (Some(s), Some(e)) => (s, e), diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index cf9baed833b40754a5b00b04ebe329f8d5618587..4b049a48cdaf385872428f82950e5fa77b7b0c29 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -678,8 +678,9 @@ impl std::hash::Hash for DiffTransformHunkInfo { #[derive(Clone)] pub struct ExcerptBoundaryInfo { + // todo!() do we need the buffer? pub buffer: Arc, - pub buffer_id: BufferId, + path_key_index: PathKeyIndex, pub range: ExcerptRange, pub end_row: MultiBufferRow, } @@ -3856,7 +3857,7 @@ impl MultiBufferSnapshot { + AddAssign + Ord, { - let mut current_excerpt_metadata: Option<(Excerpt, I)> = None; + let mut current_excerpt_metadata: Option<(ExcerptAnchor, I)> = None; let mut cursor = self.cursor::(); // Find the excerpt and buffer offset where the given range ends. @@ -3871,7 +3872,7 @@ impl MultiBufferSnapshot { ::default() }; buffer_end = buffer_end + overshoot; - range_end = Some((region.excerpt, buffer_end)); + range_end = Some((region.excerpt.end_anchor(), buffer_end)); break; } cursor.next(); @@ -3900,7 +3901,7 @@ impl MultiBufferSnapshot { // If we have already retrieved metadata for this excerpt, continue to use it. let metadata_iter = if let Some((_, metadata)) = current_excerpt_metadata .as_mut() - .filter(|(excerpt_id, _)| *excerpt_id == excerpt.id) + .filter(|(excerpt_anchor, _)| excerpt_anchor == &excerpt.end_anchor()) { Some(metadata) } @@ -3925,13 +3926,16 @@ impl MultiBufferSnapshot { .end .summary::(&excerpt.buffer); if let Some((end_excerpt, end_buffer_offset)) = range_end - && excerpt == end_excerpt + && excerpt.end_anchor() == end_excerpt { buffer_end = buffer_end.min(end_buffer_offset); } - get_buffer_metadata(&excerpt.buffer, buffer_start..buffer_end) - .map(|iterator| &mut current_excerpt_metadata.insert((excerpt, iterator)).1) + get_buffer_metadata(&excerpt.buffer, buffer_start..buffer_end).map(|iterator| { + &mut current_excerpt_metadata + .insert((excerpt.end_anchor(), iterator)) + .1 + }) }; // Visit each metadata item. @@ -3996,7 +4000,7 @@ impl MultiBufferSnapshot { else { current_excerpt_metadata.take(); if let Some((end_excerpt, _)) = range_end - && excerpt == end_excerpt + && excerpt.end_anchor() == end_excerpt { return None; } @@ -4168,12 +4172,9 @@ impl MultiBufferSnapshot { self.singleton } - pub fn as_singleton(&self) -> Option<(ExcerptId, BufferId, &BufferSnapshot)> { + pub fn as_singleton(&self) -> Option<&BufferSnapshot> { if self.singleton { - self.excerpts - .iter() - .next() - .map(|e| (e.id, e.buffer_id, &*e.buffer)) + self.excerpts.iter().next().map(|e| (&*e.buffer)) } else { None } @@ -5208,92 +5209,23 @@ impl MultiBufferSnapshot { }) } - pub fn refresh_anchors<'a, I>(&'a self, anchors: I) -> Vec<(usize, Anchor, bool)> - where - I: 'a + IntoIterator, - { - let mut anchors = anchors.into_iter().enumerate().peekable(); - let mut cursor = self.excerpts.cursor::(()); - cursor.next(); - - let mut result = Vec::new(); - - while let Some((_, anchor)) = anchors.peek() { - let old_excerpt_id = anchor.excerpt_id; - - // Find the location where this anchor's excerpt should be. - let old_locator = self.excerpt_locator_for_id(old_excerpt_id); - cursor.seek_forward(&Some(old_locator), Bias::Left); - - let next_excerpt = cursor.item(); - let prev_excerpt = cursor.prev_item(); - - // Process all of the anchors for this excerpt. - while let Some((anchor_ix, &anchor)) = - anchors.next_if(|(_, anchor)| anchor.excerpt_id == old_excerpt_id) - { - let mut anchor = anchor; - - // Leave min and max anchors unchanged if invalid or - // if the old excerpt still exists at this location - let mut kept_position = next_excerpt - .is_some_and(|e| e.id == old_excerpt_id && e.contains(&anchor)) - || old_excerpt_id == ExcerptId::max() - || old_excerpt_id == ExcerptId::min(); - - // If the old excerpt no longer exists at this location, then attempt to - // find an equivalent position for this anchor in an adjacent excerpt. - if !kept_position { - for excerpt in [next_excerpt, prev_excerpt].iter().filter_map(|e| *e) { - if excerpt.contains(&anchor) { - anchor.excerpt_id = excerpt.id; - kept_position = true; - break; - } - } - } - - // If there's no adjacent excerpt that contains the anchor's position, - // then report that the anchor has lost its position. - if !kept_position { - anchor = if let Some(excerpt) = next_excerpt { - let mut text_anchor = excerpt - .range - .context - .start - .bias(anchor.text_anchor.bias, &excerpt.buffer); - if text_anchor - .cmp(&excerpt.range.context.end, &excerpt.buffer) - .is_gt() - { - text_anchor = excerpt.range.context.end; - } - Anchor::text(excerpt.id, text_anchor) - } else if let Some(excerpt) = prev_excerpt { - let mut text_anchor = excerpt - .range - .context - .end - .bias(anchor.text_anchor.bias, &excerpt.buffer); - if text_anchor - .cmp(&excerpt.range.context.start, &excerpt.buffer) - .is_lt() - { - text_anchor = excerpt.range.context.start; - } - Anchor::text(excerpt.id, text_anchor) - } else if anchor.text_anchor.bias == Bias::Left { - Anchor::min() - } else { - Anchor::max() - }; + fn excerpts_for_buffer(&self, buffer_id: BufferId) -> impl Iterator { + if let Some(path_key) = self.path_keys_by_buffer.get(&buffer_id) { + let mut cursor = self.excerpts.cursor::(()); + cursor.seek_forward(path_key, Bias::Left); + Some(iter::from_fn(move || { + let excerpt = cursor.item()?; + if &excerpt.path_key != path_key { + return None; } - - result.push((anchor_ix, anchor, kept_position)); - } + cursor.next(); + Some(excerpt) + })) + } else { + None } - result.sort_unstable_by(|a, b| a.1.cmp(&b.1, self)); - result + .into_iter() + .flatten() } pub fn anchor_before(&self, position: T) -> Anchor { @@ -5387,46 +5319,48 @@ impl MultiBufferSnapshot { } } - /// Returns an anchor for the given excerpt and text anchor, - /// Returns [`None`] if the excerpt_id is no longer valid or the text anchor range is out of excerpt's bounds. + /// Creates a multibuffer anchor range for the given buffer anchor range, if any excerpt contains both endpoints. pub fn anchor_range_in_buffer( &self, - excerpt_id: BufferId, + buffer_id: BufferId, text_anchor: Range, ) -> Option> { - let path_key_index = self.first_excerpt_for_buffer(buffer_id)?.path_key_index; - - let target = self.anchor_see - self.excerpts.cursor.find(&snapshot, (path_key_index, anchor)) + for excerpt in self.excerpts_for_buffer(buffer_id) { + if excerpt.range.contains(&text_anchor.start, &excerpt.buffer) + && excerpt.range.contains(&text_anchor.end, &excerpt.buffer) + { + return Some(Anchor::range_in_buffer(excerpt.path_key_index, text_anchor)); + } + } - Some( - Self::anchor_in_excerpt_(excerpt, text_anchor.start)? - ..Self::anchor_in_excerpt_(excerpt, text_anchor.end)?, - ) + None } - /// Returns an anchor for the given excerpt and text anchor, - /// Returns [`None`] if the excerpt_id is no longer valid or the text anchor range is out of excerpt's bounds. - pub fn anchor_in_excerpt( + /// Creates a multibuffer anchor for the given buffer anchor, if it is contained in any excerpt. + pub fn anchor_in_buffer( &self, - excerpt_id: ExcerptId, + buffer_id: BufferId, text_anchor: text::Anchor, ) -> Option { - let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?; - Self::anchor_in_excerpt_(excerpt, text_anchor) + for excerpt in self.excerpts_for_buffer(buffer_id) { + if excerpt.range.contains(&text_anchor, &excerpt.buffer) { + return Some(Anchor::in_buffer(excerpt.path_key_index, text_anchor)); + } + } + + None } - /// Same as [`MultiBuffer::anchor_in_excerpt`], but more efficient than calling it multiple times. - pub fn anchors_in_excerpt( + pub fn anchors_in_buffer( &self, - excerpt_id: ExcerptId, + buffer_id: BufferId, text_anchors: impl IntoIterator, - ) -> Option>> { - let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?; + ) -> Option> { + let path_key_index = self.path_key_index_for_buffer(buffer_id)?; Some( text_anchors .into_iter() - .map(|text_anchor| Self::anchor_in_excerpt_(excerpt, text_anchor)), + .map(move |anchor| Anchor::in_buffer(path_key_index, anchor)), ) } @@ -5468,12 +5402,10 @@ impl MultiBufferSnapshot { } } - pub fn excerpts( - &self, - ) -> impl Iterator)> { + pub fn excerpts(&self) -> impl Iterator)> { self.excerpts .iter() - .map(|excerpt| (excerpt.id, &*excerpt.buffer, excerpt.range.clone())) + .map(|excerpt| (&*excerpt.buffer, excerpt.range.clone())) } fn cursor<'a, MBD, BD>(&'a self) -> MultiBufferCursor<'a, MBD, BD> @@ -5491,30 +5423,12 @@ impl MultiBufferSnapshot { } } - pub fn excerpt_before(&self, excerpt_id: ExcerptId) -> Option> { - let start_locator = self.excerpt_locator_for_id(excerpt_id); - let mut excerpts = self - .excerpts - .cursor::, ExcerptOffset>>(()); - excerpts.seek(&Some(start_locator), Bias::Left); + pub fn excerpt_before(&self, anchor: Anchor) -> Option { + let target = anchor.try_seek_target(&self)?; + let mut excerpts = self.excerpts.cursor::(()); + excerpts.seek(&target, Bias::Left); excerpts.prev(); - - let mut diff_transforms = self - .diff_transforms - .cursor::>(()); - diff_transforms.seek(&excerpts.start().1, Bias::Left); - if diff_transforms.end().excerpt_dimension < excerpts.start().1 { - diff_transforms.next(); - } - - let excerpt = excerpts.item()?; - Some(MultiBufferExcerpt { - excerpt, - offset: diff_transforms.start().output_dimension.0, - buffer_offset: BufferOffset(excerpt.range.context.start.to_offset(&excerpt.buffer)), - excerpt_offset: excerpts.start().1, - diff_transforms, - }) + Some(excerpts.item()?.info()) } pub fn excerpt_boundaries_in_range( @@ -5586,17 +5500,15 @@ impl MultiBufferSnapshot { }; let prev = prev_region.as_ref().map(|region| ExcerptBoundaryInfo { - id: region.id, + path_key_index: region.path_key_index, buffer: region.buffer.clone(), - buffer_id: region.buffer_id, range: region.range.clone(), end_row: MultiBufferRow(next_region_start.row), }); let next = ExcerptBoundaryInfo { - id: next_excerpt.id, + path_key_index: next_excerpt.path_key_index, buffer: next_excerpt.buffer.clone(), - buffer_id: next_excerpt.buffer_id, range: next_excerpt.range.clone(), end_row: if next_excerpt.has_trailing_newline { MultiBufferRow(next_region_end.row - 1) @@ -6278,7 +6190,12 @@ impl MultiBufferSnapshot { .map(|entry| (entry.range, entry.diagnostic)), ) }) - .map(|(range, diagnostic, b)| (b.buffer_id, DiagnosticEntryRef { diagnostic, range })) + .map(|(range, diagnostic, b)| { + ( + b.buffer.remote_id(), + DiagnosticEntryRef { diagnostic, range }, + ) + }) } pub fn syntax_ancestor( @@ -6299,7 +6216,7 @@ impl MultiBufferSnapshot { } pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Option> { - let (excerpt_id, _, buffer) = self.as_singleton()?; + let buffer = self.as_singleton()?; let outline = buffer.outline(theme); Some(Outline::new( outline @@ -6308,17 +6225,19 @@ impl MultiBufferSnapshot { .flat_map(|item| { Some(OutlineItem { depth: item.depth, - range: self.anchor_range_in_buffer(excerpt_id, item.range)?, - source_range_for_text: self - .anchor_range_in_buffer(excerpt_id, item.source_range_for_text)?, + range: self.anchor_range_in_buffer(buffer.remote_id(), item.range)?, + source_range_for_text: self.anchor_range_in_buffer( + buffer.remote_id(), + item.source_range_for_text, + )?, text: item.text, highlight_ranges: item.highlight_ranges, name_ranges: item.name_ranges, body_range: item.body_range.and_then(|body_range| { - self.anchor_range_in_buffer(excerpt_id, body_range) + self.anchor_range_in_buffer(buffer.remote_id(), body_range) }), annotation_range: item.annotation_range.and_then(|annotation_range| { - self.anchor_range_in_buffer(excerpt_id, annotation_range) + self.anchor_range_in_buffer(buffer.remote_id(), annotation_range) }), }) }) @@ -6332,46 +6251,38 @@ impl MultiBufferSnapshot { theme: Option<&SyntaxTheme>, ) -> Option<(BufferId, Vec>)> { let anchor = self.anchor_before(offset); - let excerpt @ &Excerpt { - id: excerpt_id, - buffer_id, - ref buffer, - .. - } = self.excerpt(anchor.excerpt_id)?; - if cfg!(debug_assertions) { - match anchor.text_anchor.buffer_id { - // we clearly are hitting this according to sentry, but in what situations can this occur? - Some(anchor_buffer_id) => { - assert_eq!( - anchor_buffer_id, buffer_id, - "anchor {anchor:?} does not match with resolved excerpt {excerpt:?}" - ) - } - None => assert!(anchor.is_max()), - } - }; + let target = anchor.try_seek_target(&self)?; + let (_, _, excerpt) = self.excerpts.find((), &target, Bias::Left); + let excerpt = excerpt?; Some(( - buffer_id, - buffer - .symbols_containing(anchor.text_anchor, theme) + excerpt.buffer.remote_id(), + excerpt + .buffer + .symbols_containing( + anchor + .excerpt_anchor() + .map(|anchor| anchor.text_anchor()) + .unwrap_or(text::Anchor::MIN), + theme, + ) .into_iter() .flat_map(|item| { Some(OutlineItem { depth: item.depth, source_range_for_text: Anchor::range_in_buffer( - excerpt_id, + excerpt.path_key_index, item.source_range_for_text, ), - range: Anchor::range_in_buffer(excerpt_id, item.range), + range: Anchor::range_in_buffer(excerpt.path_key_index, item.range), text: item.text, highlight_ranges: item.highlight_ranges, name_ranges: item.name_ranges, - body_range: item - .body_range - .map(|body_range| Anchor::range_in_buffer(excerpt_id, body_range)), - annotation_range: item - .annotation_range - .map(|body_range| Anchor::range_in_buffer(excerpt_id, body_range)), + body_range: item.body_range.map(|body_range| { + Anchor::range_in_buffer(excerpt.path_key_index, body_range) + }), + annotation_range: item.annotation_range.map(|body_range| { + Anchor::range_in_buffer(excerpt.path_key_index, body_range) + }), }) }) .collect(), @@ -6379,15 +6290,27 @@ impl MultiBufferSnapshot { } pub fn buffer_for_path(&self, path: &PathKey) -> Option<&BufferSnapshot> { - todo!() + let (_, _, excerpt) = self + .excerpts + .find::((), path, Bias::Left); + Some(&excerpt?.buffer) } pub fn path_for_buffer(&self, buffer_id: BufferId) -> Option<&PathKey> { self.path_keys_by_buffer.get(&buffer_id) } + pub fn path_key_index_for_buffer(&self, buffer_id: BufferId) -> Option { + self.first_excerpt_for_buffer(buffer_id) + .map(|excerpt| excerpt.path_key_index) + } + pub fn first_excerpt_for_buffer(&self, buffer_id: BufferId) -> Option<&Excerpt> { let path_key = self.path_keys_by_buffer.get(&buffer_id)?; + self.first_excerpt_for_path(&path_key) + } + + pub fn first_excerpt_for_path(&self, path_key: &PathKey) -> Option<&Excerpt> { let (_, _, first_excerpt) = self.excerpts .find::((), path_key, Bias::Left); diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 7b60f562d8be20cd7755d63f0aee3498c128026b..b5446349de83cdbd9095901d8b8d72ef1c08a7da 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -3058,8 +3058,8 @@ async fn test_random_multibuffer(cx: &mut TestAppContext, mut rng: StdRng) { let start = excerpt.range.start; let end = excerpt.range.end; - let range = snapshot.anchor_in_excerpt(excerpt.id, start).unwrap() - ..snapshot.anchor_in_excerpt(excerpt.id, end).unwrap(); + let range = snapshot.anchor_in_buffer(excerpt.id, start).unwrap() + ..snapshot.anchor_in_buffer(excerpt.id, end).unwrap(); log::info!( "expanding diff hunks in range {:?} (excerpt id {:?}, index {excerpt_ix:?}, buffer id {:?})", diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index d2457471280e9d2fc02bb51a7fa67b11f1e5b01c..76481fab41bdd27187d4a1f0cf9380fc727268db 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -1120,7 +1120,7 @@ impl OutlinePanel { |(excerpt_id, buffer_snapshot, excerpt_range)| { if buffer_snapshot.remote_id() == file.buffer_id { multi_buffer_snapshot - .anchor_in_excerpt(excerpt_id, excerpt_range.context.start) + .anchor_in_buffer(excerpt_id, excerpt_range.context.start) } else { None } @@ -1145,19 +1145,19 @@ impl OutlinePanel { .and_then(|excerpts| { let (excerpt_id, excerpt_range) = excerpts.first()?; multi_buffer_snapshot - .anchor_in_excerpt(*excerpt_id, excerpt_range.context.start) + .anchor_in_buffer(*excerpt_id, excerpt_range.context.start) }) } PanelEntry::Outline(OutlineEntry::Outline(outline)) => multi_buffer_snapshot - .anchor_in_excerpt(outline.excerpt_id, outline.outline.range.start) + .anchor_in_buffer(outline.excerpt_id, outline.outline.range.start) .or_else(|| { multi_buffer_snapshot - .anchor_in_excerpt(outline.excerpt_id, outline.outline.range.end) + .anchor_in_buffer(outline.excerpt_id, outline.outline.range.end) }), PanelEntry::Outline(OutlineEntry::Excerpt(excerpt)) => { change_selection = false; change_focus = false; - multi_buffer_snapshot.anchor_in_excerpt(excerpt.id, excerpt.range.context.start) + multi_buffer_snapshot.anchor_in_buffer(excerpt.id, excerpt.range.context.start) } PanelEntry::Search(search_entry) => Some(search_entry.match_range.start), };