Detailed changes
@@ -31,26 +31,26 @@ pub struct AnchorRangeMap<T> {
pub struct AnchorRangeSet(pub(crate) AnchorRangeMap<()>);
pub struct AnchorRangeMultimap<T: Clone> {
- entries: SumTree<AnchorRangeMultimapEntry<T>>,
+ pub(crate) entries: SumTree<AnchorRangeMultimapEntry<T>>,
pub(crate) version: clock::Global,
pub(crate) start_bias: Bias,
pub(crate) end_bias: Bias,
}
#[derive(Clone)]
-struct AnchorRangeMultimapEntry<T> {
- range: FullOffsetRange,
- value: T,
+pub(crate) struct AnchorRangeMultimapEntry<T> {
+ pub(crate) range: FullOffsetRange,
+ pub(crate) value: T,
}
#[derive(Clone, Debug)]
-struct FullOffsetRange {
- start: usize,
- end: usize,
+pub(crate) struct FullOffsetRange {
+ pub(crate) start: usize,
+ pub(crate) end: usize,
}
#[derive(Clone, Debug)]
-struct AnchorRangeMultimapSummary {
+pub(crate) struct AnchorRangeMultimapSummary {
start: usize,
end: usize,
min_start: usize,
@@ -165,46 +165,61 @@ impl AnchorRangeSet {
}
impl<T: Clone> AnchorRangeMultimap<T> {
- fn intersecting_point_ranges<'a, O: ToOffset>(
+ fn intersecting_point_ranges<'a>(
&'a self,
- range: Range<O>,
- content: impl Into<Content<'a>>,
+ range: Range<Anchor>,
+ content: &'a Content<'a>,
inclusive: bool,
) -> impl Iterator<Item = (usize, Range<Point>, &T)> + 'a {
use super::ToPoint as _;
- let content = content.into();
- let start = range.start.to_full_offset(&content, self.start_bias);
- let end = range.end.to_full_offset(&content, self.end_bias);
let mut cursor = self.entries.filter::<_, usize>(
- move |summary: &AnchorRangeMultimapSummary| {
- if inclusive {
- start <= summary.max_end && end >= summary.min_start
- } else {
- start < summary.max_end && end > summary.min_start
+ {
+ let mut endpoint = Anchor {
+ full_offset: 0,
+ bias: Bias::Right,
+ version: self.version.clone(),
+ };
+ move |summary: &AnchorRangeMultimapSummary| {
+ endpoint.full_offset = summary.max_end;
+ endpoint.bias = self.end_bias;
+ let start_cmp = range.start.cmp(&endpoint, content).unwrap();
+
+ endpoint.full_offset = summary.min_start;
+ endpoint.bias = self.start_bias;
+ let end_cmp = range.end.cmp(&endpoint, content).unwrap();
+
+ if inclusive {
+ start_cmp <= Ordering::Equal && end_cmp >= Ordering::Equal
+ } else {
+ start_cmp == Ordering::Less && end_cmp == Ordering::Greater
+ }
}
},
&(),
);
- let mut anchor = Anchor {
- full_offset: 0,
- bias: Bias::Left,
- version: self.version.clone(),
- };
- std::iter::from_fn(move || {
- if let Some(item) = cursor.item() {
- let ix = *cursor.start();
- anchor.full_offset = item.range.start;
- anchor.bias = self.start_bias;
- let start = anchor.to_point(&content);
- anchor.full_offset = item.range.end;
- anchor.bias = self.end_bias;
- let end = anchor.to_point(&content);
- let value = &item.value;
- cursor.next(&());
- Some((ix, start..end, value))
- } else {
- None
+
+ std::iter::from_fn({
+ let mut endpoint = Anchor {
+ full_offset: 0,
+ bias: Bias::Left,
+ version: self.version.clone(),
+ };
+ move || {
+ if let Some(item) = cursor.item() {
+ let ix = *cursor.start();
+ endpoint.full_offset = item.range.start;
+ endpoint.bias = self.start_bias;
+ let start = endpoint.to_point(content);
+ endpoint.full_offset = item.range.end;
+ endpoint.bias = self.end_bias;
+ let end = endpoint.to_point(content);
+ let value = &item.value;
+ cursor.next(&());
+ Some((ix, start..end, value))
+ } else {
+ None
+ }
}
})
}
@@ -20,6 +20,7 @@ use rpc::proto;
pub use selection::*;
use std::{
cmp,
+ collections::{BTreeMap, BTreeSet},
convert::{TryFrom, TryInto},
iter::Iterator,
ops::Range,
@@ -315,7 +316,7 @@ impl UndoMap {
}
}
-struct Edits<'a, F: Fn(&FragmentSummary) -> bool> {
+struct Edits<'a, F: FnMut(&FragmentSummary) -> bool> {
visible_text: &'a Rope,
deleted_text: &'a Rope,
cursor: Option<FilterCursor<'a, F, Fragment, FragmentTextSummary>>,
@@ -1836,6 +1837,56 @@ impl<'a> Content<'a> {
AnchorRangeSet(self.anchor_range_map(entries.into_iter().map(|range| (range, ()))))
}
+ pub fn anchor_range_multimap<T, E, O>(
+ &self,
+ start_bias: Bias,
+ end_bias: Bias,
+ entries: E,
+ ) -> AnchorRangeMultimap<T>
+ where
+ T: Clone,
+ E: IntoIterator<Item = (Range<O>, T)>,
+ O: ToOffset,
+ {
+ let mut items = Vec::new();
+ let mut endpoints = BTreeMap::new();
+ for (ix, (range, value)) in entries.into_iter().enumerate() {
+ items.push(AnchorRangeMultimapEntry {
+ range: FullOffsetRange { start: 0, end: 0 },
+ value,
+ });
+ endpoints
+ .entry((range.start.to_offset(self), start_bias))
+ .or_insert(Vec::new())
+ .push((ix, true));
+ endpoints
+ .entry((range.end.to_offset(self), end_bias))
+ .or_insert(Vec::new())
+ .push((ix, false));
+ }
+
+ let mut cursor = self.fragments.cursor::<FragmentTextSummary>();
+ for ((endpoint, bias), item_ixs) in endpoints {
+ cursor.seek_forward(&endpoint, bias, &None);
+ let full_offset = cursor.start().deleted + endpoint;
+ for (item_ix, is_start) in item_ixs {
+ if is_start {
+ items[item_ix].range.start = full_offset;
+ } else {
+ items[item_ix].range.end = full_offset;
+ }
+ }
+ }
+ items.sort_unstable_by_key(|i| (i.range.start, i.range.end));
+
+ AnchorRangeMultimap {
+ entries: SumTree::from_iter(items, &()),
+ version: self.version.clone(),
+ start_bias,
+ end_bias,
+ }
+ }
+
fn full_offset_for_anchor(&self, anchor: &Anchor) -> usize {
let cx = Some(anchor.version.clone());
let mut cursor = self
@@ -1917,7 +1968,7 @@ impl<'a> RopeBuilder<'a> {
}
}
-impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
+impl<'a, F: FnMut(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
type Item = Edit;
fn next(&mut self) -> Option<Self::Item> {
@@ -720,7 +720,7 @@ fn intersecting_folds<'a, T>(
folds: &'a SumTree<Fold>,
range: Range<T>,
inclusive: bool,
-) -> FilterCursor<'a, impl 'a + Fn(&FoldSummary) -> bool, Fold, usize>
+) -> FilterCursor<'a, impl 'a + FnMut(&FoldSummary) -> bool, Fold, usize>
where
T: ToOffset,
{
@@ -1190,7 +1190,6 @@ impl LocalWorktree {
diagnostics: lsp::PublishDiagnosticsParams,
cx: &mut ModelContext<Worktree>,
) {
- //
}
}
@@ -184,9 +184,9 @@ where
self.next_internal(|_| true, cx)
}
- fn next_internal<F>(&mut self, filter_node: F, cx: &<T::Summary as Summary>::Context)
+ fn next_internal<F>(&mut self, mut filter_node: F, cx: &<T::Summary as Summary>::Context)
where
- F: Fn(&T::Summary) -> bool,
+ F: FnMut(&T::Summary) -> bool,
{
let mut descend = false;
@@ -509,24 +509,24 @@ where
}
}
-pub struct FilterCursor<'a, F: Fn(&T::Summary) -> bool, T: Item, D> {
+pub struct FilterCursor<'a, F: FnMut(&T::Summary) -> bool, T: Item, D> {
cursor: Cursor<'a, T, D>,
filter_node: F,
}
impl<'a, F, T, D> FilterCursor<'a, F, T, D>
where
- F: Fn(&T::Summary) -> bool,
+ F: FnMut(&T::Summary) -> bool,
T: Item,
D: Dimension<'a, T::Summary>,
{
pub fn new(
tree: &'a SumTree<T>,
- filter_node: F,
+ mut filter_node: F,
cx: &<T::Summary as Summary>::Context,
) -> Self {
let mut cursor = tree.cursor::<D>();
- cursor.next_internal(&filter_node, cx);
+ cursor.next_internal(&mut filter_node, cx);
Self {
cursor,
filter_node,
@@ -542,7 +542,7 @@ where
}
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
- self.cursor.next_internal(&self.filter_node, cx);
+ self.cursor.next_internal(&mut self.filter_node, cx);
}
}
@@ -163,7 +163,7 @@ impl<T: Item> SumTree<T> {
cx: &<T::Summary as Summary>::Context,
) -> FilterCursor<F, T, U>
where
- F: Fn(&T::Summary) -> bool,
+ F: FnMut(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>,
{
FilterCursor::new(self, filter_node, cx)