diff --git a/crates/channel/src/channel_chat.rs b/crates/channel/src/channel_chat.rs index 286eb46a91..1a9e46db04 100644 --- a/crates/channel/src/channel_chat.rs +++ b/crates/channel/src/channel_chat.rs @@ -332,7 +332,7 @@ impl ChannelChat { .update(&mut cx, |chat, cx| { if let Some(first_id) = chat.first_loaded_message_id() { if first_id <= message_id { - let mut cursor = chat.messages.cursor::<(ChannelMessageId, Count)>(); + let mut cursor = chat.messages.cursor::<(ChannelMessageId, Count)>(&()); let message_id = ChannelMessageId::Saved(message_id); cursor.seek(&message_id, Bias::Left, &()); return ControlFlow::Break( @@ -498,7 +498,7 @@ impl ChannelChat { } pub fn message(&self, ix: usize) -> &ChannelMessage { - let mut cursor = self.messages.cursor::(); + let mut cursor = self.messages.cursor::(&()); cursor.seek(&Count(ix), Bias::Right, &()); cursor.item().unwrap() } @@ -515,13 +515,13 @@ impl ChannelChat { } pub fn messages_in_range(&self, range: Range) -> impl Iterator { - let mut cursor = self.messages.cursor::(); + let mut cursor = self.messages.cursor::(&()); cursor.seek(&Count(range.start), Bias::Right, &()); cursor.take(range.len()) } pub fn pending_messages(&self) -> impl Iterator { - let mut cursor = self.messages.cursor::(); + let mut cursor = self.messages.cursor::(&()); cursor.seek(&ChannelMessageId::Pending(0), Bias::Left, &()); cursor } @@ -589,11 +589,11 @@ impl ChannelChat { fn insert_messages(&mut self, messages: SumTree, cx: &mut ModelContext) { if let Some((first_message, last_message)) = messages.first().zip(messages.last()) { let nonces = messages - .cursor::<()>() + .cursor::<()>(&()) .map(|m| m.nonce) .collect::>(); - let mut old_cursor = self.messages.cursor::<(ChannelMessageId, Count)>(); + let mut old_cursor = self.messages.cursor::<(ChannelMessageId, Count)>(&()); let mut new_messages = old_cursor.slice(&first_message.id, Bias::Left, &()); let start_ix = old_cursor.start().1 .0; let removed_messages = old_cursor.slice(&last_message.id, Bias::Right, &()); @@ -646,7 +646,7 @@ impl ChannelChat { } fn message_removed(&mut self, id: u64, cx: &mut ModelContext) { - let mut cursor = self.messages.cursor::(); + let mut cursor = self.messages.cursor::(&()); let mut messages = cursor.slice(&ChannelMessageId::Saved(id), Bias::Left, &()); if let Some(item) = cursor.item() { if item.id == ChannelMessageId::Saved(id) { @@ -685,7 +685,7 @@ impl ChannelChat { edited_at: Option, cx: &mut ModelContext, ) { - let mut cursor = self.messages.cursor::(); + let mut cursor = self.messages.cursor::(&()); let mut messages = cursor.slice(&id, Bias::Left, &()); let ix = messages.summary().count; @@ -716,7 +716,7 @@ async fn messages_from_proto( cx: &mut AsyncAppContext, ) -> Result> { let messages = ChannelMessage::from_proto_vec(proto_messages, user_store, cx).await?; - let mut result = SumTree::new(); + let mut result = SumTree::default(); result.extend(messages, &()); Ok(result) } @@ -825,6 +825,10 @@ impl Default for ChannelMessageId { impl sum_tree::Summary for ChannelMessageSummary { type Context = (); + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.max_id = summary.max_id; self.count += summary.count; @@ -832,6 +836,10 @@ impl sum_tree::Summary for ChannelMessageSummary { } impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for ChannelMessageId { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) { debug_assert!(summary.max_id > *self); *self = summary.max_id; @@ -839,6 +847,10 @@ impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for ChannelMessageId { } impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for Count { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) { self.0 += summary.count; } diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 86ea7ee3fa..790a0a6a1e 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -127,7 +127,9 @@ impl DisplayMap { let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe()); let tab_size = Self::tab_size(&buffer, cx); - let (inlay_map, snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx)); + let buffer_snapshot = buffer.read(cx).snapshot(cx); + let crease_map = CreaseMap::new(&buffer_snapshot); + let (inlay_map, snapshot) = InlayMap::new(buffer_snapshot); let (fold_map, snapshot) = FoldMap::new(snapshot); let (tab_map, snapshot) = TabMap::new(snapshot, tab_size); let (wrap_map, snapshot) = WrapMap::new(snapshot, font, font_size, wrap_width, cx); @@ -138,7 +140,6 @@ impl DisplayMap { excerpt_header_height, excerpt_footer_height, ); - let crease_map = CreaseMap::default(); cx.observe(&wrap_map, |_, _, cx| cx.notify()).detach(); diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 28e0b9d7af..3a298832de 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -389,10 +389,10 @@ impl BlockMap { } let mut transforms = self.transforms.borrow_mut(); - let mut new_transforms = SumTree::new(); + let mut new_transforms = SumTree::default(); let old_row_count = transforms.summary().input_rows; let new_row_count = wrap_snapshot.max_point().row() + 1; - let mut cursor = transforms.cursor::(); + let mut cursor = transforms.cursor::(&()); let mut last_block_ix = 0; let mut blocks_in_edit = Vec::new(); let mut edits = edits.into_iter().peekable(); @@ -757,7 +757,7 @@ impl<'a> BlockMapReader<'a> { .unwrap_or(self.wrap_snapshot.max_point().row() + 1), ); - let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(); + let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(&()); cursor.seek(&start_wrap_row, Bias::Left, &()); while let Some(transform) = cursor.item() { if cursor.start().0 > end_wrap_row { @@ -950,7 +950,7 @@ impl BlockSnapshot { highlights: Highlights<'a>, ) -> BlockChunks<'a> { let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); let input_end = { cursor.seek(&BlockRow(rows.end), Bias::Right, &()); let overshoot = if cursor @@ -990,7 +990,7 @@ impl BlockSnapshot { } pub(super) fn buffer_rows(&self, start_row: BlockRow) -> BlockBufferRows { - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); cursor.seek(&start_row, Bias::Right, &()); let (output_start, input_start) = cursor.start(); let overshoot = if cursor.item().map_or(false, |t| t.is_isomorphic()) { @@ -1008,7 +1008,7 @@ impl BlockSnapshot { } pub fn blocks_in_range(&self, rows: Range) -> impl Iterator { - let mut cursor = self.transforms.cursor::(); + let mut cursor = self.transforms.cursor::(&()); cursor.seek(&BlockRow(rows.start), Bias::Left, &()); while cursor.start().0 < rows.start && cursor.end(&()).0 <= rows.start { cursor.next(&()); @@ -1050,7 +1050,7 @@ impl BlockSnapshot { let wrap_point = self .wrap_snapshot .make_wrap_point(excerpt_range.start, Bias::Left); - let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(); + let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(&()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Left, &()); while let Some(transform) = cursor.item() { if let Some(block) = transform.block.as_ref() { @@ -1072,7 +1072,7 @@ impl BlockSnapshot { .wrap_snapshot .make_wrap_point(excerpt_range.end, Bias::Left); - let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(); + let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(&()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Left, &()); while let Some(transform) = cursor.item() { if let Some(block) = transform.block.as_ref() { @@ -1102,7 +1102,7 @@ impl BlockSnapshot { } pub(super) fn line_len(&self, row: BlockRow) -> u32 { - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); cursor.seek(&BlockRow(row.0), Bias::Right, &()); if let Some(transform) = cursor.item() { let (output_start, input_start) = cursor.start(); @@ -1118,13 +1118,13 @@ impl BlockSnapshot { } pub(super) fn is_block_line(&self, row: BlockRow) -> bool { - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); cursor.seek(&row, Bias::Right, &()); cursor.item().map_or(false, |t| t.block.is_some()) } pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint { - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); cursor.seek(&BlockRow(point.row), Bias::Right, &()); let max_input_row = WrapRow(self.transforms.summary().input_rows); @@ -1172,7 +1172,7 @@ impl BlockSnapshot { } pub fn to_block_point(&self, wrap_point: WrapPoint) -> BlockPoint { - let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(); + let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(&()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Right, &()); if let Some(transform) = cursor.item() { debug_assert!(transform.is_isomorphic()); @@ -1188,7 +1188,7 @@ impl BlockSnapshot { } pub fn to_wrap_point(&self, block_point: BlockPoint) -> WrapPoint { - let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); + let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&()); cursor.seek(&BlockRow(block_point.row), Bias::Right, &()); if let Some(transform) = cursor.item() { match transform.block.as_ref().map(|b| b.disposition()) { @@ -1368,6 +1368,10 @@ impl sum_tree::Item for Transform { impl sum_tree::Summary for TransformSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.input_rows += summary.input_rows; self.output_rows += summary.output_rows; @@ -1375,12 +1379,20 @@ impl sum_tree::Summary for TransformSummary { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapRow { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += summary.input_rows; } } impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += summary.output_rows; } diff --git a/crates/editor/src/display_map/crease_map.rs b/crates/editor/src/display_map/crease_map.rs index 10ee125b32..bfc9c7d1a4 100644 --- a/crates/editor/src/display_map/crease_map.rs +++ b/crates/editor/src/display_map/crease_map.rs @@ -12,19 +12,34 @@ use crate::FoldPlaceholder; #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct CreaseId(usize); -#[derive(Default)] pub struct CreaseMap { snapshot: CreaseSnapshot, next_id: CreaseId, id_to_range: HashMap>, } -#[derive(Clone, Default)] +impl CreaseMap { + pub fn new(snapshot: &MultiBufferSnapshot) -> Self { + CreaseMap { + snapshot: CreaseSnapshot::new(snapshot), + next_id: CreaseId::default(), + id_to_range: HashMap::default(), + } + } +} + +#[derive(Clone)] pub struct CreaseSnapshot { creases: SumTree, } impl CreaseSnapshot { + pub fn new(snapshot: &MultiBufferSnapshot) -> Self { + CreaseSnapshot { + creases: SumTree::new(snapshot), + } + } + /// Returns the first Crease starting on the specified buffer row. pub fn query_row<'a>( &'a self, @@ -32,7 +47,7 @@ impl CreaseSnapshot { snapshot: &'a MultiBufferSnapshot, ) -> Option<&'a Crease> { let start = snapshot.anchor_before(Point::new(row.0, 0)); - let mut cursor = self.creases.cursor::(); + let mut cursor = self.creases.cursor::(snapshot); cursor.seek(&start, Bias::Left, snapshot); while let Some(item) = cursor.item() { match Ord::cmp(&item.crease.range.start.to_point(snapshot).row, &row.0) { @@ -56,7 +71,7 @@ impl CreaseSnapshot { snapshot: &'a MultiBufferSnapshot, ) -> impl '_ + Iterator { let start = snapshot.anchor_before(Point::new(range.start.0, 0)); - let mut cursor = self.creases.cursor::(); + let mut cursor = self.creases.cursor::(snapshot); cursor.seek(&start, Bias::Left, snapshot); std::iter::from_fn(move || { @@ -79,7 +94,7 @@ impl CreaseSnapshot { &self, snapshot: &MultiBufferSnapshot, ) -> Vec<(CreaseId, Range)> { - let mut cursor = self.creases.cursor::(); + let mut cursor = self.creases.cursor::(snapshot); let mut results = Vec::new(); cursor.next(snapshot); @@ -194,8 +209,8 @@ impl CreaseMap { ) -> Vec { let mut new_ids = Vec::new(); self.snapshot.creases = { - let mut new_creases = SumTree::new(); - let mut cursor = self.snapshot.creases.cursor::(); + let mut new_creases = SumTree::new(snapshot); + let mut cursor = self.snapshot.creases.cursor::(snapshot); for crease in creases { new_creases.append(cursor.slice(&crease.range, Bias::Left, snapshot), snapshot); @@ -227,8 +242,8 @@ impl CreaseMap { }); self.snapshot.creases = { - let mut new_creases = SumTree::new(); - let mut cursor = self.snapshot.creases.cursor::(); + let mut new_creases = SumTree::new(snapshot); + let mut cursor = self.snapshot.creases.cursor::(snapshot); for (id, range) in removals { new_creases.append(cursor.slice(&range, Bias::Left, snapshot), snapshot); @@ -264,6 +279,10 @@ impl Default for ItemSummary { impl sum_tree::Summary for ItemSummary { type Context = MultiBufferSnapshot; + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _snapshot: &MultiBufferSnapshot) { self.range = other.range.clone(); } @@ -303,7 +322,7 @@ mod test { let text = "line1\nline2\nline3\nline4\nline5"; let buffer = MultiBuffer::build_simple(text, cx); let snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); - let mut crease_map = CreaseMap::default(); + let mut crease_map = CreaseMap::new(&buffer.read(cx).read(cx)); // Insert creases let creases = [ @@ -350,7 +369,7 @@ mod test { let text = "line1\nline2\nline3\nline4\nline5\nline6\nline7"; let buffer = MultiBuffer::build_simple(text, cx); let snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); - let mut crease_map = CreaseMap::default(); + let mut crease_map = CreaseMap::new(&snapshot); let creases = [ Crease::new( diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index 486fe4b2e5..37983030b8 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -79,7 +79,7 @@ impl FoldPoint { } pub fn to_inlay_point(self, snapshot: &FoldSnapshot) -> InlayPoint { - let mut cursor = snapshot.transforms.cursor::<(FoldPoint, InlayPoint)>(); + let mut cursor = snapshot.transforms.cursor::<(FoldPoint, InlayPoint)>(&()); cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().0 .0; InlayPoint(cursor.start().1 .0 + overshoot) @@ -88,7 +88,7 @@ impl FoldPoint { pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset { let mut cursor = snapshot .transforms - .cursor::<(FoldPoint, TransformSummary)>(); + .cursor::<(FoldPoint, TransformSummary)>(&()); cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().1.output.lines; let mut offset = cursor.start().1.output.len; @@ -105,6 +105,10 @@ impl FoldPoint { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.output.lines; } @@ -154,8 +158,8 @@ impl<'a> FoldMapWriter<'a> { folds.sort_unstable_by(|a, b| sum_tree::SeekTarget::cmp(&a.range, &b.range, buffer)); self.0.snapshot.folds = { - let mut new_tree = SumTree::new(); - let mut cursor = self.0.snapshot.folds.cursor::(); + let mut new_tree = SumTree::new(buffer); + let mut cursor = self.0.snapshot.folds.cursor::(buffer); for fold in folds { new_tree.append(cursor.slice(&fold.range, Bias::Right, buffer), buffer); new_tree.push(fold, buffer); @@ -202,8 +206,8 @@ impl<'a> FoldMapWriter<'a> { fold_ixs_to_delete.dedup(); self.0.snapshot.folds = { - let mut cursor = self.0.snapshot.folds.cursor::(); - let mut folds = SumTree::new(); + let mut cursor = self.0.snapshot.folds.cursor::(buffer); + let mut folds = SumTree::new(buffer); for fold_ix in fold_ixs_to_delete { folds.append(cursor.slice(&fold_ix, Bias::Right, buffer), buffer); cursor.next(buffer); @@ -230,7 +234,7 @@ impl FoldMap { pub(crate) fn new(inlay_snapshot: InlaySnapshot) -> (Self, FoldSnapshot) { let this = Self { snapshot: FoldSnapshot { - folds: Default::default(), + folds: SumTree::new(&inlay_snapshot.buffer), transforms: SumTree::from_item( Transform { summary: TransformSummary { @@ -314,8 +318,8 @@ impl FoldMap { } else { let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable(); - let mut new_transforms = SumTree::::new(); - let mut cursor = self.snapshot.transforms.cursor::(); + let mut new_transforms = SumTree::::default(); + let mut cursor = self.snapshot.transforms.cursor::(&()); cursor.seek(&InlayOffset(0), Bias::Right, &()); while let Some(mut edit) = inlay_edits_iter.next() { @@ -367,7 +371,10 @@ impl FoldMap { let anchor = inlay_snapshot .buffer .anchor_before(inlay_snapshot.to_buffer_offset(edit.new.start)); - let mut folds_cursor = self.snapshot.folds.cursor::(); + let mut folds_cursor = self + .snapshot + .folds + .cursor::(&inlay_snapshot.buffer); folds_cursor.seek( &FoldRange(anchor..Anchor::max()), Bias::Left, @@ -470,8 +477,8 @@ impl FoldMap { let mut old_transforms = self .snapshot .transforms - .cursor::<(InlayOffset, FoldOffset)>(); - let mut new_transforms = new_transforms.cursor::<(InlayOffset, FoldOffset)>(); + .cursor::<(InlayOffset, FoldOffset)>(&()); + let mut new_transforms = new_transforms.cursor::<(InlayOffset, FoldOffset)>(&()); for mut edit in inlay_edits { old_transforms.seek(&edit.old.start, Bias::Left, &()); @@ -545,7 +552,7 @@ impl FoldSnapshot { pub fn text_summary_for_range(&self, range: Range) -> TextSummary { let mut summary = TextSummary::default(); - let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(); + let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(&()); cursor.seek(&range.start, Bias::Right, &()); if let Some(transform) = cursor.item() { let start_in_transform = range.start.0 - cursor.start().0 .0; @@ -594,7 +601,7 @@ impl FoldSnapshot { } pub fn to_fold_point(&self, point: InlayPoint, bias: Bias) -> FoldPoint { - let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>(); + let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>(&()); cursor.seek(&point, Bias::Right, &()); if cursor.item().map_or(false, |t| t.is_fold()) { if bias == Bias::Left || point == cursor.start().0 { @@ -631,7 +638,7 @@ impl FoldSnapshot { } let fold_point = FoldPoint::new(start_row, 0); - let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(); + let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(&()); cursor.seek(&fold_point, Bias::Left, &()); let overshoot = fold_point.0 - cursor.start().0 .0; @@ -672,7 +679,7 @@ impl FoldSnapshot { { let buffer_offset = offset.to_offset(&self.inlay_snapshot.buffer); let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset); - let mut cursor = self.transforms.cursor::(); + let mut cursor = self.transforms.cursor::(&()); cursor.seek(&inlay_offset, Bias::Right, &()); cursor.item().map_or(false, |t| t.placeholder.is_some()) } @@ -681,7 +688,7 @@ impl FoldSnapshot { let mut inlay_point = self .inlay_snapshot .to_inlay_point(Point::new(buffer_row.0, 0)); - let mut cursor = self.transforms.cursor::(); + let mut cursor = self.transforms.cursor::(&()); cursor.seek(&inlay_point, Bias::Right, &()); loop { match cursor.item() { @@ -711,7 +718,7 @@ impl FoldSnapshot { language_aware: bool, highlights: Highlights<'a>, ) -> FoldChunks<'a> { - let mut transform_cursor = self.transforms.cursor::<(FoldOffset, InlayOffset)>(); + let mut transform_cursor = self.transforms.cursor::<(FoldOffset, InlayOffset)>(&()); transform_cursor.seek(&range.start, Bias::Right, &()); let inlay_start = { @@ -766,7 +773,7 @@ impl FoldSnapshot { } pub fn clip_point(&self, point: FoldPoint, bias: Bias) -> FoldPoint { - let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(); + let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>(&()); cursor.seek(&point, Bias::Right, &()); if let Some(transform) = cursor.item() { let transform_start = cursor.start().0 .0; @@ -826,7 +833,7 @@ where let buffer = &inlay_snapshot.buffer; let start = buffer.anchor_before(range.start.to_offset(buffer)); let end = buffer.anchor_after(range.end.to_offset(buffer)); - let mut cursor = folds.filter::<_, usize>(move |summary| { + let mut cursor = folds.filter::<_, usize>(buffer, move |summary| { let start_cmp = start.cmp(&summary.max_end, buffer); let end_cmp = end.cmp(&summary.min_start, buffer); @@ -945,6 +952,10 @@ impl sum_tree::Item for Transform { impl sum_tree::Summary for TransformSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { self.input += &other.input; self.output += &other.output; @@ -1028,6 +1039,10 @@ impl Default for FoldSummary { impl sum_tree::Summary for FoldSummary { type Context = MultiBufferSnapshot; + fn zero(_cx: &MultiBufferSnapshot) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less { self.min_start = other.min_start; @@ -1052,6 +1067,10 @@ impl sum_tree::Summary for FoldSummary { } impl<'a> sum_tree::Dimension<'a, FoldSummary> for FoldRange { + fn zero(_cx: &MultiBufferSnapshot) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a FoldSummary, _: &MultiBufferSnapshot) { self.0.start = summary.start; self.0.end = summary.end; @@ -1065,6 +1084,10 @@ impl<'a> sum_tree::SeekTarget<'a, FoldSummary, FoldRange> for FoldRange { } impl<'a> sum_tree::Dimension<'a, FoldSummary> for usize { + fn zero(_cx: &MultiBufferSnapshot) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a FoldSummary, _: &MultiBufferSnapshot) { *self += summary.count; } @@ -1196,7 +1219,7 @@ impl FoldOffset { pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint { let mut cursor = snapshot .transforms - .cursor::<(FoldOffset, TransformSummary)>(); + .cursor::<(FoldOffset, TransformSummary)>(&()); cursor.seek(&self, Bias::Right, &()); let overshoot = if cursor.item().map_or(true, |t| t.is_fold()) { Point::new(0, (self.0 - cursor.start().0 .0) as u32) @@ -1210,7 +1233,7 @@ impl FoldOffset { #[cfg(test)] pub fn to_inlay_offset(self, snapshot: &FoldSnapshot) -> InlayOffset { - let mut cursor = snapshot.transforms.cursor::<(FoldOffset, InlayOffset)>(); + let mut cursor = snapshot.transforms.cursor::<(FoldOffset, InlayOffset)>(&()); cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().0 .0; InlayOffset(cursor.start().1 .0 + overshoot) @@ -1240,18 +1263,30 @@ impl Sub for FoldOffset { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldOffset { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.output.len; } } impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.input.lines; } } impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.input.len; } diff --git a/crates/editor/src/display_map/inlay_map.rs b/crates/editor/src/display_map/inlay_map.rs index b6ab2cdd28..712db45e3f 100644 --- a/crates/editor/src/display_map/inlay_map.rs +++ b/crates/editor/src/display_map/inlay_map.rs @@ -97,6 +97,10 @@ struct TransformSummary { impl sum_tree::Summary for TransformSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { self.input += &other.input; self.output += &other.output; @@ -137,6 +141,10 @@ impl SubAssign for InlayOffset { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.output.len; } @@ -162,18 +170,30 @@ impl Sub for InlayPoint { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += &summary.output.lines; } } impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { *self += &summary.input.len; } } impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { *self += &summary.input.lines; } @@ -475,8 +495,8 @@ impl InlayMap { (snapshot.clone(), Vec::new()) } else { let mut inlay_edits = Patch::default(); - let mut new_transforms = SumTree::new(); - let mut cursor = snapshot.transforms.cursor::<(usize, InlayOffset)>(); + let mut new_transforms = SumTree::default(); + let mut cursor = snapshot.transforms.cursor::<(usize, InlayOffset)>(&()); let mut buffer_edits_iter = buffer_edits.iter().peekable(); while let Some(buffer_edit) = buffer_edits_iter.next() { new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left, &()), &()); @@ -693,7 +713,7 @@ impl InlaySnapshot { pub fn to_point(&self, offset: InlayOffset) -> InlayPoint { let mut cursor = self .transforms - .cursor::<(InlayOffset, (InlayPoint, usize))>(); + .cursor::<(InlayOffset, (InlayPoint, usize))>(&()); cursor.seek(&offset, Bias::Right, &()); let overshoot = offset.0 - cursor.start().0 .0; match cursor.item() { @@ -723,7 +743,7 @@ impl InlaySnapshot { pub fn to_offset(&self, point: InlayPoint) -> InlayOffset { let mut cursor = self .transforms - .cursor::<(InlayPoint, (InlayOffset, Point))>(); + .cursor::<(InlayPoint, (InlayOffset, Point))>(&()); cursor.seek(&point, Bias::Right, &()); let overshoot = point.0 - cursor.start().0 .0; match cursor.item() { @@ -741,9 +761,8 @@ impl InlaySnapshot { None => self.len(), } } - pub fn to_buffer_point(&self, point: InlayPoint) -> Point { - let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(); + let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(&()); cursor.seek(&point, Bias::Right, &()); match cursor.item() { Some(Transform::Isomorphic(_)) => { @@ -754,9 +773,8 @@ impl InlaySnapshot { None => self.buffer.max_point(), } } - pub fn to_buffer_offset(&self, offset: InlayOffset) -> usize { - let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(); + let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(&()); cursor.seek(&offset, Bias::Right, &()); match cursor.item() { Some(Transform::Isomorphic(_)) => { @@ -769,7 +787,7 @@ impl InlaySnapshot { } pub fn to_inlay_offset(&self, offset: usize) -> InlayOffset { - let mut cursor = self.transforms.cursor::<(usize, InlayOffset)>(); + let mut cursor = self.transforms.cursor::<(usize, InlayOffset)>(&()); cursor.seek(&offset, Bias::Left, &()); loop { match cursor.item() { @@ -801,9 +819,8 @@ impl InlaySnapshot { } } } - pub fn to_inlay_point(&self, point: Point) -> InlayPoint { - let mut cursor = self.transforms.cursor::<(Point, InlayPoint)>(); + let mut cursor = self.transforms.cursor::<(Point, InlayPoint)>(&()); cursor.seek(&point, Bias::Left, &()); loop { match cursor.item() { @@ -837,7 +854,7 @@ impl InlaySnapshot { } pub fn clip_point(&self, mut point: InlayPoint, mut bias: Bias) -> InlayPoint { - let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(); + let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(&()); cursor.seek(&point, Bias::Left, &()); loop { match cursor.item() { @@ -934,7 +951,7 @@ impl InlaySnapshot { pub fn text_summary_for_range(&self, range: Range) -> TextSummary { let mut summary = TextSummary::default(); - let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(); + let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(&()); cursor.seek(&range.start, Bias::Right, &()); let overshoot = range.start.0 - cursor.start().0 .0; @@ -982,7 +999,7 @@ impl InlaySnapshot { } pub fn buffer_rows(&self, row: u32) -> InlayBufferRows<'_> { - let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(); + let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>(&()); let inlay_point = InlayPoint::new(row, 0); cursor.seek(&inlay_point, Bias::Left, &()); @@ -1024,7 +1041,7 @@ impl InlaySnapshot { language_aware: bool, highlights: Highlights<'a>, ) -> InlayChunks<'a> { - let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(); + let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(&()); cursor.seek(&range.start, Bias::Right, &()); let mut highlight_endpoints = Vec::new(); diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index 08b2ae0c64..564bba2158 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -204,7 +204,7 @@ impl WrapMap { } } else { let old_rows = self.snapshot.transforms.summary().output.lines.row + 1; - self.snapshot.transforms = SumTree::new(); + self.snapshot.transforms = SumTree::default(); let summary = self.snapshot.tab_snapshot.text_summary(); if !summary.lines.is_zero() { self.snapshot @@ -303,7 +303,7 @@ impl WrapMap { impl WrapSnapshot { fn new(tab_snapshot: TabSnapshot) -> Self { - let mut transforms = SumTree::new(); + let mut transforms = SumTree::default(); let extent = tab_snapshot.text_summary(); if !extent.lines.is_zero() { transforms.push(Transform::isomorphic(extent), &()); @@ -324,7 +324,7 @@ impl WrapSnapshot { if tab_edits.is_empty() { new_transforms = self.transforms.clone(); } else { - let mut old_cursor = self.transforms.cursor::(); + let mut old_cursor = self.transforms.cursor::(&()); let mut tab_edits_iter = tab_edits.iter().peekable(); new_transforms = @@ -424,7 +424,7 @@ impl WrapSnapshot { new_transforms = self.transforms.clone(); } else { let mut row_edits = row_edits.into_iter().peekable(); - let mut old_cursor = self.transforms.cursor::(); + let mut old_cursor = self.transforms.cursor::(&()); new_transforms = old_cursor.slice( &TabPoint::new(row_edits.peek().unwrap().old_rows.start, 0), @@ -537,8 +537,8 @@ impl WrapSnapshot { fn compute_edits(&self, tab_edits: &[TabEdit], new_snapshot: &WrapSnapshot) -> Patch { let mut wrap_edits = Vec::new(); - let mut old_cursor = self.transforms.cursor::(); - let mut new_cursor = new_snapshot.transforms.cursor::(); + let mut old_cursor = self.transforms.cursor::(&()); + let mut new_cursor = new_snapshot.transforms.cursor::(&()); for mut tab_edit in tab_edits.iter().cloned() { tab_edit.old.start.0.column = 0; tab_edit.old.end.0 += Point::new(1, 0); @@ -579,7 +579,7 @@ impl WrapSnapshot { ) -> WrapChunks<'a> { let output_start = WrapPoint::new(rows.start, 0); let output_end = WrapPoint::new(rows.end, 0); - let mut transforms = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut transforms = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); transforms.seek(&output_start, Bias::Right, &()); let mut input_start = TabPoint(transforms.start().1 .0); if transforms.item().map_or(false, |t| t.is_isomorphic()) { @@ -606,7 +606,7 @@ impl WrapSnapshot { } pub fn line_len(&self, row: u32) -> u32 { - let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Left, &()); if cursor .item() @@ -626,7 +626,7 @@ impl WrapSnapshot { } pub fn soft_wrap_indent(&self, row: u32) -> Option { - let mut cursor = self.transforms.cursor::(); + let mut cursor = self.transforms.cursor::(&()); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right, &()); cursor.item().and_then(|transform| { if transform.is_isomorphic() { @@ -642,7 +642,7 @@ impl WrapSnapshot { } pub fn buffer_rows(&self, start_row: u32) -> WrapBufferRows { - let mut transforms = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut transforms = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); transforms.seek(&WrapPoint::new(start_row, 0), Bias::Left, &()); let mut input_row = transforms.start().1.row(); if transforms.item().map_or(false, |t| t.is_isomorphic()) { @@ -662,7 +662,7 @@ impl WrapSnapshot { } pub fn to_tab_point(&self, point: WrapPoint) -> TabPoint { - let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); cursor.seek(&point, Bias::Right, &()); let mut tab_point = cursor.start().1 .0; if cursor.item().map_or(false, |t| t.is_isomorphic()) { @@ -680,14 +680,14 @@ impl WrapSnapshot { } pub fn tab_point_to_wrap_point(&self, point: TabPoint) -> WrapPoint { - let mut cursor = self.transforms.cursor::<(TabPoint, WrapPoint)>(); + let mut cursor = self.transforms.cursor::<(TabPoint, WrapPoint)>(&()); cursor.seek(&point, Bias::Right, &()); WrapPoint(cursor.start().1 .0 + (point.0 - cursor.start().0 .0)) } pub fn clip_point(&self, mut point: WrapPoint, bias: Bias) -> WrapPoint { if bias == Bias::Left { - let mut cursor = self.transforms.cursor::(); + let mut cursor = self.transforms.cursor::(&()); cursor.seek(&point, Bias::Right, &()); if cursor.item().map_or(false, |t| !t.is_isomorphic()) { point = *cursor.start(); @@ -705,7 +705,7 @@ impl WrapSnapshot { *point.column_mut() = 0; - let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); cursor.seek(&point, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -725,7 +725,7 @@ impl WrapSnapshot { pub fn next_row_boundary(&self, mut point: WrapPoint) -> Option { point.0 += Point::new(1, 0); - let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(&()); cursor.seek(&point, Bias::Right, &()); while let Some(transform) = cursor.item() { if transform.is_isomorphic() && cursor.start().1.column() == 0 { @@ -747,7 +747,7 @@ impl WrapSnapshot { ); { - let mut transforms = self.transforms.cursor::<()>().peekable(); + let mut transforms = self.transforms.cursor::<()>(&()).peekable(); while let Some(transform) = transforms.next() { if let Some(next_transform) = transforms.peek() { assert!(transform.is_isomorphic() != next_transform.is_isomorphic()); @@ -982,6 +982,10 @@ impl WrapPoint { impl sum_tree::Summary for TransformSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { self.input += &other.input; self.output += &other.output; @@ -989,6 +993,10 @@ impl sum_tree::Summary for TransformSummary { } impl<'a> sum_tree::Dimension<'a, TransformSummary> for TabPoint { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += summary.input.lines; } @@ -1001,6 +1009,10 @@ impl<'a> sum_tree::SeekTarget<'a, TransformSummary, TransformSummary> for TabPoi } impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapPoint { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { self.0 += summary.output.lines; } diff --git a/crates/editor/src/git/blame.rs b/crates/editor/src/git/blame.rs index 00531ee886..775cbcc379 100644 --- a/crates/editor/src/git/blame.rs +++ b/crates/editor/src/git/blame.rs @@ -37,12 +37,20 @@ impl sum_tree::Item for GitBlameEntry { impl sum_tree::Summary for GitBlameEntrySummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _cx: &()) { self.rows += summary.rows; } } impl<'a> sum_tree::Dimension<'a, GitBlameEntrySummary> for u32 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a GitBlameEntrySummary, _cx: &()) { *self += summary.rows; } @@ -191,7 +199,7 @@ impl GitBlame { ) -> impl 'a + Iterator> { self.sync(cx); - let mut cursor = self.entries.cursor::(); + let mut cursor = self.entries.cursor::(&()); rows.into_iter().map(move |row| { let row = row?; cursor.seek_forward(&row.0, Bias::Right, &()); @@ -249,8 +257,8 @@ impl GitBlame { }) .peekable(); - let mut new_entries = SumTree::new(); - let mut cursor = self.entries.cursor::(); + let mut new_entries = SumTree::default(); + let mut cursor = self.entries.cursor::(&()); while let Some(mut edit) = row_edits.next() { while let Some(next_edit) = row_edits.peek() { diff --git a/crates/git/src/diff.rs b/crates/git/src/diff.rs index eedef199dc..8cc7ee1863 100644 --- a/crates/git/src/diff.rs +++ b/crates/git/src/diff.rs @@ -48,6 +48,10 @@ pub struct DiffHunkSummary { impl sum_tree::Summary for DiffHunkSummary { type Context = text::BufferSnapshot; + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { self.buffer_range.start = self .buffer_range @@ -63,17 +67,11 @@ pub struct BufferDiff { tree: SumTree>, } -impl Default for BufferDiff { - fn default() -> Self { - Self::new() - } -} - impl BufferDiff { - pub fn new() -> BufferDiff { + pub fn new(buffer: &BufferSnapshot) -> BufferDiff { BufferDiff { last_buffer_version: None, - tree: SumTree::new(), + tree: SumTree::new(buffer), } } @@ -97,11 +95,13 @@ impl BufferDiff { range: Range, buffer: &'a BufferSnapshot, ) -> impl 'a + Iterator> { - let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| { - let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); - let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); - !before_start && !after_end - }); + let mut cursor = self + .tree + .filter::<_, DiffHunkSummary>(buffer, move |summary| { + let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); + let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); + !before_start && !after_end + }); let anchor_iter = std::iter::from_fn(move || { cursor.next(buffer); @@ -142,11 +142,13 @@ impl BufferDiff { range: Range, buffer: &'a BufferSnapshot, ) -> impl 'a + Iterator> { - let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| { - let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); - let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); - !before_start && !after_end - }); + let mut cursor = self + .tree + .filter::<_, DiffHunkSummary>(buffer, move |summary| { + let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); + let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); + !before_start && !after_end + }); std::iter::from_fn(move || { cursor.prev(buffer); @@ -171,11 +173,11 @@ impl BufferDiff { #[cfg(test)] fn clear(&mut self, buffer: &text::BufferSnapshot) { self.last_buffer_version = Some(buffer.version().clone()); - self.tree = SumTree::new(); + self.tree = SumTree::new(buffer); } pub async fn update(&mut self, diff_base: &Rope, buffer: &text::BufferSnapshot) { - let mut tree = SumTree::new(); + let mut tree = SumTree::new(buffer); let diff_base_text = diff_base.to_string(); let buffer_text = buffer.as_rope().to_string(); @@ -351,7 +353,7 @@ mod tests { .unindent(); let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text); - let mut diff = BufferDiff::new(); + let mut diff = BufferDiff::new(&buffer); smol::block_on(diff.update(&diff_base_rope, &buffer)); assert_hunks( diff.hunks(&buffer), @@ -412,7 +414,7 @@ mod tests { .unindent(); let buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text); - let mut diff = BufferDiff::new(); + let mut diff = BufferDiff::new(&buffer); smol::block_on(diff.update(&diff_base_rope, &buffer)); assert_eq!(diff.hunks(&buffer).count(), 8); diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index bea8270fa5..d03392867b 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -181,7 +181,7 @@ impl ListState { last_layout_bounds: None, last_padding: None, render_item: Box::new(render_item), - items: SumTree::new(), + items: SumTree::default(), logical_scroll_top: None, alignment, overdraw, @@ -228,7 +228,7 @@ impl ListState { ) { let state = &mut *self.0.borrow_mut(); - let mut old_items = state.items.cursor::(); + let mut old_items = state.items.cursor::(&()); let mut new_items = old_items.slice(&Count(old_range.start), Bias::Right, &()); old_items.seek_forward(&Count(old_range.end), Bias::Right, &()); @@ -297,7 +297,7 @@ impl ListState { scroll_top.item_ix = ix; scroll_top.offset_in_item = px(0.); } else { - let mut cursor = state.items.cursor::(); + let mut cursor = state.items.cursor::(&()); cursor.seek(&Count(ix + 1), Bias::Right, &()); let bottom = cursor.start().height + padding.top; let goal_top = px(0.).max(bottom - height + padding.bottom); @@ -326,7 +326,7 @@ impl ListState { return None; } - let mut cursor = state.items.cursor::<(Count, Height)>(); + let mut cursor = state.items.cursor::<(Count, Height)>(&()); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); let scroll_top = cursor.start().1 .0 + scroll_top.offset_in_item; @@ -348,7 +348,7 @@ impl ListState { impl StateInner { fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range { - let mut cursor = self.items.cursor::(); + let mut cursor = self.items.cursor::(&()); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); let start_y = cursor.start().height + scroll_top.offset_in_item; cursor.seek_forward(&Height(start_y + height), Bias::Left, &()); @@ -378,7 +378,7 @@ impl StateInner { if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max { self.logical_scroll_top = None; } else { - let mut cursor = self.items.cursor::(); + let mut cursor = self.items.cursor::(&()); cursor.seek(&Height(new_scroll_top), Bias::Right, &()); let item_ix = cursor.start().count; let offset_in_item = new_scroll_top - cursor.start().height; @@ -418,7 +418,7 @@ impl StateInner { } fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels { - let mut cursor = self.items.cursor::(); + let mut cursor = self.items.cursor::(&()); cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right, &()); cursor.start().height + logical_scroll_top.offset_in_item } @@ -445,7 +445,7 @@ impl StateInner { AvailableSpace::MinContent, ); - let mut cursor = old_items.cursor::(); + let mut cursor = old_items.cursor::(&()); // Render items after the scroll top, including those in the trailing overdraw cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); @@ -560,7 +560,7 @@ impl StateInner { } let measured_range = cursor.start().0..(cursor.start().0 + measured_items.len()); - let mut cursor = old_items.cursor::(); + let mut cursor = old_items.cursor::(&()); let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right, &()); new_items.extend(measured_items, &()); cursor.seek(&Count(measured_range.end), Bias::Right, &()); @@ -573,7 +573,7 @@ impl StateInner { if !rendered_focused_item { let mut cursor = self .items - .filter::<_, Count>(|summary| summary.has_focus_handles); + .filter::<_, Count>(&(), |summary| summary.has_focus_handles); cursor.next(&()); while let Some(item) = cursor.item() { if item.contains_focused(cx) { @@ -629,7 +629,7 @@ impl StateInner { offset_in_item: autoscroll_bounds.top() - item_origin.y, }); } else if autoscroll_bounds.bottom() > bounds.bottom() { - let mut cursor = self.items.cursor::(); + let mut cursor = self.items.cursor::(&()); cursor.seek(&Count(item.index), Bias::Right, &()); let mut height = bounds.size.height - padding.top - padding.bottom; @@ -883,6 +883,10 @@ impl sum_tree::Item for ListItem { impl sum_tree::Summary for ListItemSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.count += summary.count; self.rendered_count += summary.rendered_count; @@ -893,12 +897,20 @@ impl sum_tree::Summary for ListItemSummary { } impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { self.0 += summary.count; } } impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { self.0 += summary.height; } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 76058ffd9b..43fe1565ac 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -722,7 +722,9 @@ impl Buffer { capability: Capability, ) -> Self { let saved_mtime = file.as_ref().and_then(|file| file.mtime()); - + let snapshot = buffer.snapshot(); + let git_diff = git::diff::BufferDiff::new(&snapshot); + let syntax_map = Mutex::new(SyntaxMap::new(&snapshot)); Self { saved_mtime, saved_version: buffer.version(), @@ -739,10 +741,10 @@ impl Buffer { }) .map(Rope::from), diff_base_version: 0, - git_diff: git::diff::BufferDiff::new(), + git_diff, file, capability, - syntax_map: Mutex::new(SyntaxMap::new()), + syntax_map, parsing_in_background: false, non_text_state_update_count: 0, sync_parse_timeout: Duration::from_millis(1), @@ -809,7 +811,7 @@ impl Buffer { /// Assign a language to the buffer. pub fn set_language(&mut self, language: Option>, cx: &mut ModelContext) { self.non_text_state_update_count += 1; - self.syntax_map.lock().clear(); + self.syntax_map.lock().clear(&self.text); self.language = language; self.reparse(cx); cx.emit(BufferEvent::LanguageChanged); diff --git a/crates/language/src/diagnostic_set.rs b/crates/language/src/diagnostic_set.rs index bc53778d97..c35659d9bb 100644 --- a/crates/language/src/diagnostic_set.rs +++ b/crates/language/src/diagnostic_set.rs @@ -15,7 +15,7 @@ use text::{Anchor, FromAnchor, PointUtf16, ToOffset}; /// The diagnostics are stored in a [`SumTree`], which allows this struct /// to be cheaply copied, and allows for efficient retrieval of the /// diagnostics that intersect a given range of the buffer. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct DiagnosticSet { diagnostics: SumTree>, } @@ -135,7 +135,7 @@ impl DiagnosticSet { { let end_bias = if inclusive { Bias::Right } else { Bias::Left }; let range = buffer.anchor_before(range.start)..buffer.anchor_at(range.end, end_bias); - let mut cursor = self.diagnostics.filter::<_, ()>({ + let mut cursor = self.diagnostics.filter::<_, ()>(buffer, { move |summary: &Summary| { let start_cmp = range.start.cmp(&summary.max_end, buffer); let end_cmp = range.end.cmp(&summary.min_start, buffer); @@ -261,6 +261,10 @@ impl Default for Summary { impl sum_tree::Summary for Summary { type Context = text::BufferSnapshot; + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { if other.min_start.cmp(&self.min_start, buffer).is_lt() { self.min_start = other.min_start; diff --git a/crates/language/src/syntax_map.rs b/crates/language/src/syntax_map.rs index 0cdc166570..daae54fb4d 100644 --- a/crates/language/src/syntax_map.rs +++ b/crates/language/src/syntax_map.rs @@ -18,13 +18,12 @@ use sum_tree::{Bias, SeekTarget, SumTree}; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree}; -#[derive(Default)] pub struct SyntaxMap { snapshot: SyntaxSnapshot, language_registry: Option>, } -#[derive(Clone, Default)] +#[derive(Clone)] pub struct SyntaxSnapshot { layers: SumTree, parsed_version: clock::Global, @@ -212,8 +211,11 @@ struct ByteChunks<'a>(text::Chunks<'a>); pub(crate) struct QueryCursorHandle(Option); impl SyntaxMap { - pub fn new() -> Self { - Self::default() + pub fn new(text: &BufferSnapshot) -> Self { + Self { + snapshot: SyntaxSnapshot::new(text), + language_registry: None, + } } pub fn set_language_registry(&mut self, registry: Arc) { @@ -242,12 +244,21 @@ impl SyntaxMap { self.snapshot = snapshot; } - pub fn clear(&mut self) { - self.snapshot = SyntaxSnapshot::default(); + pub fn clear(&mut self, text: &BufferSnapshot) { + self.snapshot = SyntaxSnapshot::new(text); } } impl SyntaxSnapshot { + fn new(text: &BufferSnapshot) -> Self { + Self { + layers: SumTree::new(text), + parsed_version: clock::Global::default(), + interpolated_version: clock::Global::default(), + language_registry_version: 0, + } + } + pub fn is_empty(&self) -> bool { self.layers.is_empty() } @@ -262,10 +273,10 @@ impl SyntaxSnapshot { return; } - let mut layers = SumTree::new(); + let mut layers = SumTree::new(text); let mut first_edit_ix_for_depth = 0; let mut prev_depth = 0; - let mut cursor = self.layers.cursor::(); + let mut cursor = self.layers.cursor::(text); cursor.next(text); 'outer: loop { @@ -388,7 +399,7 @@ impl SyntaxSnapshot { let mut resolved_injection_ranges = Vec::new(); let mut cursor = self .layers - .filter::<_, ()>(|summary| summary.contains_unknown_injections); + .filter::<_, ()>(text, |summary| summary.contains_unknown_injections); cursor.next(text); while let Some(layer) = cursor.item() { let SyntaxLayerContent::Pending { language_name } = &layer.content else { @@ -430,9 +441,9 @@ impl SyntaxSnapshot { log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges); let max_depth = self.layers.summary().max_depth; - let mut cursor = self.layers.cursor::(); + let mut cursor = self.layers.cursor::(text); cursor.next(text); - let mut layers = SumTree::new(); + let mut layers = SumTree::new(text); let mut changed_regions = ChangeRegionSet::default(); let mut queue = BinaryHeap::new(); @@ -823,7 +834,7 @@ impl SyntaxSnapshot { let start = buffer.anchor_before(start_offset); let end = buffer.anchor_after(end_offset); - let mut cursor = self.layers.filter::<_, ()>(move |summary| { + let mut cursor = self.layers.filter::<_, ()>(buffer, move |summary| { if summary.max_depth > summary.min_depth { true } else { @@ -1666,6 +1677,10 @@ impl Default for SyntaxLayerSummary { impl sum_tree::Summary for SyntaxLayerSummary { type Context = BufferSnapshot; + fn zero(_cx: &BufferSnapshot) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { if other.max_depth > self.max_depth { self.max_depth = other.max_depth; diff --git a/crates/language/src/syntax_map/syntax_map_tests.rs b/crates/language/src/syntax_map/syntax_map_tests.rs index 6f42252da5..f6d27bcbd2 100644 --- a/crates/language/src/syntax_map/syntax_map_tests.rs +++ b/crates/language/src/syntax_map/syntax_map_tests.rs @@ -103,7 +103,7 @@ fn test_syntax_map_layers_for_range(cx: &mut AppContext) { .unindent(), ); - let mut syntax_map = SyntaxMap::new(); + let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry.clone()); syntax_map.reparse(language.clone(), &buffer); @@ -202,7 +202,7 @@ fn test_dynamic_language_injection(cx: &mut AppContext) { .unindent(), ); - let mut syntax_map = SyntaxMap::new(); + let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry.clone()); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); @@ -897,11 +897,11 @@ fn test_random_edits( let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), text); - let mut syntax_map = SyntaxMap::new(); + let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry.clone()); syntax_map.reparse(language.clone(), &buffer); - let mut reference_syntax_map = SyntaxMap::new(); + let mut reference_syntax_map = SyntaxMap::new(&buffer); reference_syntax_map.set_language_registry(registry.clone()); log::info!("initial text:\n{}", buffer.text()); @@ -918,7 +918,7 @@ fn test_random_edits( syntax_map.reparse(language.clone(), &buffer); - reference_syntax_map.clear(); + reference_syntax_map.clear(&buffer); reference_syntax_map.reparse(language.clone(), &buffer); } @@ -931,7 +931,7 @@ fn test_random_edits( syntax_map.interpolate(&buffer); syntax_map.reparse(language.clone(), &buffer); - reference_syntax_map.clear(); + reference_syntax_map.clear(&buffer); reference_syntax_map.reparse(language.clone(), &buffer); assert_eq!( syntax_map.layers(&buffer).len(), @@ -1082,7 +1082,7 @@ fn test_edit_sequence( .unwrap(); let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), Default::default()); - let mut mutated_syntax_map = SyntaxMap::new(); + let mut mutated_syntax_map = SyntaxMap::new(&buffer); mutated_syntax_map.set_language_registry(registry.clone()); mutated_syntax_map.reparse(language.clone(), &buffer); @@ -1097,7 +1097,7 @@ fn test_edit_sequence( // Create a second syntax map from scratch log::info!("fresh parse {i}: {marked_string:?}"); - let mut reference_syntax_map = SyntaxMap::new(); + let mut reference_syntax_map = SyntaxMap::new(&buffer); reference_syntax_map.set_language_registry(registry.clone()); reference_syntax_map.reparse(language.clone(), &buffer); diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 5b6eddd5b1..9dee092dea 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -561,7 +561,7 @@ impl MultiBuffer { } let mut buffer_edits: HashMap> = Default::default(); let mut edited_excerpt_ids = Vec::new(); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); for (ix, (range, new_text)) in edits.enumerate() { let new_text: Arc = new_text.into(); let original_indent_column = original_indent_columns.get(ix).copied().unwrap_or(0); @@ -841,7 +841,7 @@ impl MultiBuffer { let mut ranges = Vec::new(); let snapshot = self.read(cx); let buffers = self.buffers.borrow(); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); for (buffer_id, buffer_transaction) in &transaction.buffer_transactions { let Some(buffer_state) = buffers.get(buffer_id) else { @@ -957,7 +957,7 @@ impl MultiBuffer { let mut selections_by_buffer: HashMap>> = Default::default(); let snapshot = self.read(cx); - let mut cursor = snapshot.excerpts.cursor::>(); + let mut cursor = snapshot.excerpts.cursor::>(&()); for selection in selections { let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id); let end_locator = snapshot.excerpt_locator_for_id(selection.end.excerpt_id); @@ -1281,7 +1281,7 @@ impl MultiBuffer { let mut prev_locator = snapshot.excerpt_locator_for_id(prev_excerpt_id).clone(); let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids); - let mut cursor = snapshot.excerpts.cursor::>(); + let mut cursor = snapshot.excerpts.cursor::>(&()); let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right, &()); prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone(); @@ -1388,7 +1388,7 @@ impl MultiBuffer { let mut excerpts = Vec::new(); let snapshot = self.read(cx); let buffers = self.buffers.borrow(); - let mut cursor = snapshot.excerpts.cursor::>(); + let mut cursor = snapshot.excerpts.cursor::>(&()); for locator in buffers .get(&buffer.read(cx).remote_id()) .map(|state| &state.excerpts) @@ -1432,7 +1432,7 @@ impl MultiBuffer { let snapshot = self.read(cx); let position = position.to_offset(&snapshot); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); cursor.seek(&position, Bias::Right, &()); cursor .item() @@ -1459,7 +1459,7 @@ impl MultiBuffer { ) -> Option<(Model, usize, ExcerptId)> { let snapshot = self.read(cx); let offset = point.to_offset(&snapshot); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); cursor.seek(&offset, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -1482,7 +1482,7 @@ impl MultiBuffer { ) -> Option<(Model, Point, ExcerptId)> { let snapshot = self.read(cx); let point = point.to_point(&snapshot); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); cursor.seek(&point, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -1507,7 +1507,7 @@ impl MultiBuffer { let end = range.end.to_offset(&snapshot); let mut result = Vec::new(); - let mut cursor = snapshot.excerpts.cursor::(); + let mut cursor = snapshot.excerpts.cursor::(&()); cursor.seek(&start, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -1546,8 +1546,8 @@ impl MultiBuffer { let mut buffers = self.buffers.borrow_mut(); let mut snapshot = self.snapshot.borrow_mut(); - let mut new_excerpts = SumTree::new(); - let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); + let mut new_excerpts = SumTree::default(); + let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&()); let mut edits = Vec::new(); let mut excerpt_ids = ids.iter().copied().peekable(); @@ -1801,8 +1801,8 @@ impl MultiBuffer { let ids = ids.into_iter().collect::>(); let snapshot = self.snapshot(cx); let locators = snapshot.excerpt_locators_for_ids(ids.iter().copied()); - let mut new_excerpts = SumTree::new(); - let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); + let mut new_excerpts = SumTree::default(); + let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&()); let mut edits = Vec::>::new(); for locator in &locators { @@ -1927,8 +1927,8 @@ impl MultiBuffer { excerpts_to_edit.sort_unstable_by_key(|(locator, _, _)| *locator); let mut edits = Vec::new(); - let mut new_excerpts = SumTree::new(); - let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); + let mut new_excerpts = SumTree::default(); + let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&()); for (locator, buffer, buffer_edited) in excerpts_to_edit { new_excerpts.append(cursor.slice(&Some(locator), Bias::Left, &()), &()); @@ -2230,7 +2230,7 @@ impl MultiBufferSnapshot { pub fn reversed_chars_at(&self, position: T) -> impl Iterator + '_ { let mut offset = position.to_offset(self); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&offset, Bias::Left, &()); let mut excerpt_chunks = cursor.item().map(|excerpt| { let end_before_footer = cursor.start() + excerpt.text_summary.len; @@ -2357,7 +2357,7 @@ impl MultiBufferSnapshot { return buffer.clip_offset(offset, bias); } - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&offset, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); @@ -2376,7 +2376,7 @@ impl MultiBufferSnapshot { return buffer.clip_point(point, bias); } - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&point, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer); @@ -2395,7 +2395,7 @@ impl MultiBufferSnapshot { return buffer.clip_offset_utf16(offset, bias); } - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&offset, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { let excerpt_start = excerpt.range.context.start.to_offset_utf16(&excerpt.buffer); @@ -2414,7 +2414,7 @@ impl MultiBufferSnapshot { return buffer.clip_point_utf16(point, bias); } - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&point.0, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { let excerpt_start = excerpt @@ -2432,7 +2432,7 @@ impl MultiBufferSnapshot { pub fn bytes_in_range(&self, range: Range) -> MultiBufferBytes { let range = range.start.to_offset(self)..range.end.to_offset(self); - let mut excerpts = self.excerpts.cursor::(); + let mut excerpts = self.excerpts.cursor::(&()); excerpts.seek(&range.start, Bias::Right, &()); let mut chunk = &[][..]; @@ -2457,7 +2457,7 @@ impl MultiBufferSnapshot { range: Range, ) -> ReversedMultiBufferBytes { let range = range.start.to_offset(self)..range.end.to_offset(self); - let mut excerpts = self.excerpts.cursor::(); + let mut excerpts = self.excerpts.cursor::(&()); excerpts.seek(&range.end, Bias::Left, &()); let mut chunk = &[][..]; @@ -2482,7 +2482,7 @@ impl MultiBufferSnapshot { pub fn buffer_rows(&self, start_row: MultiBufferRow) -> MultiBufferRows { let mut result = MultiBufferRows { buffer_row_range: 0..0, - excerpts: self.excerpts.cursor(), + excerpts: self.excerpts.cursor(&()), }; result.seek(start_row); result @@ -2492,7 +2492,7 @@ impl MultiBufferSnapshot { let range = range.start.to_offset(self)..range.end.to_offset(self); let mut chunks = MultiBufferChunks { range: range.clone(), - excerpts: self.excerpts.cursor(), + excerpts: self.excerpts.cursor(&()), excerpt_chunks: None, language_aware, }; @@ -2505,7 +2505,7 @@ impl MultiBufferSnapshot { return buffer.offset_to_point(offset); } - let mut cursor = self.excerpts.cursor::<(usize, Point)>(); + let mut cursor = self.excerpts.cursor::<(usize, Point)>(&()); cursor.seek(&offset, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); @@ -2526,7 +2526,7 @@ impl MultiBufferSnapshot { return buffer.offset_to_point_utf16(offset); } - let mut cursor = self.excerpts.cursor::<(usize, PointUtf16)>(); + let mut cursor = self.excerpts.cursor::<(usize, PointUtf16)>(&()); cursor.seek(&offset, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); @@ -2547,7 +2547,7 @@ impl MultiBufferSnapshot { return buffer.point_to_point_utf16(point); } - let mut cursor = self.excerpts.cursor::<(Point, PointUtf16)>(); + let mut cursor = self.excerpts.cursor::<(Point, PointUtf16)>(&()); cursor.seek(&point, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); @@ -2569,7 +2569,7 @@ impl MultiBufferSnapshot { return buffer.point_to_offset(point); } - let mut cursor = self.excerpts.cursor::<(Point, usize)>(); + let mut cursor = self.excerpts.cursor::<(Point, usize)>(&()); cursor.seek(&point, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_point, start_offset) = cursor.start(); @@ -2590,7 +2590,7 @@ impl MultiBufferSnapshot { return buffer.offset_utf16_to_offset(offset_utf16); } - let mut cursor = self.excerpts.cursor::<(OffsetUtf16, usize)>(); + let mut cursor = self.excerpts.cursor::<(OffsetUtf16, usize)>(&()); cursor.seek(&offset_utf16, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_offset_utf16, start_offset) = cursor.start(); @@ -2612,7 +2612,7 @@ impl MultiBufferSnapshot { return buffer.offset_to_offset_utf16(offset); } - let mut cursor = self.excerpts.cursor::<(usize, OffsetUtf16)>(); + let mut cursor = self.excerpts.cursor::<(usize, OffsetUtf16)>(&()); cursor.seek(&offset, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_offset, start_offset_utf16) = cursor.start(); @@ -2636,7 +2636,7 @@ impl MultiBufferSnapshot { return buffer.point_utf16_to_offset(point); } - let mut cursor = self.excerpts.cursor::<(PointUtf16, usize)>(); + let mut cursor = self.excerpts.cursor::<(PointUtf16, usize)>(&()); cursor.seek(&point, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let (start_point, start_offset) = cursor.start(); @@ -2659,7 +2659,7 @@ impl MultiBufferSnapshot { point: T, ) -> Option<(&BufferSnapshot, usize)> { let offset = point.to_offset(self); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&offset, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -2680,7 +2680,7 @@ impl MultiBufferSnapshot { let mut result = BTreeMap::new(); let mut rows_for_excerpt = Vec::new(); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); let mut rows = rows.into_iter().peekable(); let mut prev_row = u32::MAX; let mut prev_language_indent_size = IndentSize::default(); @@ -2769,7 +2769,7 @@ impl MultiBufferSnapshot { &self, row: MultiBufferRow, ) -> Option<(&BufferSnapshot, Range)> { - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); let point = Point::new(row.0, 0); cursor.seek(&point, Bias::Right, &()); if cursor.item().is_none() && *cursor.start() == point { @@ -2803,9 +2803,9 @@ impl MultiBufferSnapshot { D: TextDimension, O: ToOffset, { - let mut summary = D::default(); + let mut summary = D::zero(&()); let mut range = range.start.to_offset(self)..range.end.to_offset(self); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&range.start, Bias::Right, &()); if let Some(excerpt) = cursor.item() { let mut end_before_newline = cursor.end(&()); @@ -2856,7 +2856,7 @@ impl MultiBufferSnapshot { where D: TextDimension + Ord + Sub, { - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); let locator = self.excerpt_locator_for_id(anchor.excerpt_id); cursor.seek(locator, Bias::Left, &()); @@ -2894,7 +2894,7 @@ impl MultiBufferSnapshot { } let mut anchors = anchors.into_iter().peekable(); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); let mut summaries = Vec::new(); while let Some(anchor) = anchors.peek() { let excerpt_id = anchor.excerpt_id; @@ -2949,7 +2949,7 @@ impl MultiBufferSnapshot { I: 'a + IntoIterator, { let mut anchors = anchors.into_iter().enumerate().peekable(); - let mut cursor = self.excerpts.cursor::>(); + let mut cursor = self.excerpts.cursor::>(&()); cursor.next(&()); let mut result = Vec::new(); @@ -3064,7 +3064,7 @@ impl MultiBufferSnapshot { }; } - let mut cursor = self.excerpts.cursor::<(usize, Option)>(); + let mut cursor = self.excerpts.cursor::<(usize, Option)>(&()); cursor.seek(&offset, Bias::Right, &()); if cursor.item().is_none() && offset == cursor.start().0 && bias == Bias::Left { cursor.prev(&()); @@ -3099,7 +3099,7 @@ impl MultiBufferSnapshot { text_anchor: text::Anchor, ) -> Option { let locator = self.excerpt_locator_for_id(excerpt_id); - let mut cursor = self.excerpts.cursor::>(); + let mut cursor = self.excerpts.cursor::>(&()); cursor.seek(locator, Bias::Left, &()); if let Some(excerpt) = cursor.item() { if excerpt.id == excerpt_id { @@ -3139,7 +3139,7 @@ impl MultiBufferSnapshot { ) -> impl Iterator + '_ { let range = range.start.to_offset(self)..range.end.to_offset(self); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&range.start, Bias::Right, &()); cursor.prev(&()); @@ -3183,7 +3183,7 @@ impl MultiBufferSnapshot { }; let bounds = (start, end); - let mut cursor = self.excerpts.cursor::<(usize, Point)>(); + let mut cursor = self.excerpts.cursor::<(usize, Point)>(&()); cursor.seek(&start_offset, Bias::Right, &()); if cursor.item().is_none() { cursor.prev(&()); @@ -3550,7 +3550,7 @@ impl MultiBufferSnapshot { &self, row_range: Range, ) -> impl Iterator> + '_ { - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&Point::new(row_range.end.0, 0), Bias::Left, &()); if cursor.item().is_none() { @@ -3617,7 +3617,7 @@ impl MultiBufferSnapshot { &self, row_range: Range, ) -> impl Iterator> + '_ { - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&Point::new(row_range.start.0, 0), Bias::Left, &()); @@ -3779,7 +3779,7 @@ impl MultiBufferSnapshot { } else if id == ExcerptId::max() { Locator::max_ref() } else { - let mut cursor = self.excerpt_ids.cursor::(); + let mut cursor = self.excerpt_ids.cursor::(&()); cursor.seek(&id, Bias::Left, &()); if let Some(entry) = cursor.item() { if entry.id == id { @@ -3814,7 +3814,7 @@ impl MultiBufferSnapshot { } } - let mut cursor = self.excerpt_ids.cursor::(); + let mut cursor = self.excerpt_ids.cursor::(&()); for id in sorted_ids { if cursor.seek_forward(&id, Bias::Left, &()) { locators.push(cursor.item().unwrap().locator.clone()); @@ -3839,7 +3839,7 @@ impl MultiBufferSnapshot { &'a self, excerpt_id: ExcerptId, ) -> Option> { - let mut cursor = self.excerpts.cursor::<(Option<&Locator>, T)>(); + let mut cursor = self.excerpts.cursor::<(Option<&Locator>, T)>(&()); let locator = self.excerpt_locator_for_id(excerpt_id); if cursor.seek(&Some(locator), Bias::Left, &()) { let start = cursor.start().1.clone(); @@ -3851,7 +3851,7 @@ impl MultiBufferSnapshot { } fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> { - let mut cursor = self.excerpts.cursor::>(); + let mut cursor = self.excerpts.cursor::>(&()); let locator = self.excerpt_locator_for_id(excerpt_id); cursor.seek(&Some(locator), Bias::Left, &()); if let Some(excerpt) = cursor.item() { @@ -3866,7 +3866,7 @@ impl MultiBufferSnapshot { pub fn excerpt_containing(&self, range: Range) -> Option { let range = range.start.to_offset(self)..range.end.to_offset(self); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.seek(&range.start, Bias::Right, &()); let start_excerpt = cursor.item()?; @@ -3891,7 +3891,7 @@ impl MultiBufferSnapshot { I: IntoIterator> + 'a, { let mut ranges = ranges.into_iter().map(|range| range.to_offset(self)); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.next(&()); let mut current_range = ranges.next(); iter::from_fn(move || { @@ -3943,7 +3943,7 @@ impl MultiBufferSnapshot { ranges: impl IntoIterator>, ) -> impl Iterator)> { let mut ranges = ranges.into_iter().map(|range| range.to_offset(self)); - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); cursor.next(&()); let mut current_range = ranges.next(); iter::from_fn(move || { @@ -3980,7 +3980,7 @@ impl MultiBufferSnapshot { range: &'a Range, include_local: bool, ) -> impl 'a + Iterator)> { - let mut cursor = self.excerpts.cursor::(); + let mut cursor = self.excerpts.cursor::(&()); let start_locator = self.excerpt_locator_for_id(range.start.excerpt_id); let end_locator = self.excerpt_locator_for_id(range.end.excerpt_id); cursor.seek(start_locator, Bias::Left, &()); @@ -4519,6 +4519,10 @@ impl sum_tree::KeyedItem for ExcerptIdMapping { impl sum_tree::Summary for ExcerptId { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { *self = *other; } @@ -4527,6 +4531,10 @@ impl sum_tree::Summary for ExcerptId { impl sum_tree::Summary for ExcerptSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { debug_assert!(summary.excerpt_locator > self.excerpt_locator); self.excerpt_locator = summary.excerpt_locator.clone(); @@ -4536,12 +4544,20 @@ impl sum_tree::Summary for ExcerptSummary { } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for TextSummary { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self += &summary.text; } } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for usize { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self += summary.text.len; } @@ -4566,30 +4582,50 @@ impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for Locator { } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for OffsetUtf16 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self += summary.text.len_utf16; } } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Point { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self += summary.text.lines; } } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for PointUtf16 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self += summary.text.lines_utf16() } } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a Locator> { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self = Some(&summary.excerpt_locator); } } impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { *self = Some(summary.excerpt_id); } diff --git a/crates/notifications/src/notification_store.rs b/crates/notifications/src/notification_store.rs index e01b99d472..48fcb5dfbb 100644 --- a/crates/notifications/src/notification_store.rs +++ b/crates/notifications/src/notification_store.rs @@ -137,13 +137,12 @@ impl NotificationStore { return None; } let ix = count - 1 - ix; - let mut cursor = self.notifications.cursor::(); + let mut cursor = self.notifications.cursor::(&()); cursor.seek(&Count(ix), Bias::Right, &()); cursor.item() } - pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> { - let mut cursor = self.notifications.cursor::(); + let mut cursor = self.notifications.cursor::(&()); cursor.seek(&NotificationId(id), Bias::Left, &()); if let Some(item) = cursor.item() { if item.id == id { @@ -372,8 +371,8 @@ impl NotificationStore { is_new: bool, cx: &mut ModelContext<'_, NotificationStore>, ) { - let mut cursor = self.notifications.cursor::<(NotificationId, Count)>(); - let mut new_notifications = SumTree::new(); + let mut cursor = self.notifications.cursor::<(NotificationId, Count)>(&()); + let mut new_notifications = SumTree::default(); let mut old_range = 0..0; for (i, (id, new_notification)) in notifications.into_iter().enumerate() { @@ -468,6 +467,10 @@ impl sum_tree::Item for NotificationEntry { impl sum_tree::Summary for NotificationSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.max_id = self.max_id.max(summary.max_id); self.count += summary.count; @@ -476,6 +479,10 @@ impl sum_tree::Summary for NotificationSummary { } impl<'a> sum_tree::Dimension<'a, NotificationSummary> for NotificationId { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { debug_assert!(summary.max_id > self.0); self.0 = summary.max_id; @@ -483,6 +490,10 @@ impl<'a> sum_tree::Dimension<'a, NotificationSummary> for NotificationId { } impl<'a> sum_tree::Dimension<'a, NotificationSummary> for Count { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { self.0 += summary.count; } diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 35eb20259c..24852afd70 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -2753,7 +2753,7 @@ impl LspStore { if let Some(language) = buffer.language().cloned() { for adapter in self.languages.lsp_adapters(&language.name()) { if let Some(server_id) = ids.get(&(worktree_id, adapter.name.clone())) { - buffer.update_diagnostics(*server_id, Default::default(), cx); + buffer.update_diagnostics(*server_id, DiagnosticSet::new([], buffer), cx); } } } @@ -5149,7 +5149,11 @@ impl LspStore { self.buffer_store.update(cx, |buffer_store, cx| { for buffer in buffer_store.buffers() { buffer.update(cx, |buffer, cx| { - buffer.update_diagnostics(server_id, Default::default(), cx); + buffer.update_diagnostics( + server_id, + DiagnosticSet::new([], buffer), + cx, + ); }); } }); diff --git a/crates/rope/src/rope.rs b/crates/rope/src/rope.rs index 00ffbfa9eb..56fe7fc054 100644 --- a/crates/rope/src/rope.rs +++ b/crates/rope/src/rope.rs @@ -36,7 +36,7 @@ impl Rope { } pub fn append(&mut self, rope: Rope) { - let mut chunks = rope.chunks.cursor::<()>(); + let mut chunks = rope.chunks.cursor::<()>(&()); chunks.next(&()); if let Some(chunk) = chunks.item() { if self.chunks.last().map_or(false, |c| c.0.len() < CHUNK_BASE) @@ -175,7 +175,7 @@ impl Rope { { // Ensure all chunks except maybe the last one are not underflowing. // Allow some wiggle room for multibyte characters at chunk boundaries. - let mut chunks = self.chunks.cursor::<()>().peekable(); + let mut chunks = self.chunks.cursor::<()>(&()).peekable(); while let Some(chunk) = chunks.next() { if chunks.peek().is_some() { assert!(chunk.0.len() + 3 >= CHUNK_BASE); @@ -245,7 +245,7 @@ impl Rope { if offset >= self.summary().len { return self.summary().len_utf16; } - let mut cursor = self.chunks.cursor::<(usize, OffsetUtf16)>(); + let mut cursor = self.chunks.cursor::<(usize, OffsetUtf16)>(&()); cursor.seek(&offset, Bias::Left, &()); let overshoot = offset - cursor.start().0; cursor.start().1 @@ -258,7 +258,7 @@ impl Rope { if offset >= self.summary().len_utf16 { return self.summary().len; } - let mut cursor = self.chunks.cursor::<(OffsetUtf16, usize)>(); + let mut cursor = self.chunks.cursor::<(OffsetUtf16, usize)>(&()); cursor.seek(&offset, Bias::Left, &()); let overshoot = offset - cursor.start().0; cursor.start().1 @@ -271,7 +271,7 @@ impl Rope { if offset >= self.summary().len { return self.summary().lines; } - let mut cursor = self.chunks.cursor::<(usize, Point)>(); + let mut cursor = self.chunks.cursor::<(usize, Point)>(&()); cursor.seek(&offset, Bias::Left, &()); let overshoot = offset - cursor.start().0; cursor.start().1 @@ -284,7 +284,7 @@ impl Rope { if offset >= self.summary().len { return self.summary().lines_utf16(); } - let mut cursor = self.chunks.cursor::<(usize, PointUtf16)>(); + let mut cursor = self.chunks.cursor::<(usize, PointUtf16)>(&()); cursor.seek(&offset, Bias::Left, &()); let overshoot = offset - cursor.start().0; cursor.start().1 @@ -297,7 +297,7 @@ impl Rope { if point >= self.summary().lines { return self.summary().lines_utf16(); } - let mut cursor = self.chunks.cursor::<(Point, PointUtf16)>(); + let mut cursor = self.chunks.cursor::<(Point, PointUtf16)>(&()); cursor.seek(&point, Bias::Left, &()); let overshoot = point - cursor.start().0; cursor.start().1 @@ -310,7 +310,7 @@ impl Rope { if point >= self.summary().lines { return self.summary().len; } - let mut cursor = self.chunks.cursor::<(Point, usize)>(); + let mut cursor = self.chunks.cursor::<(Point, usize)>(&()); cursor.seek(&point, Bias::Left, &()); let overshoot = point - cursor.start().0; cursor.start().1 @@ -331,7 +331,7 @@ impl Rope { if point >= self.summary().lines_utf16() { return self.summary().len; } - let mut cursor = self.chunks.cursor::<(PointUtf16, usize)>(); + let mut cursor = self.chunks.cursor::<(PointUtf16, usize)>(&()); cursor.seek(&point, Bias::Left, &()); let overshoot = point - cursor.start().0; cursor.start().1 @@ -344,7 +344,7 @@ impl Rope { if point.0 >= self.summary().lines_utf16() { return self.summary().lines; } - let mut cursor = self.chunks.cursor::<(PointUtf16, Point)>(); + let mut cursor = self.chunks.cursor::<(PointUtf16, Point)>(&()); cursor.seek(&point.0, Bias::Left, &()); let overshoot = Unclipped(point.0 - cursor.start().0); cursor.start().1 @@ -354,7 +354,7 @@ impl Rope { } pub fn clip_offset(&self, mut offset: usize, bias: Bias) -> usize { - let mut cursor = self.chunks.cursor::(); + let mut cursor = self.chunks.cursor::(&()); cursor.seek(&offset, Bias::Left, &()); if let Some(chunk) = cursor.item() { let mut ix = offset - cursor.start(); @@ -377,7 +377,7 @@ impl Rope { } pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 { - let mut cursor = self.chunks.cursor::(); + let mut cursor = self.chunks.cursor::(&()); cursor.seek(&offset, Bias::Right, &()); if let Some(chunk) = cursor.item() { let overshoot = offset - cursor.start(); @@ -388,7 +388,7 @@ impl Rope { } pub fn clip_point(&self, point: Point, bias: Bias) -> Point { - let mut cursor = self.chunks.cursor::(); + let mut cursor = self.chunks.cursor::(&()); cursor.seek(&point, Bias::Right, &()); if let Some(chunk) = cursor.item() { let overshoot = point - cursor.start(); @@ -399,7 +399,7 @@ impl Rope { } pub fn clip_point_utf16(&self, point: Unclipped, bias: Bias) -> PointUtf16 { - let mut cursor = self.chunks.cursor::(); + let mut cursor = self.chunks.cursor::(&()); cursor.seek(&point.0, Bias::Right, &()); if let Some(chunk) = cursor.item() { let overshoot = Unclipped(point.0 - cursor.start()); @@ -472,7 +472,7 @@ pub struct Cursor<'a> { impl<'a> Cursor<'a> { pub fn new(rope: &'a Rope, offset: usize) -> Self { - let mut chunks = rope.chunks.cursor(); + let mut chunks = rope.chunks.cursor(&()); chunks.seek(&offset, Bias::Right, &()); Self { rope, @@ -521,7 +521,7 @@ impl<'a> Cursor<'a> { pub fn summary(&mut self, end_offset: usize) -> D { debug_assert!(end_offset >= self.offset); - let mut summary = D::default(); + let mut summary = D::zero(&()); if let Some(start_chunk) = self.chunks.item() { let start_ix = self.offset - self.chunks.start(); let end_ix = cmp::min(end_offset, self.chunks.end(&())) - self.chunks.start(); @@ -563,7 +563,7 @@ pub struct Chunks<'a> { impl<'a> Chunks<'a> { pub fn new(rope: &'a Rope, range: Range, reversed: bool) -> Self { - let mut chunks = rope.chunks.cursor(); + let mut chunks = rope.chunks.cursor(&()); let offset = if reversed { chunks.seek(&range.end, Bias::Left, &()); range.end @@ -774,7 +774,7 @@ pub struct Bytes<'a> { impl<'a> Bytes<'a> { pub fn new(rope: &'a Rope, range: Range, reversed: bool) -> Self { - let mut chunks = rope.chunks.cursor(); + let mut chunks = rope.chunks.cursor(&()); if reversed { chunks.seek(&range.end, Bias::Left, &()); } else { @@ -1180,6 +1180,10 @@ impl<'a> From<&'a str> for ChunkSummary { impl sum_tree::Summary for ChunkSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.text += &summary.text; } @@ -1263,6 +1267,10 @@ impl<'a> From<&'a str> for TextSummary { impl sum_tree::Summary for TextSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &Self::Context) { *self += summary; } @@ -1333,6 +1341,10 @@ impl TextDimension for (D1, D2) { } impl<'a> sum_tree::Dimension<'a, ChunkSummary> for TextSummary { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { *self += &summary.text; } @@ -1349,6 +1361,10 @@ impl TextDimension for TextSummary { } impl<'a> sum_tree::Dimension<'a, ChunkSummary> for usize { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { *self += summary.text.len; } @@ -1365,6 +1381,10 @@ impl TextDimension for usize { } impl<'a> sum_tree::Dimension<'a, ChunkSummary> for OffsetUtf16 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { *self += summary.text.len_utf16; } @@ -1381,6 +1401,10 @@ impl TextDimension for OffsetUtf16 { } impl<'a> sum_tree::Dimension<'a, ChunkSummary> for Point { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { *self += summary.text.lines; } @@ -1397,6 +1421,10 @@ impl TextDimension for Point { } impl<'a> sum_tree::Dimension<'a, ChunkSummary> for PointUtf16 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { *self += summary.text.lines_utf16(); } @@ -1890,7 +1918,7 @@ mod tests { impl Rope { fn text(&self) -> String { let mut text = String::new(); - for chunk in self.chunks.cursor::<()>() { + for chunk in self.chunks.cursor::<()>(&()) { text.push_str(&chunk.0); } text diff --git a/crates/rope/src/unclipped.rs b/crates/rope/src/unclipped.rs index 937cbca053..b3427e2cb9 100644 --- a/crates/rope/src/unclipped.rs +++ b/crates/rope/src/unclipped.rs @@ -13,6 +13,10 @@ impl From for Unclipped { impl<'a, T: sum_tree::Dimension<'a, ChunkSummary>> sum_tree::Dimension<'a, ChunkSummary> for Unclipped { + fn zero(_: &()) -> Self { + Self(T::zero(&())) + } + fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { self.0.add_summary(summary, &()); } diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 452930f942..6da43a8de5 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -28,21 +28,21 @@ where T: Item, D: Dimension<'a, T::Summary>, { - pub fn new(tree: &'a SumTree) -> Self { + pub fn new(tree: &'a SumTree, cx: &::Context) -> Self { Self { tree, stack: ArrayVec::new(), - position: D::default(), + position: D::zero(cx), did_seek: false, at_end: tree.is_empty(), } } - fn reset(&mut self) { + fn reset(&mut self, cx: &::Context) { self.did_seek = false; self.at_end = self.tree.is_empty(); self.stack.truncate(0); - self.position = D::default(); + self.position = D::zero(cx); } pub fn start(&self) -> &D { @@ -192,7 +192,7 @@ where } if self.at_end { - self.position = D::default(); + self.position = D::zero(cx); self.at_end = self.tree.is_empty(); if !self.tree.is_empty() { self.stack.push(StackEntry { @@ -208,7 +208,7 @@ where if let Some(StackEntry { position, .. }) = self.stack.iter().rev().nth(1) { self.position = position.clone(); } else { - self.position = D::default(); + self.position = D::zero(cx); } let entry = self.stack.last_mut().unwrap(); @@ -232,7 +232,7 @@ where if descending { let tree = &child_trees[entry.index]; self.stack.push(StackEntry { - position: D::default(), + position: D::zero(cx), tree, index: tree.0.child_summaries().len() - 1, }) @@ -264,7 +264,7 @@ where self.stack.push(StackEntry { tree: self.tree, index: 0, - position: D::default(), + position: D::zero(cx), }); descend = true; } @@ -364,7 +364,7 @@ where where Target: SeekTarget<'a, T::Summary, D>, { - self.reset(); + self.reset(cx); self.seek_internal(pos, bias, &mut (), cx) } @@ -392,10 +392,10 @@ where Target: SeekTarget<'a, T::Summary, D>, { let mut slice = SliceSeekAggregate { - tree: SumTree::new(), + tree: SumTree::new(cx), leaf_items: ArrayVec::new(), leaf_item_summaries: ArrayVec::new(), - leaf_summary: T::Summary::default(), + leaf_summary: ::zero(cx), }; self.seek_internal(end, bias, &mut slice, cx); slice.tree @@ -417,7 +417,7 @@ where Target: SeekTarget<'a, T::Summary, D>, Output: Dimension<'a, T::Summary>, { - let mut summary = SummarySeekAggregate(Output::default()); + let mut summary = SummarySeekAggregate(Output::zero(cx)); self.seek_internal(end, bias, &mut summary, cx); summary.0 } @@ -443,7 +443,7 @@ where self.stack.push(StackEntry { tree: self.tree, index: 0, - position: Default::default(), + position: D::zero(cx), }); } @@ -633,8 +633,12 @@ where T: Item, D: Dimension<'a, T::Summary>, { - pub fn new(tree: &'a SumTree, filter_node: F) -> Self { - let cursor = tree.cursor::(); + pub fn new( + tree: &'a SumTree, + cx: &::Context, + filter_node: F, + ) -> Self { + let cursor = tree.cursor::(cx); Self { cursor, filter_node, @@ -727,7 +731,7 @@ impl<'a, T: Item> SeekAggregate<'a, T> for SliceSeekAggregate { fn end_leaf(&mut self, cx: &::Context) { self.tree.append( SumTree(Arc::new(Node::Leaf { - summary: mem::take(&mut self.leaf_summary), + summary: mem::replace(&mut self.leaf_summary, ::zero(cx)), items: mem::take(&mut self.leaf_items), item_summaries: mem::take(&mut self.leaf_item_summaries), })), diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 8a8027408f..ca351d67ce 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -34,9 +34,11 @@ pub trait KeyedItem: Item { /// /// Each Summary type can have multiple [`Dimensions`] that it measures, /// which can be used to navigate the tree -pub trait Summary: Default + Clone + fmt::Debug { +pub trait Summary: Clone + fmt::Debug { type Context; + fn zero(cx: &Self::Context) -> Self; + fn add_summary(&mut self, summary: &Self, cx: &Self::Context); } @@ -47,17 +49,23 @@ pub trait Summary: Default + Clone + fmt::Debug { /// # Example: /// Zed's rope has a `TextSummary` type that summarizes lines, characters, and bytes. /// Each of these are different dimensions we may want to seek to -pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug + Default { - fn add_summary(&mut self, _summary: &'a S, _: &S::Context); +pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug { + fn zero(cx: &S::Context) -> Self; + + fn add_summary(&mut self, summary: &'a S, cx: &S::Context); fn from_summary(summary: &'a S, cx: &S::Context) -> Self { - let mut dimension = Self::default(); + let mut dimension = Self::zero(cx); dimension.add_summary(summary, cx); dimension } } impl<'a, T: Summary> Dimension<'a, T> for T { + fn zero(cx: &T::Context) -> Self { + Summary::zero(cx) + } + fn add_summary(&mut self, summary: &'a T, cx: &T::Context) { Summary::add_summary(self, summary, cx); } @@ -74,10 +82,18 @@ impl<'a, S: Summary, D: Dimension<'a, S> + Ord> SeekTarget<'a, S, D> for D { } impl<'a, T: Summary> Dimension<'a, T> for () { + fn zero(_: &T::Context) -> Self { + () + } + fn add_summary(&mut self, _: &'a T, _: &T::Context) {} } impl<'a, T: Summary, D1: Dimension<'a, T>, D2: Dimension<'a, T>> Dimension<'a, T> for (D1, D2) { + fn zero(cx: &T::Context) -> Self { + (D1::zero(cx), D2::zero(cx)) + } + fn add_summary(&mut self, summary: &'a T, cx: &T::Context) { self.0.add_summary(summary, cx); self.1.add_summary(summary, cx); @@ -161,16 +177,16 @@ impl Bias { pub struct SumTree(Arc>); impl SumTree { - pub fn new() -> Self { + pub fn new(cx: &::Context) -> Self { SumTree(Arc::new(Node::Leaf { - summary: T::Summary::default(), + summary: ::zero(cx), items: ArrayVec::new(), item_summaries: ArrayVec::new(), })) } pub fn from_item(item: T, cx: &::Context) -> Self { - let mut tree = Self::new(); + let mut tree = Self::new(cx); tree.push(item, cx); tree } @@ -206,7 +222,7 @@ impl SumTree { let mut current_parent_node = None; for child_node in nodes.drain(..) { let parent_node = current_parent_node.get_or_insert_with(|| Node::Internal { - summary: T::Summary::default(), + summary: ::zero(cx), height, child_summaries: ArrayVec::new(), child_trees: ArrayVec::new(), @@ -234,7 +250,7 @@ impl SumTree { } if nodes.is_empty() { - Self::new() + Self::new(cx) } else { debug_assert_eq!(nodes.len(), 1); Self(Arc::new(nodes.pop().unwrap())) @@ -296,7 +312,7 @@ impl SumTree { } if nodes.is_empty() { - Self::new() + Self::new(cx) } else { debug_assert_eq!(nodes.len(), 1); nodes.pop().unwrap() @@ -306,7 +322,7 @@ impl SumTree { #[allow(unused)] pub fn items(&self, cx: &::Context) -> Vec { let mut items = Vec::new(); - let mut cursor = self.cursor::<()>(); + let mut cursor = self.cursor::<()>(cx); cursor.next(cx); while let Some(item) = cursor.item() { items.push(item.clone()); @@ -319,21 +335,25 @@ impl SumTree { Iter::new(self) } - pub fn cursor<'a, S>(&'a self) -> Cursor + pub fn cursor<'a, S>(&'a self, cx: &::Context) -> Cursor where S: Dimension<'a, T::Summary>, { - Cursor::new(self) + Cursor::new(self, cx) } /// Note: If the summary type requires a non `()` context, then the filter cursor /// that is returned cannot be used with Rust's iterators. - pub fn filter<'a, F, U>(&'a self, filter_node: F) -> FilterCursor + pub fn filter<'a, F, U>( + &'a self, + cx: &::Context, + filter_node: F, + ) -> FilterCursor where F: FnMut(&T::Summary) -> bool, U: Dimension<'a, T::Summary>, { - FilterCursor::new(self, filter_node) + FilterCursor::new(self, cx, filter_node) } #[allow(dead_code)] @@ -389,7 +409,7 @@ impl SumTree { &'a self, cx: &::Context, ) -> D { - let mut extent = D::default(); + let mut extent = D::zero(cx); match self.0.as_ref() { Node::Internal { summary, .. } | Node::Leaf { summary, .. } => { extent.add_summary(summary, cx); @@ -636,7 +656,7 @@ impl SumTree { ) -> Option { let mut replaced = None; *self = { - let mut cursor = self.cursor::(); + let mut cursor = self.cursor::(cx); let mut new_tree = cursor.slice(&item.key(), Bias::Left, cx); if let Some(cursor_item) = cursor.item() { if cursor_item.key() == item.key() { @@ -654,7 +674,7 @@ impl SumTree { pub fn remove(&mut self, key: &T::Key, cx: &::Context) -> Option { let mut removed = None; *self = { - let mut cursor = self.cursor::(); + let mut cursor = self.cursor::(cx); let mut new_tree = cursor.slice(key, Bias::Left, cx); if let Some(item) = cursor.item() { if item.key() == *key { @@ -681,11 +701,11 @@ impl SumTree { edits.sort_unstable_by_key(|item| item.key()); *self = { - let mut cursor = self.cursor::(); - let mut new_tree = SumTree::new(); + let mut cursor = self.cursor::(cx); + let mut new_tree = SumTree::new(cx); let mut buffered_items = Vec::new(); - cursor.seek(&T::Key::default(), Bias::Left, cx); + cursor.seek(&T::Key::zero(cx), Bias::Left, cx); for edit in edits { let new_key = edit.key(); let mut old_item = cursor.item(); @@ -724,7 +744,7 @@ impl SumTree { } pub fn get(&self, key: &T::Key, cx: &::Context) -> Option<&T> { - let mut cursor = self.cursor::(); + let mut cursor = self.cursor::(cx); if cursor.seek(key, Bias::Left, cx) { cursor.item() } else { @@ -733,9 +753,13 @@ impl SumTree { } } -impl Default for SumTree { +impl Default for SumTree +where + T: Item, + S: Summary, +{ fn default() -> Self { - Self::new() + Self::new(&()) } } @@ -824,7 +848,7 @@ where T: 'a + Summary, I: Iterator, { - let mut sum = T::default(); + let mut sum = T::zero(cx); for value in iter { sum.add_summary(value, cx); } @@ -846,10 +870,10 @@ mod tests { #[test] fn test_extend_and_push_tree() { - let mut tree1 = SumTree::new(); + let mut tree1 = SumTree::default(); tree1.extend(0..20, &()); - let mut tree2 = SumTree::new(); + let mut tree2 = SumTree::default(); tree2.extend(50..100, &()); tree1.append(tree2, &()); @@ -877,7 +901,7 @@ mod tests { let mut rng = StdRng::seed_from_u64(seed); let rng = &mut rng; - let mut tree = SumTree::::new(); + let mut tree = SumTree::::default(); let count = rng.gen_range(0..10); if rng.gen() { tree.extend(rng.sample_iter(distributions::Standard).take(count), &()); @@ -903,7 +927,7 @@ mod tests { reference_items.splice(splice_start..splice_end, new_items.clone()); tree = { - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right, &()); if rng.gen() { new_tree.extend(new_items, &()); @@ -918,12 +942,13 @@ mod tests { assert_eq!(tree.items(&()), reference_items); assert_eq!( tree.iter().collect::>(), - tree.cursor::<()>().collect::>() + tree.cursor::<()>(&()).collect::>() ); log::info!("tree items: {:?}", tree.items(&())); - let mut filter_cursor = tree.filter::<_, Count>(|summary| summary.contains_even); + let mut filter_cursor = + tree.filter::<_, Count>(&(), |summary| summary.contains_even); let expected_filtered_items = tree .items(&()) .into_iter() @@ -964,7 +989,7 @@ mod tests { assert_eq!(filter_cursor.item(), None); let mut before_start = false; - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); let start_pos = rng.gen_range(0..=reference_items.len()); cursor.seek(&Count(start_pos), Bias::Right, &()); let mut pos = rng.gen_range(start_pos..=reference_items.len()); @@ -1015,7 +1040,7 @@ mod tests { let start_bias = if rng.gen() { Bias::Left } else { Bias::Right }; let end_bias = if rng.gen() { Bias::Left } else { Bias::Right }; - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); cursor.seek(&Count(start), start_bias, &()); let slice = cursor.slice(&Count(end), end_bias, &()); @@ -1030,8 +1055,8 @@ mod tests { #[test] fn test_cursor() { // Empty tree - let tree = SumTree::::new(); - let mut cursor = tree.cursor::(); + let tree = SumTree::::default(); + let mut cursor = tree.cursor::(&()); assert_eq!( cursor.slice(&Count(0), Bias::Right, &()).items(&()), Vec::::new() @@ -1052,9 +1077,9 @@ mod tests { assert_eq!(cursor.start().sum, 0); // Single-element tree - let mut tree = SumTree::::new(); + let mut tree = SumTree::::default(); tree.extend(vec![1], &()); - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); assert_eq!( cursor.slice(&Count(0), Bias::Right, &()).items(&()), Vec::::new() @@ -1076,7 +1101,7 @@ mod tests { assert_eq!(cursor.next_item(), None); assert_eq!(cursor.start().sum, 0); - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); assert_eq!(cursor.slice(&Count(1), Bias::Right, &()).items(&()), [1]); assert_eq!(cursor.item(), None); assert_eq!(cursor.prev_item(), Some(&1)); @@ -1096,9 +1121,9 @@ mod tests { assert_eq!(cursor.start().sum, 1); // Multiple-element tree - let mut tree = SumTree::new(); + let mut tree = SumTree::default(); tree.extend(vec![1, 2, 3, 4, 5, 6], &()); - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); assert_eq!(cursor.slice(&Count(2), Bias::Right, &()).items(&()), [1, 2]); assert_eq!(cursor.item(), Some(&3)); @@ -1179,7 +1204,7 @@ mod tests { assert_eq!(cursor.next_item(), Some(&2)); assert_eq!(cursor.start().sum, 0); - let mut cursor = tree.cursor::(); + let mut cursor = tree.cursor::(&()); assert_eq!( cursor .slice(&tree.extent::(&()), Bias::Right, &()) @@ -1227,7 +1252,7 @@ mod tests { #[test] fn test_edit() { - let mut tree = SumTree::::new(); + let mut tree = SumTree::::default(); let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &()); assert_eq!(tree.items(&()), vec![0, 1, 2]); @@ -1305,6 +1330,10 @@ mod tests { impl Summary for IntegersSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { self.count += other.count; self.sum += other.sum; @@ -1314,12 +1343,20 @@ mod tests { } impl<'a> Dimension<'a, IntegersSummary> for u8 { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { *self = summary.max; } } impl<'a> Dimension<'a, IntegersSummary> for Count { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { self.0 += summary.count; } @@ -1332,6 +1369,10 @@ mod tests { } impl<'a> Dimension<'a, IntegersSummary> for Sum { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { self.0 += summary.sum; } diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index 53bb0a807c..72465b1a99 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -53,7 +53,7 @@ impl TreeMap { } pub fn get(&self, key: &K) -> Option<&V> { - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); cursor.seek(&MapKeyRef(Some(key)), Bias::Left, &()); if let Some(item) = cursor.item() { if Some(key) == item.key().0.as_ref() { @@ -72,7 +72,7 @@ impl TreeMap { pub fn remove(&mut self, key: &K) -> Option { let mut removed = None; - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); let key = MapKeyRef(Some(key)); let mut new_tree = cursor.slice(&key, Bias::Left, &()); if key.cmp(&cursor.end(&()), &()) == Ordering::Equal { @@ -88,7 +88,7 @@ impl TreeMap { pub fn remove_range(&mut self, start: &impl MapSeekTarget, end: &impl MapSeekTarget) { let start = MapSeekTargetAdaptor(start); let end = MapSeekTargetAdaptor(end); - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); let mut new_tree = cursor.slice(&start, Bias::Left, &()); cursor.seek(&end, Bias::Left, &()); new_tree.append(cursor.suffix(&()), &()); @@ -98,7 +98,7 @@ impl TreeMap { /// Returns the key-value pair with the greatest key less than or equal to the given key. pub fn closest(&self, key: &K) -> Option<(&K, &V)> { - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); let key = MapKeyRef(Some(key)); cursor.seek(&key, Bias::Right, &()); cursor.prev(&()); @@ -106,7 +106,7 @@ impl TreeMap { } pub fn iter_from<'a>(&'a self, from: &'a K) -> impl Iterator + '_ { - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); let from_key = MapKeyRef(Some(from)); cursor.seek(&from_key, Bias::Left, &()); @@ -117,7 +117,7 @@ impl TreeMap { where F: FnOnce(&mut V) -> T, { - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); let key = MapKeyRef(Some(key)); let mut new_tree = cursor.slice(&key, Bias::Left, &()); let mut result = None; @@ -136,7 +136,7 @@ impl TreeMap { pub fn retain bool>(&mut self, mut predicate: F) { let mut new_map = SumTree::>::default(); - let mut cursor = self.0.cursor::>(); + let mut cursor = self.0.cursor::>(&()); cursor.next(&()); while let Some(item) = cursor.item() { if predicate(&item.key, &item.value) { @@ -247,6 +247,10 @@ where { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { *self = summary.clone() } @@ -256,6 +260,10 @@ impl<'a, K> Dimension<'a, MapKey> for MapKeyRef<'a, K> where K: Clone + Debug + Ord, { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a MapKey, _: &()) { self.0 = summary.0.as_ref(); } diff --git a/crates/text/src/anchor.rs b/crates/text/src/anchor.rs index ee833326f5..3bc5889cae 100644 --- a/crates/text/src/anchor.rs +++ b/crates/text/src/anchor.rs @@ -100,7 +100,7 @@ impl Anchor { false } else { let fragment_id = buffer.fragment_id_for_anchor(self); - let mut fragment_cursor = buffer.fragments.cursor::<(Option<&Locator>, usize)>(); + let mut fragment_cursor = buffer.fragments.cursor::<(Option<&Locator>, usize)>(&None); fragment_cursor.seek(&Some(fragment_id), Bias::Left, &None); fragment_cursor .item() diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index 83d57016c5..7afc16f581 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -85,6 +85,10 @@ impl sum_tree::KeyedItem for Locator { impl sum_tree::Summary for Locator { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { self.assign(summary); } diff --git a/crates/text/src/operation_queue.rs b/crates/text/src/operation_queue.rs index 063f050665..c7964f6267 100644 --- a/crates/text/src/operation_queue.rs +++ b/crates/text/src/operation_queue.rs @@ -34,7 +34,7 @@ impl Default for OperationQueue { impl OperationQueue { pub fn new() -> Self { - OperationQueue(SumTree::new()) + OperationQueue(SumTree::default()) } pub fn len(&self) -> usize { @@ -58,7 +58,7 @@ impl OperationQueue { pub fn drain(&mut self) -> Self { let clone = self.clone(); - self.0 = SumTree::new(); + self.0 = SumTree::default(); clone } @@ -70,6 +70,10 @@ impl OperationQueue { impl Summary for OperationSummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &()) { assert!(self.key < other.key); self.key = other.key; @@ -90,6 +94,10 @@ impl<'a> Add<&'a Self> for OperationSummary { } impl<'a> Dimension<'a, OperationSummary> for OperationKey { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &OperationSummary, _: &()) { assert!(*self <= summary.key); *self = summary.key; diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index b17748c6d0..9630ec5b80 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -492,6 +492,10 @@ struct FragmentTextSummary { } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary { + fn zero(_: &Option) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option) { self.visible += summary.text.visible; self.deleted += summary.text.deleted; @@ -654,8 +658,8 @@ impl Buffer { normalized: Rope, ) -> Buffer { let history = History::new(normalized); - let mut fragments = SumTree::new(); - let mut insertions = SumTree::new(); + let mut fragments = SumTree::new(&None); + let mut insertions = SumTree::default(); let mut lamport_clock = clock::Lamport::new(replica_id); let mut version = clock::Global::new(); @@ -772,7 +776,7 @@ impl Buffer { let mut new_ropes = RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); - let mut old_fragments = self.fragments.cursor::(); + let mut old_fragments = self.fragments.cursor::(&None); let mut new_fragments = old_fragments.slice(&edits.peek().unwrap().0.start, Bias::Right, &None); new_ropes.append(new_fragments.summary().text); @@ -992,7 +996,7 @@ impl Buffer { let mut insertion_offset = 0; let mut new_ropes = RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); - let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>(); + let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>(&cx); let mut new_fragments = old_fragments.slice( &VersionedFullOffset::Offset(ranges[0].start), Bias::Left, @@ -1185,7 +1189,7 @@ impl Buffer { // Get all of the fragments corresponding to these insertion slices. let mut fragment_ids = Vec::new(); - let mut insertions_cursor = self.insertions.cursor::(); + let mut insertions_cursor = self.insertions.cursor::(&()); for insertion_slice in &insertion_slices { if insertion_slice.insertion_id != insertions_cursor.start().timestamp || insertion_slice.range.start > insertions_cursor.start().split_offset @@ -1217,8 +1221,8 @@ impl Buffer { self.snapshot.undo_map.insert(undo); let mut edits = Patch::default(); - let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(); - let mut new_fragments = SumTree::new(); + let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(&None); + let mut new_fragments = SumTree::new(&None); let mut new_ropes = RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); @@ -1455,7 +1459,7 @@ impl Buffer { D: TextDimension, { // get fragment ranges - let mut cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(); + let mut cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None); let offset_ranges = self .fragment_ids_for_edits(transaction.edit_ids.iter()) .into_iter() @@ -1485,7 +1489,7 @@ impl Buffer { }); // convert to the desired text dimension. - let mut position = D::default(); + let mut position = D::zero(&()); let mut rope_cursor = self.visible_text.cursor(0); disjoint_ranges.map(move |range| { position.add_assign(&rope_cursor.summary(range.start)); @@ -1665,8 +1669,8 @@ impl Buffer { ); } - let mut cursor = self.snapshot.fragments.cursor::>(); - for insertion_fragment in self.snapshot.insertions.cursor::<()>() { + let mut cursor = self.snapshot.fragments.cursor::>(&None); + for insertion_fragment in self.snapshot.insertions.cursor::<()>(&()) { cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left, &None); let fragment = cursor.item().unwrap(); assert_eq!(insertion_fragment.fragment_id, fragment.id); @@ -1783,7 +1787,7 @@ impl BufferSnapshot { let mut cursor = self .fragments - .filter::<_, FragmentTextSummary>(move |summary| { + .filter::<_, FragmentTextSummary>(&None, move |summary| { !version.observed_all(&summary.max_version) }); cursor.next(&None); @@ -2110,14 +2114,14 @@ impl BufferSnapshot { A: 'a + IntoIterator, { let anchors = anchors.into_iter(); - let mut insertion_cursor = self.insertions.cursor::(); - let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(); + let mut insertion_cursor = self.insertions.cursor::(&()); + let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None); let mut text_cursor = self.visible_text.cursor(0); - let mut position = D::default(); + let mut position = D::zero(&()); anchors.map(move |(anchor, payload)| { if *anchor == Anchor::MIN { - return (D::default(), payload); + return (D::zero(&()), payload); } else if *anchor == Anchor::MAX { return (D::from_text_summary(&self.visible_text.summary()), payload); } @@ -2159,7 +2163,7 @@ impl BufferSnapshot { D: TextDimension, { if *anchor == Anchor::MIN { - D::default() + D::zero(&()) } else if *anchor == Anchor::MAX { D::from_text_summary(&self.visible_text.summary()) } else { @@ -2167,7 +2171,7 @@ impl BufferSnapshot { timestamp: anchor.timestamp, split_offset: anchor.offset, }; - let mut insertion_cursor = self.insertions.cursor::(); + let mut insertion_cursor = self.insertions.cursor::(&()); insertion_cursor.seek(&anchor_key, anchor.bias, &()); if let Some(insertion) = insertion_cursor.item() { let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); @@ -2192,7 +2196,7 @@ impl BufferSnapshot { ); }; - let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(); + let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None); fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None); let fragment = fragment_cursor.item().unwrap(); let mut fragment_offset = fragment_cursor.start().1; @@ -2213,7 +2217,7 @@ impl BufferSnapshot { timestamp: anchor.timestamp, split_offset: anchor.offset, }; - let mut insertion_cursor = self.insertions.cursor::(); + let mut insertion_cursor = self.insertions.cursor::(&()); insertion_cursor.seek(&anchor_key, anchor.bias, &()); if let Some(insertion) = insertion_cursor.item() { let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); @@ -2263,7 +2267,7 @@ impl BufferSnapshot { } else if bias == Bias::Right && offset == self.len() { Anchor::MAX } else { - let mut fragment_cursor = self.fragments.cursor::(); + let mut fragment_cursor = self.fragments.cursor::(&None); fragment_cursor.seek(&offset, bias, &None); let fragment = fragment_cursor.item().unwrap(); let overshoot = offset - *fragment_cursor.start(); @@ -2341,15 +2345,15 @@ impl BufferSnapshot { let fragments_cursor = if *since == self.version { None } else { - let mut cursor = self - .fragments - .filter(move |summary| !since.observed_all(&summary.max_version)); + let mut cursor = self.fragments.filter(&None, move |summary| { + !since.observed_all(&summary.max_version) + }); cursor.next(&None); Some(cursor) }; let mut cursor = self .fragments - .cursor::<(Option<&Locator>, FragmentTextSummary)>(); + .cursor::<(Option<&Locator>, FragmentTextSummary)>(&None); let start_fragment_id = self.fragment_id_for_anchor(&range.start); cursor.seek(&Some(start_fragment_id), Bias::Left, &None); @@ -2371,8 +2375,8 @@ impl BufferSnapshot { fragments_cursor, undos: &self.undo_map, since, - old_end: Default::default(), - new_end: Default::default(), + old_end: D::zero(&()), + new_end: D::zero(&()), range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset), buffer_id: self.remote_id, } @@ -2382,9 +2386,9 @@ impl BufferSnapshot { if *since != self.version { let start_fragment_id = self.fragment_id_for_anchor(&range.start); let end_fragment_id = self.fragment_id_for_anchor(&range.end); - let mut cursor = self - .fragments - .filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version)); + let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| { + !since.observed_all(&summary.max_version) + }); cursor.next(&None); while let Some(fragment) = cursor.item() { if fragment.id > *end_fragment_id { @@ -2405,9 +2409,9 @@ impl BufferSnapshot { pub fn has_edits_since(&self, since: &clock::Global) -> bool { if *since != self.version { - let mut cursor = self - .fragments - .filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version)); + let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| { + !since.observed_all(&summary.max_version) + }); cursor.next(&None); while let Some(fragment) = cursor.item() { let was_visible = fragment.was_visible(since, &self.undo_map); @@ -2644,6 +2648,10 @@ impl sum_tree::Item for Fragment { impl sum_tree::Summary for FragmentSummary { type Context = Option; + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, other: &Self, _: &Self::Context) { self.max_id.assign(&other.max_id); self.text.visible += &other.text.visible; @@ -2704,6 +2712,10 @@ impl InsertionFragment { impl sum_tree::Summary for InsertionFragmentKey { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &()) { *self = *summary; } @@ -2736,18 +2748,30 @@ impl ops::Sub for FullOffset { } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize { + fn zero(_: &Option) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &FragmentSummary, _: &Option) { *self += summary.text.visible; } } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset { + fn zero(_: &Option) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &FragmentSummary, _: &Option) { self.0 += summary.text.visible + summary.text.deleted; } } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> { + fn zero(_: &Option) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option) { *self = Some(&summary.max_id); } @@ -2786,6 +2810,10 @@ impl Default for VersionedFullOffset { } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset { + fn zero(_cx: &Option) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option) { if let Self::Offset(offset) = self { let version = cx.as_ref().unwrap(); diff --git a/crates/text/src/undo_map.rs b/crates/text/src/undo_map.rs index f95809c02e..4e670fd456 100644 --- a/crates/text/src/undo_map.rs +++ b/crates/text/src/undo_map.rs @@ -33,6 +33,10 @@ struct UndoMapKey { impl sum_tree::Summary for UndoMapKey { type Context = (); + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &Self::Context) { *self = cmp::max(*self, *summary); } @@ -62,9 +66,8 @@ impl UndoMap { pub fn is_undone(&self, edit_id: clock::Lamport) -> bool { self.undo_count(edit_id) % 2 == 1 } - pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool { - let mut cursor = self.0.cursor::(); + let mut cursor = self.0.cursor::(&()); cursor.seek( &UndoMapKey { edit_id, @@ -89,7 +92,7 @@ impl UndoMap { } pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 { - let mut cursor = self.0.cursor::(); + let mut cursor = self.0.cursor::(&()); cursor.seek( &UndoMapKey { edit_id, diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 776c01c49c..d8555b71a4 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -2049,7 +2049,7 @@ impl Snapshot { fn delete_entry(&mut self, entry_id: ProjectEntryId) -> Option> { let removed_entry = self.entries_by_id.remove(&entry_id, &())?; self.entries_by_path = { - let mut cursor = self.entries_by_path.cursor::(); + let mut cursor = self.entries_by_path.cursor::(&()); let mut new_entries_by_path = cursor.slice(&TraversalTarget::Path(&removed_entry.path), Bias::Left, &()); while let Some(entry) = cursor.item() { @@ -2192,7 +2192,7 @@ impl Snapshot { include_ignored: bool, start_offset: usize, ) -> Traversal { - let mut cursor = self.entries_by_path.cursor(); + let mut cursor = self.entries_by_path.cursor(&()); cursor.seek( &TraversalTarget::Count { count: start_offset, @@ -2302,7 +2302,7 @@ impl Snapshot { pub fn propagate_git_statuses(&self, result: &mut [Entry]) { let mut cursor = self .entries_by_path - .cursor::<(TraversalProgress, GitStatuses)>(); + .cursor::<(TraversalProgress, GitStatuses)>(&()); let mut entry_stack = Vec::<(usize, GitStatuses)>::new(); let mut result_ix = 0; @@ -2358,13 +2358,13 @@ impl Snapshot { pub fn paths(&self) -> impl Iterator> { let empty_path = Path::new(""); self.entries_by_path - .cursor::<()>() + .cursor::<()>(&()) .filter(move |entry| entry.path.as_ref() != empty_path) .map(|entry| &entry.path) } pub fn child_entries<'a>(&'a self, parent_path: &'a Path) -> ChildEntriesIter<'a> { - let mut cursor = self.entries_by_path.cursor(); + let mut cursor = self.entries_by_path.cursor(&()); cursor.seek(&TraversalTarget::Path(parent_path), Bias::Right, &()); let traversal = Traversal { cursor, @@ -2581,7 +2581,7 @@ impl LocalSnapshot { #[cfg(test)] pub(crate) fn expanded_entries(&self) -> impl Iterator { self.entries_by_path - .cursor::<()>() + .cursor::<()>(&()) .filter(|entry| entry.kind == EntryKind::Dir && (entry.is_external || entry.is_ignored)) } @@ -2591,11 +2591,11 @@ impl LocalSnapshot { assert_eq!( self.entries_by_path - .cursor::<()>() + .cursor::<()>(&()) .map(|e| (&e.path, e.id)) .collect::>(), self.entries_by_id - .cursor::<()>() + .cursor::<()>(&()) .map(|e| (&e.path, e.id)) .collect::>() .into_iter() @@ -2605,7 +2605,7 @@ impl LocalSnapshot { let mut files = self.files(true, 0); let mut visible_files = self.files(false, 0); - for entry in self.entries_by_path.cursor::<()>() { + for entry in self.entries_by_path.cursor::<()>(&()) { if entry.is_file() { assert_eq!(files.next().unwrap().inode, entry.inode); if !entry.is_ignored && !entry.is_external { @@ -2633,7 +2633,7 @@ impl LocalSnapshot { let dfs_paths_via_iter = self .entries_by_path - .cursor::<()>() + .cursor::<()>(&()) .map(|e| e.path.as_ref()) .collect::>(); assert_eq!(bfs_paths, dfs_paths_via_iter); @@ -2679,7 +2679,7 @@ impl LocalSnapshot { #[cfg(test)] pub fn entries_without_ids(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> { let mut paths = Vec::new(); - for entry in self.entries_by_path.cursor::<()>() { + for entry in self.entries_by_path.cursor::<()>(&()) { if include_ignored || !entry.is_ignored { paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored)); } @@ -2839,7 +2839,10 @@ impl BackgroundScannerState { let mut new_entries; let removed_entries; { - let mut cursor = self.snapshot.entries_by_path.cursor::(); + let mut cursor = self + .snapshot + .entries_by_path + .cursor::(&()); new_entries = cursor.slice(&TraversalTarget::Path(path), Bias::Left, &()); removed_entries = cursor.slice(&TraversalTarget::PathSuccessor(path), Bias::Left, &()); new_entries.append(cursor.suffix(&()), &()); @@ -2847,7 +2850,7 @@ impl BackgroundScannerState { self.snapshot.entries_by_path = new_entries; let mut removed_ids = Vec::with_capacity(removed_entries.summary().count); - for entry in removed_entries.cursor::<()>() { + for entry in removed_entries.cursor::<()>(&()) { match self.removed_entries.entry(entry.inode) { hash_map::Entry::Occupied(mut e) => { let prev_removed_entry = e.get_mut(); @@ -3403,6 +3406,10 @@ impl Default for EntrySummary { impl sum_tree::Summary for EntrySummary { type Context = (); + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, rhs: &Self, _: &()) { self.max_path = rhs.max_path.clone(); self.count += rhs.count; @@ -3445,12 +3452,20 @@ struct PathEntrySummary { impl sum_tree::Summary for PathEntrySummary { type Context = (); + fn zero(_cx: &Self::Context) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &Self, _: &Self::Context) { self.max_id = summary.max_id; } } impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a PathEntrySummary, _: &()) { *self = summary.max_id; } @@ -3466,6 +3481,10 @@ impl Default for PathKey { } impl<'a> sum_tree::Dimension<'a, EntrySummary> for PathKey { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) { self.0 = summary.max_path.clone(); } @@ -4629,8 +4648,8 @@ impl BackgroundScanner { // Identify which paths have changed. Use the known set of changed // parent paths to optimize the search. let mut changes = Vec::new(); - let mut old_paths = old_snapshot.entries_by_path.cursor::(); - let mut new_paths = new_snapshot.entries_by_path.cursor::(); + let mut old_paths = old_snapshot.entries_by_path.cursor::(&()); + let mut new_paths = new_snapshot.entries_by_path.cursor::(&()); let mut last_newly_loaded_dir_path = None; old_paths.next(&()); new_paths.next(&()); @@ -4981,6 +5000,10 @@ impl<'a> TraversalProgress<'a> { } impl<'a> sum_tree::Dimension<'a, EntrySummary> for TraversalProgress<'a> { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) { self.max_path = summary.max_path.as_ref(); self.count += summary.count; @@ -5030,6 +5053,10 @@ impl Sub for GitStatuses { } impl<'a> sum_tree::Dimension<'a, EntrySummary> for GitStatuses { + fn zero(_cx: &()) -> Self { + Default::default() + } + fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) { *self += summary.statuses } @@ -5050,7 +5077,7 @@ impl<'a> Traversal<'a> { include_ignored: bool, start_path: &Path, ) -> Self { - let mut cursor = entries.cursor(); + let mut cursor = entries.cursor(&()); cursor.seek(&TraversalTarget::Path(start_path), Bias::Left, &()); let mut traversal = Self { cursor,