diff --git a/crates/editor/src/bracket_colorization.rs b/crates/editor/src/bracket_colorization.rs index 65d8c139e99437e37d0c18551dd01475ac824bfd..5631d7f5adc0cefb5adf840fa9f62113179dff2f 100644 --- a/crates/editor/src/bracket_colorization.rs +++ b/crates/editor/src/bracket_colorization.rs @@ -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 { diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 2e59eaa621c79bc8d0d0a149704cb55314e9b70d..3e9d113a300fad6f8c29221d0f886497793fafc9 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -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 { 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 { + /// 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, + ) -> Option>> { + 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 { match text_anchor.buffer_id { Some(buffer_id) if buffer_id == excerpt.buffer_id => (), Some(_) => return None,