Detailed changes
@@ -194,6 +194,66 @@ impl<T> AnchorRangeMap<T> {
.iter()
.map(|(range, value)| (range.start.0..range.end.0, value))
}
+
+ pub fn min_by_key<'a, C, D, F, K>(
+ &self,
+ content: C,
+ mut extract_key: F,
+ ) -> Option<(Range<D>, &T)>
+ where
+ C: Into<Content<'a>>,
+ D: 'a + TextDimension<'a>,
+ F: FnMut(&T) -> K,
+ K: Ord,
+ {
+ let content = content.into();
+ self.entries
+ .iter()
+ .min_by_key(|(_, value)| extract_key(value))
+ .map(|(range, value)| (self.resolve_range(range, &content), value))
+ }
+
+ pub fn max_by_key<'a, C, D, F, K>(
+ &self,
+ content: C,
+ mut extract_key: F,
+ ) -> Option<(Range<D>, &T)>
+ where
+ C: Into<Content<'a>>,
+ D: 'a + TextDimension<'a>,
+ F: FnMut(&T) -> K,
+ K: Ord,
+ {
+ let content = content.into();
+ self.entries
+ .iter()
+ .max_by_key(|(_, value)| extract_key(value))
+ .map(|(range, value)| (self.resolve_range(range, &content), value))
+ }
+
+ fn resolve_range<'a, D>(
+ &self,
+ range: &Range<(FullOffset, Bias)>,
+ content: &Content<'a>,
+ ) -> Range<D>
+ where
+ D: 'a + TextDimension<'a>,
+ {
+ let (start, start_bias) = range.start;
+ let mut anchor = Anchor {
+ full_offset: start,
+ bias: start_bias,
+ version: self.version.clone(),
+ };
+ let start = content.summary_for_anchor(&anchor);
+
+ let (end, end_bias) = range.end;
+ anchor.full_offset = end;
+ anchor.bias = end_bias;
+ let end = content.summary_for_anchor(&anchor);
+
+ start..end
+ }
}
impl<T: PartialEq> PartialEq for AnchorRangeMap<T> {
@@ -116,4 +116,36 @@ impl SelectionSet {
goal: state.goal,
})
}
+
+ pub fn oldest_selection<'a, D, C>(&'a self, content: C) -> Option<Selection<D>>
+ where
+ D: 'a + TextDimension<'a>,
+ C: 'a + Into<Content<'a>>,
+ {
+ self.selections
+ .min_by_key(content, |selection| selection.id)
+ .map(|(range, state)| Selection {
+ id: state.id,
+ start: range.start,
+ end: range.end,
+ reversed: state.reversed,
+ goal: state.goal,
+ })
+ }
+
+ pub fn newest_selection<'a, D, C>(&'a self, content: C) -> Option<Selection<D>>
+ where
+ D: 'a + TextDimension<'a>,
+ C: 'a + Into<Content<'a>>,
+ {
+ self.selections
+ .max_by_key(content, |selection| selection.id)
+ .map(|(range, state)| Selection {
+ id: state.id,
+ start: range.start,
+ end: range.end,
+ reversed: state.reversed,
+ goal: state.goal,
+ })
+ }
}
@@ -707,16 +707,8 @@ impl Editor {
self.update_selections(vec![pending_selection], true, cx);
}
} else {
- let selections = self.selections::<Point>(cx);
- let mut selection_count = 0;
- let mut oldest_selection = selections
- .min_by_key(|s| {
- selection_count += 1;
- s.id
- })
- .unwrap()
- .clone();
- if selection_count == 1 {
+ let mut oldest_selection = self.oldest_selection::<usize>(cx);
+ if self.selection_count(cx) == 1 {
oldest_selection.start = oldest_selection.head().clone();
oldest_selection.end = oldest_selection.head().clone();
}
@@ -2294,9 +2286,8 @@ impl Editor {
) -> impl 'a + Iterator<Item = Range<DisplayPoint>> {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = self.buffer.read(cx);
- let selections = buffer
- .selection_set(set_id)
- .unwrap()
+ let selections = self
+ .selection_set(cx)
.selections::<Point, _>(buffer)
.collect::<Vec<_>>();
let start = range.start.to_point(&display_map);
@@ -2343,18 +2334,8 @@ impl Editor {
D: 'a + TextDimension<'a> + Ord,
{
let buffer = self.buffer.read(cx);
- let mut selections = buffer
- .selection_set(self.selection_set_id)
- .unwrap()
- .selections::<D, _>(buffer)
- .peekable();
- let mut pending_selection = self.pending_selection.clone().map(|selection| Selection {
- id: selection.id,
- start: selection.start.summary::<D, _>(buffer),
- end: selection.end.summary::<D, _>(buffer),
- reversed: selection.reversed,
- goal: selection.goal,
- });
+ let mut selections = self.selection_set(cx).selections::<D, _>(buffer).peekable();
+ let mut pending_selection = self.pending_selection(cx);
iter::from_fn(move || {
if let Some(pending) = pending_selection.as_mut() {
while let Some(next_selection) = selections.peek() {
@@ -2380,6 +2361,56 @@ impl Editor {
})
}
+ fn pending_selection<'a, D>(&self, cx: &'a AppContext) -> Option<Selection<D>>
+ where
+ D: 'a + TextDimension<'a>,
+ {
+ let buffer = self.buffer.read(cx);
+ self.pending_selection.as_ref().map(|selection| Selection {
+ id: selection.id,
+ start: selection.start.summary::<D, _>(buffer),
+ end: selection.end.summary::<D, _>(buffer),
+ reversed: selection.reversed,
+ goal: selection.goal,
+ })
+ }
+
+ fn selection_count<'a>(&self, cx: &'a AppContext) -> usize {
+ let mut selection_count = self.selection_set(cx).len();
+ if self.pending_selection.is_some() {
+ selection_count += 1;
+ }
+ selection_count
+ }
+
+ pub fn oldest_selection<'a, T>(&self, cx: &'a AppContext) -> Selection<T>
+ where
+ T: 'a + TextDimension<'a>,
+ {
+ let buffer = self.buffer.read(cx);
+ self.selection_set(cx)
+ .oldest_selection(buffer)
+ .or_else(|| self.pending_selection(cx))
+ .unwrap()
+ }
+
+ pub fn newest_selection<'a, T>(&self, cx: &'a AppContext) -> Selection<T>
+ where
+ T: 'a + TextDimension<'a>,
+ {
+ let buffer = self.buffer.read(cx);
+ self.pending_selection(cx)
+ .or_else(|| self.selection_set(cx).newest_selection(buffer))
+ .unwrap()
+ }
+
+ fn selection_set<'a>(&self, cx: &'a AppContext) -> &'a SelectionSet {
+ self.buffer
+ .read(cx)
+ .selection_set(self.selection_set_id)
+ .unwrap()
+ }
+
fn update_selections<T>(
&mut self,
mut selections: Vec<Selection<T>>,
@@ -258,11 +258,7 @@ impl DiagnosticMessage {
fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
let editor = editor.read(cx);
- let cursor_position = editor
- .selections::<usize>(cx)
- .max_by_key(|selection| selection.id)
- .unwrap()
- .head();
+ let cursor_position = editor.newest_selection(cx).head();
let new_diagnostic = editor
.buffer()
.read(cx)