@@ -7,6 +7,7 @@ use std::ops::Range;
use crate::Editor;
use collections::HashMap;
use gpui::{Context, HighlightStyle};
+use itertools::Itertools;
use language::language_settings;
use multi_buffer::{Anchor, ExcerptId};
use ui::{ActiveTheme, utils::ensure_minimum_contrast};
@@ -26,17 +27,20 @@ impl Editor {
let accents_count = cx.theme().accents().0.len();
let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx);
let all_excerpts = self.buffer().read(cx).excerpt_ids();
- let anchor_in_multi_buffer = |current_excerpt: ExcerptId, text_anchor: text::Anchor| {
+ let anchors_in_multi_buffer = |current_excerpt: ExcerptId,
+ text_anchors: [text::Anchor; 4]|
+ -> Option<[Option<_>; 4]> {
multi_buffer_snapshot
- .anchor_in_excerpt(current_excerpt, text_anchor)
+ .anchors_in_excerpt(current_excerpt, text_anchors)
.or_else(|| {
all_excerpts
.iter()
.filter(|&&excerpt_id| excerpt_id != current_excerpt)
.find_map(|&excerpt_id| {
- multi_buffer_snapshot.anchor_in_excerpt(excerpt_id, text_anchor)
+ multi_buffer_snapshot.anchors_in_excerpt(excerpt_id, text_anchors)
})
- })
+ })?
+ .collect_array()
};
let bracket_matches_by_accent = self.visible_excerpts(cx).into_iter().fold(
@@ -77,13 +81,24 @@ impl Editor {
let buffer_close_range = buffer_snapshot
.anchor_before(pair.close_range.start)
..buffer_snapshot.anchor_after(pair.close_range.end);
+ let [
+ buffer_open_range_start,
+ buffer_open_range_end,
+ buffer_close_range_start,
+ buffer_close_range_end,
+ ] = anchors_in_multi_buffer(
+ excerpt_id,
+ [
+ buffer_open_range.start,
+ buffer_open_range.end,
+ buffer_close_range.start,
+ buffer_close_range.end,
+ ],
+ )?;
let multi_buffer_open_range =
- anchor_in_multi_buffer(excerpt_id, buffer_open_range.start)
- .zip(anchor_in_multi_buffer(excerpt_id, buffer_open_range.end));
+ buffer_open_range_start.zip(buffer_open_range_end);
let multi_buffer_close_range =
- anchor_in_multi_buffer(excerpt_id, buffer_close_range.start).zip(
- anchor_in_multi_buffer(excerpt_id, buffer_close_range.end),
- );
+ buffer_close_range_start.zip(buffer_close_range_end);
let mut ranges = Vec::with_capacity(2);
if let Some((open_start, open_end)) = multi_buffer_open_range {
@@ -5084,8 +5084,8 @@ impl MultiBufferSnapshot {
let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?;
Some(
- self.anchor_in_excerpt_(excerpt, text_anchor.start)?
- ..self.anchor_in_excerpt_(excerpt, text_anchor.end)?,
+ Self::anchor_in_excerpt_(excerpt, text_anchor.start)?
+ ..Self::anchor_in_excerpt_(excerpt, text_anchor.end)?,
)
}
@@ -5097,10 +5097,24 @@ impl MultiBufferSnapshot {
text_anchor: text::Anchor,
) -> Option<Anchor> {
let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?;
- self.anchor_in_excerpt_(excerpt, text_anchor)
+ Self::anchor_in_excerpt_(excerpt, text_anchor)
}
- fn anchor_in_excerpt_(&self, excerpt: &Excerpt, text_anchor: text::Anchor) -> Option<Anchor> {
+ /// Same as [`MultiBuffer::anchor_in_excerpt`], but more efficient than calling it multiple times.
+ pub fn anchors_in_excerpt(
+ &self,
+ excerpt_id: ExcerptId,
+ text_anchors: impl IntoIterator<Item = text::Anchor>,
+ ) -> Option<impl Iterator<Item = Option<Anchor>>> {
+ let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?;
+ Some(
+ text_anchors
+ .into_iter()
+ .map(|text_anchor| Self::anchor_in_excerpt_(excerpt, text_anchor)),
+ )
+ }
+
+ fn anchor_in_excerpt_(excerpt: &Excerpt, text_anchor: text::Anchor) -> Option<Anchor> {
match text_anchor.buffer_id {
Some(buffer_id) if buffer_id == excerpt.buffer_id => (),
Some(_) => return None,