Refactor retrieving oldest and newest selection

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-11-18 15:04:12 +01:00
parent 0a6293bcda
commit 401b59be5c
4 changed files with 149 additions and 30 deletions

View File

@ -194,6 +194,66 @@ impl<T> AnchorRangeMap<T> {
.iter() .iter()
.map(|(range, value)| (range.start.0..range.end.0, value)) .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> { impl<T: PartialEq> PartialEq for AnchorRangeMap<T> {

View File

@ -116,4 +116,36 @@ impl SelectionSet {
goal: state.goal, 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,
})
}
} }

View File

@ -707,16 +707,8 @@ impl Editor {
self.update_selections(vec![pending_selection], true, cx); self.update_selections(vec![pending_selection], true, cx);
} }
} else { } else {
let selections = self.selections::<Point>(cx); let mut oldest_selection = self.oldest_selection::<usize>(cx);
let mut selection_count = 0; if self.selection_count(cx) == 1 {
let mut oldest_selection = selections
.min_by_key(|s| {
selection_count += 1;
s.id
})
.unwrap()
.clone();
if selection_count == 1 {
oldest_selection.start = oldest_selection.head().clone(); oldest_selection.start = oldest_selection.head().clone();
oldest_selection.end = oldest_selection.head().clone(); oldest_selection.end = oldest_selection.head().clone();
} }
@ -2294,9 +2286,8 @@ impl Editor {
) -> impl 'a + Iterator<Item = Range<DisplayPoint>> { ) -> impl 'a + Iterator<Item = Range<DisplayPoint>> {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = self.buffer.read(cx); let buffer = self.buffer.read(cx);
let selections = buffer let selections = self
.selection_set(set_id) .selection_set(cx)
.unwrap()
.selections::<Point, _>(buffer) .selections::<Point, _>(buffer)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let start = range.start.to_point(&display_map); let start = range.start.to_point(&display_map);
@ -2343,18 +2334,8 @@ impl Editor {
D: 'a + TextDimension<'a> + Ord, D: 'a + TextDimension<'a> + Ord,
{ {
let buffer = self.buffer.read(cx); let buffer = self.buffer.read(cx);
let mut selections = buffer let mut selections = self.selection_set(cx).selections::<D, _>(buffer).peekable();
.selection_set(self.selection_set_id) let mut pending_selection = self.pending_selection(cx);
.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,
});
iter::from_fn(move || { iter::from_fn(move || {
if let Some(pending) = pending_selection.as_mut() { if let Some(pending) = pending_selection.as_mut() {
while let Some(next_selection) = selections.peek() { 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>( fn update_selections<T>(
&mut self, &mut self,
mut selections: Vec<Selection<T>>, mut selections: Vec<Selection<T>>,

View File

@ -258,11 +258,7 @@ impl DiagnosticMessage {
fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) { fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
let editor = editor.read(cx); let editor = editor.read(cx);
let cursor_position = editor let cursor_position = editor.newest_selection(cx).head();
.selections::<usize>(cx)
.max_by_key(|selection| selection.id)
.unwrap()
.head();
let new_diagnostic = editor let new_diagnostic = editor
.buffer() .buffer()
.read(cx) .read(cx)