Detailed changes
@@ -210,14 +210,14 @@ impl<T> AnchorRangeMap<T> {
.zip(self.entries.iter().map(|e| &e.1))
}
- pub fn intersecting_ranges<'a, D, T>(
+ pub fn intersecting_ranges<'a, D, I>(
&'a self,
- range: Range<(T, Bias)>,
+ range: Range<(I, Bias)>,
content: impl Into<Content<'a>> + 'a,
) -> impl Iterator<Item = (Range<D>, &'a T)> + 'a
where
D: 'a + TextDimension<'a>,
- T: ToOffset,
+ I: ToOffset,
{
let content = content.into();
let range = content.anchor_at(range.start.0, range.start.1)
@@ -229,10 +229,20 @@ impl<T> AnchorRangeMap<T> {
version: self.version.clone(),
};
let start_ix = self.entries.binary_search_by(|probe| {
- probe_anchor.full_offset = probe.0.start;
+ probe_anchor.full_offset = probe.0.end;
probe_anchor.cmp(&range.start, &content).unwrap()
});
- std::iter::empty()
+
+ match start_ix {
+ Ok(start_ix) | Err(start_ix) => content
+ .summaries_for_anchor_ranges(
+ self.version.clone(),
+ self.start_bias,
+ self.end_bias,
+ self.entries[start_ix..].iter().map(|e| &e.0),
+ )
+ .zip(self.entries.iter().map(|e| &e.1)),
+ }
}
pub fn full_offset_ranges(&self) -> impl Iterator<Item = &(Range<FullOffset>, T)> {
@@ -1,3 +1,5 @@
+use sum_tree::Bias;
+
use crate::rope::TextDimension;
use super::{AnchorRangeMap, Buffer, Content, Point, ToOffset, ToPoint};
@@ -117,6 +119,27 @@ impl SelectionSet {
})
}
+ pub fn intersecting_selections<'a, D, I, C>(
+ &'a self,
+ range: Range<(I, Bias)>,
+ content: C,
+ ) -> impl 'a + Iterator<Item = Selection<D>>
+ where
+ D: 'a + TextDimension<'a>,
+ I: 'a + ToOffset,
+ C: 'a + Into<Content<'a>>,
+ {
+ self.selections
+ .intersecting_ranges(range, content)
+ .map(|(range, state)| Selection {
+ id: state.id,
+ start: range.start,
+ end: range.end,
+ reversed: state.reversed,
+ goal: state.goal,
+ })
+ }
+
pub fn oldest_selection<'a, D, C>(&'a self, content: C) -> Option<Selection<D>>
where
D: 'a + TextDimension<'a>,
@@ -748,11 +748,13 @@ impl Element for EditorElement {
self.update_view(cx.app, |view, cx| {
highlighted_row = view.highlighted_row();
for selection_set_id in view.active_selection_sets(cx).collect::<Vec<_>>() {
- let replica_selections = view.selections_in_range(
- selection_set_id,
- DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
- cx,
- );
+ let replica_selections = view
+ .intersecting_selections(
+ selection_set_id,
+ DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
+ cx,
+ )
+ .collect::<Vec<_>>();
for selection in &replica_selections {
if selection_set_id == view.selection_set_id {
let is_empty = selection.start == selection.end;
@@ -3017,23 +3017,15 @@ impl Editor {
.map(|(set_id, _)| *set_id)
}
- pub fn selections_in_range<'a>(
+ pub fn intersecting_selections<'a>(
&'a self,
set_id: SelectionSetId,
range: Range<DisplayPoint>,
cx: &'a mut MutableAppContext,
- ) -> Vec<Selection<DisplayPoint>> {
+ ) -> impl 'a + Iterator<Item = Selection<DisplayPoint>> {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = self.buffer.read(cx);
- let selections = self
- .buffer
- .read(cx)
- .selection_set(set_id)
- .unwrap()
- .selections::<Point, _>(buffer)
- .collect::<Vec<_>>();
- let start = range.start.to_point(&display_map);
- let start_index = self.selection_insertion_index(&selections, start);
+
let pending_selection = if set_id == self.selection_set_id {
self.pending_selection.as_ref().and_then(|pending| {
let selection_start = pending.selection.start.to_display_point(&display_map);
@@ -3053,9 +3045,17 @@ impl Editor {
} else {
None
};
+
+ let range = (range.start.to_offset(&display_map, Bias::Left), Bias::Left)
+ ..(range.end.to_offset(&display_map, Bias::Left), Bias::Right);
+ let selections = self
+ .buffer
+ .read(cx)
+ .selection_set(set_id)
+ .unwrap()
+ .intersecting_selections::<Point, _, _>(range, buffer);
+
selections
- .into_iter()
- .skip(start_index)
.map(move |s| Selection {
id: s.id,
start: s.start.to_display_point(&display_map),
@@ -3063,22 +3063,7 @@ impl Editor {
reversed: s.reversed,
goal: s.goal,
})
- .take_while(move |r| r.start <= range.end || r.end <= range.end)
.chain(pending_selection)
- .collect()
- }
-
- fn selection_insertion_index(&self, selections: &[Selection<Point>], start: Point) -> usize {
- match selections.binary_search_by_key(&start, |probe| probe.start) {
- Ok(index) => index,
- Err(index) => {
- if index > 0 && selections[index - 1].end > start {
- index - 1
- } else {
- index
- }
- }
- }
}
pub fn selections<'a, D>(&self, cx: &'a AppContext) -> impl 'a + Iterator<Item = Selection<D>>
@@ -5694,7 +5679,7 @@ mod tests {
impl Editor {
fn selection_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
- self.selections_in_range(
+ self.intersecting_selections(
self.selection_set_id,
DisplayPoint::zero()..self.max_point(cx),
cx,