Make resolving selections generic
Co-Authored-By: Nathan Sobo <nathan@zed.dev> Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
a26b066788
commit
9dc3c74260
8 changed files with 113 additions and 133 deletions
|
@ -1,3 +1,5 @@
|
|||
use crate::rope::TextDimension;
|
||||
|
||||
use super::{Buffer, Content, FromAnchor, FullOffset, Point, ToOffset};
|
||||
use anyhow::Result;
|
||||
use std::{
|
||||
|
@ -183,31 +185,22 @@ impl<T> AnchorRangeMap<T> {
|
|||
Self { version, entries }
|
||||
}
|
||||
|
||||
pub fn ranges<'a, D>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl Iterator<Item = (Range<D>, &'a T)> + 'a
|
||||
where
|
||||
D: 'a + TextDimension<'a>,
|
||||
{
|
||||
let content = content.into();
|
||||
content.summaries_for_anchor_ranges(self)
|
||||
}
|
||||
|
||||
pub fn full_offset_ranges(&self) -> impl Iterator<Item = (Range<FullOffset>, &T)> {
|
||||
self.entries
|
||||
.iter()
|
||||
.map(|(range, value)| (range.start.0..range.end.0, value))
|
||||
}
|
||||
|
||||
pub fn point_ranges<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl Iterator<Item = (Range<Point>, &'a T)> + 'a {
|
||||
let content = content.into();
|
||||
content
|
||||
.summaries_for_anchor_ranges(self)
|
||||
.map(move |(range, value)| ((range.start.lines..range.end.lines), value))
|
||||
}
|
||||
|
||||
pub fn offset_ranges<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl Iterator<Item = (Range<usize>, &'a T)> + 'a {
|
||||
let content = content.into();
|
||||
content
|
||||
.summaries_for_anchor_ranges(self)
|
||||
.map(move |(range, value)| ((range.start.bytes..range.end.bytes), value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> PartialEq for AnchorRangeMap<T> {
|
||||
|
@ -248,18 +241,12 @@ impl AnchorRangeSet {
|
|||
self.0.version()
|
||||
}
|
||||
|
||||
pub fn offset_ranges<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl Iterator<Item = Range<usize>> + 'a {
|
||||
self.0.offset_ranges(content).map(|(range, _)| range)
|
||||
}
|
||||
|
||||
pub fn point_ranges<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl Iterator<Item = Range<Point>> + 'a {
|
||||
self.0.point_ranges(content).map(|(range, _)| range)
|
||||
pub fn ranges<'a, D, C>(&'a self, content: C) -> impl 'a + Iterator<Item = Range<Point>>
|
||||
where
|
||||
D: 'a + TextDimension<'a>,
|
||||
C: 'a + Into<Content<'a>>,
|
||||
{
|
||||
self.0.ranges(content).map(|(range, _)| range)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1486,10 +1486,14 @@ impl Buffer {
|
|||
Ok(selections)
|
||||
}
|
||||
|
||||
pub fn selection_ranges<'a>(&'a self, set_id: SelectionSetId) -> Result<Vec<Range<usize>>> {
|
||||
#[cfg(test)]
|
||||
pub fn selection_ranges<'a, D>(&'a self, set_id: SelectionSetId) -> Result<Vec<Range<D>>>
|
||||
where
|
||||
D: 'a + TextDimension<'a>,
|
||||
{
|
||||
Ok(self
|
||||
.selection_set(set_id)?
|
||||
.offset_selections(self)
|
||||
.selections(self)
|
||||
.map(move |selection| {
|
||||
if selection.reversed {
|
||||
selection.end..selection.start
|
||||
|
@ -1500,9 +1504,13 @@ impl Buffer {
|
|||
.collect())
|
||||
}
|
||||
|
||||
pub fn all_selection_ranges<'a>(
|
||||
#[cfg(test)]
|
||||
pub fn all_selection_ranges<'a, D>(
|
||||
&'a self,
|
||||
) -> impl 'a + Iterator<Item = (SelectionSetId, Vec<Range<usize>>)> {
|
||||
) -> impl 'a + Iterator<Item = (SelectionSetId, Vec<Range<usize>>)>
|
||||
where
|
||||
D: 'a + TextDimension<'a>,
|
||||
{
|
||||
self.selections
|
||||
.keys()
|
||||
.map(move |set_id| (*set_id, self.selection_ranges(*set_id).unwrap()))
|
||||
|
@ -1751,12 +1759,15 @@ impl<'a> Content<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn summaries_for_anchor_ranges<T>(
|
||||
fn summaries_for_anchor_ranges<D, T>(
|
||||
&self,
|
||||
map: &'a AnchorRangeMap<T>,
|
||||
) -> impl Iterator<Item = (Range<TextSummary>, &'a T)> {
|
||||
) -> impl Iterator<Item = (Range<D>, &'a T)>
|
||||
where
|
||||
D: TextDimension<'a>,
|
||||
{
|
||||
let cx = Some(map.version.clone());
|
||||
let mut summary = TextSummary::default();
|
||||
let mut summary = D::default();
|
||||
let mut rope_cursor = self.visible_text.cursor(0);
|
||||
let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
|
||||
map.entries.iter().map(move |(range, value)| {
|
||||
|
@ -1775,7 +1786,7 @@ impl<'a> Content<'a> {
|
|||
} else {
|
||||
0
|
||||
};
|
||||
summary += rope_cursor.summary::<TextSummary>(cursor.start().1 + overshoot);
|
||||
summary.add_assign(&rope_cursor.summary::<D>(cursor.start().1 + overshoot));
|
||||
let start_summary = summary.clone();
|
||||
|
||||
cursor.seek_forward(&VersionedFullOffset::Offset(*end_offset), *end_bias, &cx);
|
||||
|
@ -1784,7 +1795,7 @@ impl<'a> Content<'a> {
|
|||
} else {
|
||||
0
|
||||
};
|
||||
summary += rope_cursor.summary::<TextSummary>(cursor.start().1 + overshoot);
|
||||
summary.add_assign(&rope_cursor.summary::<D>(cursor.start().1 + overshoot));
|
||||
let end_summary = summary.clone();
|
||||
|
||||
(start_summary..end_summary, value)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::rope::TextDimension;
|
||||
|
||||
use super::{AnchorRangeMap, Buffer, Content, Point, ToOffset, ToPoint};
|
||||
use std::{cmp::Ordering, ops::Range, sync::Arc};
|
||||
|
||||
|
@ -97,27 +99,13 @@ impl SelectionSet {
|
|||
self.selections.len()
|
||||
}
|
||||
|
||||
pub fn offset_selections<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl 'a + Iterator<Item = Selection<usize>> {
|
||||
pub fn selections<'a, D, C>(&'a self, content: C) -> impl 'a + Iterator<Item = Selection<D>>
|
||||
where
|
||||
D: 'a + TextDimension<'a>,
|
||||
C: 'a + Into<Content<'a>>,
|
||||
{
|
||||
self.selections
|
||||
.offset_ranges(content)
|
||||
.map(|(range, state)| Selection {
|
||||
id: state.id,
|
||||
start: range.start,
|
||||
end: range.end,
|
||||
reversed: state.reversed,
|
||||
goal: state.goal,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn point_selections<'a>(
|
||||
&'a self,
|
||||
content: impl Into<Content<'a>> + 'a,
|
||||
) -> impl 'a + Iterator<Item = Selection<Point>> {
|
||||
self.selections
|
||||
.point_ranges(content)
|
||||
.ranges(content)
|
||||
.map(|(range, state)| Selection {
|
||||
id: state.id,
|
||||
start: range.start,
|
||||
|
|
|
@ -576,9 +576,11 @@ fn test_random_concurrent_edits(mut rng: StdRng) {
|
|||
first_buffer.selection_sets().collect::<HashMap<_, _>>()
|
||||
);
|
||||
assert_eq!(
|
||||
buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
|
||||
buffer
|
||||
.all_selection_ranges::<usize>()
|
||||
.collect::<HashMap<_, _>>(),
|
||||
first_buffer
|
||||
.all_selection_ranges()
|
||||
.all_selection_ranges::<usize>()
|
||||
.collect::<HashMap<_, _>>()
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue