@@ -90,7 +90,7 @@ use std::{
cmp::{self, Ordering, Reverse},
mem,
num::NonZeroU32,
- ops::{ControlFlow, Deref, DerefMut, Range},
+ ops::{ControlFlow, Deref, DerefMut, Range, RangeInclusive},
path::Path,
sync::Arc,
time::{Duration, Instant},
@@ -7549,6 +7549,78 @@ impl Editor {
results
}
+ pub fn background_highlight_row_ranges<T: 'static>(
+ &self,
+ search_range: Range<Anchor>,
+ display_snapshot: &DisplaySnapshot,
+ count: usize,
+ ) -> Vec<RangeInclusive<DisplayPoint>> {
+ let mut results = Vec::new();
+ let buffer = &display_snapshot.buffer_snapshot;
+ let Some((_, ranges)) = self.background_highlights
+ .get(&TypeId::of::<T>()) else {
+ return vec![];
+ };
+
+ let start_ix = match ranges.binary_search_by(|probe| {
+ let cmp = probe.end.cmp(&search_range.start, buffer);
+ if cmp.is_gt() {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }) {
+ Ok(i) | Err(i) => i,
+ };
+ let mut push_region = |start: Option<Point>, end: Option<Point>| {
+ if let (Some(start_display), Some(end_display)) = (start, end) {
+ results.push(
+ start_display.to_display_point(display_snapshot)
+ ..=end_display.to_display_point(display_snapshot),
+ );
+ }
+ };
+ let mut start_row: Option<Point> = None;
+ let mut end_row: Option<Point> = None;
+ if ranges.len() > count {
+ return vec![];
+ }
+ for range in &ranges[start_ix..] {
+ if range.start.cmp(&search_range.end, buffer).is_ge() {
+ break;
+ }
+ let end = range.end.to_point(buffer);
+ if let Some(current_row) = &end_row {
+ if end.row == current_row.row {
+ continue;
+ }
+ }
+ let start = range.start.to_point(buffer);
+
+ if start_row.is_none() {
+ assert_eq!(end_row, None);
+ start_row = Some(start);
+ end_row = Some(end);
+ continue;
+ }
+ if let Some(current_end) = end_row.as_mut() {
+ if start.row > current_end.row + 1 {
+ push_region(start_row, end_row);
+ start_row = Some(start);
+ end_row = Some(end);
+ } else {
+ // Merge two hunks.
+ *current_end = end;
+ }
+ } else {
+ unreachable!();
+ }
+ }
+ // We might still have a hunk that was not rendered (if there was a search hit on the last line)
+ push_region(start_row, end_row);
+ results
+ }
+
pub fn highlight_text<T: 'static>(
&mut self,
ranges: Vec<Range<Anchor>>,
@@ -1107,8 +1107,6 @@ impl EditorElement {
if layout.is_singleton && scrollbar_settings.selections {
let start_anchor = Anchor::min();
let end_anchor = Anchor::max();
- let mut start_row = None;
- let mut end_row = None;
let color = scrollbar_theme.selections;
let border = Border {
width: 1.,
@@ -1119,54 +1117,32 @@ impl EditorElement {
bottom: false,
left: true,
};
- let mut push_region = |start, end| {
- if let (Some(start_display), Some(end_display)) = (start, end) {
- let start_y = y_for_row(start_display as f32);
- let mut end_y = y_for_row(end_display as f32);
- if end_y - start_y < 1. {
- end_y = start_y + 1.;
- }
- let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y));
-
- scene.push_quad(Quad {
- bounds,
- background: Some(color),
- border,
- corner_radius: style.thumb.corner_radius,
- })
+ let mut push_region = |start: DisplayPoint, end: DisplayPoint| {
+ let start_y = y_for_row(start.row() as f32);
+ let mut end_y = y_for_row(end.row() as f32);
+ if end_y - start_y < 1. {
+ end_y = start_y + 1.;
}
+ let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y));
+
+ scene.push_quad(Quad {
+ bounds,
+ background: Some(color),
+ border,
+ corner_radius: style.thumb.corner_radius,
+ })
};
- for (row, _) in &editor
- .background_highlights_in_range_for::<crate::items::BufferSearchHighlights>(
+ let background_ranges = editor
+ .background_highlight_row_ranges::<crate::items::BufferSearchHighlights>(
start_anchor..end_anchor,
&layout.position_map.snapshot,
- &theme,
- )
- {
- let start_display = row.start;
- let end_display = row.end;
-
- if start_row.is_none() {
- assert_eq!(end_row, None);
- start_row = Some(start_display.row());
- end_row = Some(end_display.row());
- continue;
- }
- if let Some(current_end) = end_row.as_mut() {
- if start_display.row() > *current_end + 1 {
- push_region(start_row, end_row);
- start_row = Some(start_display.row());
- end_row = Some(end_display.row());
- } else {
- // Merge two hunks.
- *current_end = end_display.row();
- }
- } else {
- unreachable!();
- }
+ 50000,
+ );
+ for row in background_ranges {
+ let start = row.start();
+ let end = row.end();
+ push_region(*start, *end);
}
- // We might still have a hunk that was not rendered (if there was a search hit on the last line)
- push_region(start_row, end_row);
}
if layout.is_singleton && scrollbar_settings.git_diff {