Replace Default trait bound with a zero function on Summary/Dimension (#17975)

This lets us provide a context when constructing the zero value. We need
it so we can require anchors to be associated with a buffer id, which
we're doing as part of simplifying the multibuffer API.

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-09-17 19:43:59 -06:00 committed by GitHub
parent 4d074fc737
commit 2e72fd210a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 706 additions and 349 deletions

View File

@ -332,7 +332,7 @@ impl ChannelChat {
.update(&mut cx, |chat, cx| { .update(&mut cx, |chat, cx| {
if let Some(first_id) = chat.first_loaded_message_id() { if let Some(first_id) = chat.first_loaded_message_id() {
if first_id <= 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); let message_id = ChannelMessageId::Saved(message_id);
cursor.seek(&message_id, Bias::Left, &()); cursor.seek(&message_id, Bias::Left, &());
return ControlFlow::Break( return ControlFlow::Break(
@ -498,7 +498,7 @@ impl ChannelChat {
} }
pub fn message(&self, ix: usize) -> &ChannelMessage { pub fn message(&self, ix: usize) -> &ChannelMessage {
let mut cursor = self.messages.cursor::<Count>(); let mut cursor = self.messages.cursor::<Count>(&());
cursor.seek(&Count(ix), Bias::Right, &()); cursor.seek(&Count(ix), Bias::Right, &());
cursor.item().unwrap() cursor.item().unwrap()
} }
@ -515,13 +515,13 @@ impl ChannelChat {
} }
pub fn messages_in_range(&self, range: Range<usize>) -> impl Iterator<Item = &ChannelMessage> { pub fn messages_in_range(&self, range: Range<usize>) -> impl Iterator<Item = &ChannelMessage> {
let mut cursor = self.messages.cursor::<Count>(); let mut cursor = self.messages.cursor::<Count>(&());
cursor.seek(&Count(range.start), Bias::Right, &()); cursor.seek(&Count(range.start), Bias::Right, &());
cursor.take(range.len()) cursor.take(range.len())
} }
pub fn pending_messages(&self) -> impl Iterator<Item = &ChannelMessage> { pub fn pending_messages(&self) -> impl Iterator<Item = &ChannelMessage> {
let mut cursor = self.messages.cursor::<ChannelMessageId>(); let mut cursor = self.messages.cursor::<ChannelMessageId>(&());
cursor.seek(&ChannelMessageId::Pending(0), Bias::Left, &()); cursor.seek(&ChannelMessageId::Pending(0), Bias::Left, &());
cursor cursor
} }
@ -589,11 +589,11 @@ impl ChannelChat {
fn insert_messages(&mut self, messages: SumTree<ChannelMessage>, cx: &mut ModelContext<Self>) { fn insert_messages(&mut self, messages: SumTree<ChannelMessage>, cx: &mut ModelContext<Self>) {
if let Some((first_message, last_message)) = messages.first().zip(messages.last()) { if let Some((first_message, last_message)) = messages.first().zip(messages.last()) {
let nonces = messages let nonces = messages
.cursor::<()>() .cursor::<()>(&())
.map(|m| m.nonce) .map(|m| m.nonce)
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
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 mut new_messages = old_cursor.slice(&first_message.id, Bias::Left, &());
let start_ix = old_cursor.start().1 .0; let start_ix = old_cursor.start().1 .0;
let removed_messages = old_cursor.slice(&last_message.id, Bias::Right, &()); 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<Self>) { fn message_removed(&mut self, id: u64, cx: &mut ModelContext<Self>) {
let mut cursor = self.messages.cursor::<ChannelMessageId>(); let mut cursor = self.messages.cursor::<ChannelMessageId>(&());
let mut messages = cursor.slice(&ChannelMessageId::Saved(id), Bias::Left, &()); let mut messages = cursor.slice(&ChannelMessageId::Saved(id), Bias::Left, &());
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if item.id == ChannelMessageId::Saved(id) { if item.id == ChannelMessageId::Saved(id) {
@ -685,7 +685,7 @@ impl ChannelChat {
edited_at: Option<OffsetDateTime>, edited_at: Option<OffsetDateTime>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) { ) {
let mut cursor = self.messages.cursor::<ChannelMessageId>(); let mut cursor = self.messages.cursor::<ChannelMessageId>(&());
let mut messages = cursor.slice(&id, Bias::Left, &()); let mut messages = cursor.slice(&id, Bias::Left, &());
let ix = messages.summary().count; let ix = messages.summary().count;
@ -716,7 +716,7 @@ async fn messages_from_proto(
cx: &mut AsyncAppContext, cx: &mut AsyncAppContext,
) -> Result<SumTree<ChannelMessage>> { ) -> Result<SumTree<ChannelMessage>> {
let messages = ChannelMessage::from_proto_vec(proto_messages, user_store, cx).await?; 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, &()); result.extend(messages, &());
Ok(result) Ok(result)
} }
@ -825,6 +825,10 @@ impl Default for ChannelMessageId {
impl sum_tree::Summary for ChannelMessageSummary { impl sum_tree::Summary for ChannelMessageSummary {
type Context = (); type Context = ();
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.max_id = summary.max_id; self.max_id = summary.max_id;
self.count += summary.count; self.count += summary.count;
@ -832,6 +836,10 @@ impl sum_tree::Summary for ChannelMessageSummary {
} }
impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for ChannelMessageId { impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for ChannelMessageId {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) {
debug_assert!(summary.max_id > *self); debug_assert!(summary.max_id > *self);
*self = summary.max_id; *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 { impl<'a> sum_tree::Dimension<'a, ChannelMessageSummary> for Count {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChannelMessageSummary, _: &()) {
self.0 += summary.count; self.0 += summary.count;
} }

View File

@ -127,7 +127,9 @@ impl DisplayMap {
let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe()); let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
let tab_size = Self::tab_size(&buffer, cx); 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 (fold_map, snapshot) = FoldMap::new(snapshot);
let (tab_map, snapshot) = TabMap::new(snapshot, tab_size); let (tab_map, snapshot) = TabMap::new(snapshot, tab_size);
let (wrap_map, snapshot) = WrapMap::new(snapshot, font, font_size, wrap_width, cx); let (wrap_map, snapshot) = WrapMap::new(snapshot, font, font_size, wrap_width, cx);
@ -138,7 +140,6 @@ impl DisplayMap {
excerpt_header_height, excerpt_header_height,
excerpt_footer_height, excerpt_footer_height,
); );
let crease_map = CreaseMap::default();
cx.observe(&wrap_map, |_, _, cx| cx.notify()).detach(); cx.observe(&wrap_map, |_, _, cx| cx.notify()).detach();

View File

@ -389,10 +389,10 @@ impl BlockMap {
} }
let mut transforms = self.transforms.borrow_mut(); 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 old_row_count = transforms.summary().input_rows;
let new_row_count = wrap_snapshot.max_point().row() + 1; let new_row_count = wrap_snapshot.max_point().row() + 1;
let mut cursor = transforms.cursor::<WrapRow>(); let mut cursor = transforms.cursor::<WrapRow>(&());
let mut last_block_ix = 0; let mut last_block_ix = 0;
let mut blocks_in_edit = Vec::new(); let mut blocks_in_edit = Vec::new();
let mut edits = edits.into_iter().peekable(); let mut edits = edits.into_iter().peekable();
@ -757,7 +757,7 @@ impl<'a> BlockMapReader<'a> {
.unwrap_or(self.wrap_snapshot.max_point().row() + 1), .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, &()); cursor.seek(&start_wrap_row, Bias::Left, &());
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if cursor.start().0 > end_wrap_row { if cursor.start().0 > end_wrap_row {
@ -950,7 +950,7 @@ impl BlockSnapshot {
highlights: Highlights<'a>, highlights: Highlights<'a>,
) -> BlockChunks<'a> { ) -> BlockChunks<'a> {
let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); 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 = { let input_end = {
cursor.seek(&BlockRow(rows.end), Bias::Right, &()); cursor.seek(&BlockRow(rows.end), Bias::Right, &());
let overshoot = if cursor let overshoot = if cursor
@ -990,7 +990,7 @@ impl BlockSnapshot {
} }
pub(super) fn buffer_rows(&self, start_row: BlockRow) -> BlockBufferRows { 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, &()); cursor.seek(&start_row, Bias::Right, &());
let (output_start, input_start) = cursor.start(); let (output_start, input_start) = cursor.start();
let overshoot = if cursor.item().map_or(false, |t| t.is_isomorphic()) { 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<u32>) -> impl Iterator<Item = (u32, &Block)> { pub fn blocks_in_range(&self, rows: Range<u32>) -> impl Iterator<Item = (u32, &Block)> {
let mut cursor = self.transforms.cursor::<BlockRow>(); let mut cursor = self.transforms.cursor::<BlockRow>(&());
cursor.seek(&BlockRow(rows.start), Bias::Left, &()); cursor.seek(&BlockRow(rows.start), Bias::Left, &());
while cursor.start().0 < rows.start && cursor.end(&()).0 <= rows.start { while cursor.start().0 < rows.start && cursor.end(&()).0 <= rows.start {
cursor.next(&()); cursor.next(&());
@ -1050,7 +1050,7 @@ impl BlockSnapshot {
let wrap_point = self let wrap_point = self
.wrap_snapshot .wrap_snapshot
.make_wrap_point(excerpt_range.start, Bias::Left); .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, &()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Left, &());
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if let Some(block) = transform.block.as_ref() { if let Some(block) = transform.block.as_ref() {
@ -1072,7 +1072,7 @@ impl BlockSnapshot {
.wrap_snapshot .wrap_snapshot
.make_wrap_point(excerpt_range.end, Bias::Left); .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, &()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Left, &());
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if let Some(block) = transform.block.as_ref() { if let Some(block) = transform.block.as_ref() {
@ -1102,7 +1102,7 @@ impl BlockSnapshot {
} }
pub(super) fn line_len(&self, row: BlockRow) -> u32 { 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, &()); cursor.seek(&BlockRow(row.0), Bias::Right, &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let (output_start, input_start) = cursor.start(); let (output_start, input_start) = cursor.start();
@ -1118,13 +1118,13 @@ impl BlockSnapshot {
} }
pub(super) fn is_block_line(&self, row: BlockRow) -> bool { 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.seek(&row, Bias::Right, &());
cursor.item().map_or(false, |t| t.block.is_some()) cursor.item().map_or(false, |t| t.block.is_some())
} }
pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint { 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, &()); cursor.seek(&BlockRow(point.row), Bias::Right, &());
let max_input_row = WrapRow(self.transforms.summary().input_rows); 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 { 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, &()); cursor.seek(&WrapRow(wrap_point.row()), Bias::Right, &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
debug_assert!(transform.is_isomorphic()); debug_assert!(transform.is_isomorphic());
@ -1188,7 +1188,7 @@ impl BlockSnapshot {
} }
pub fn to_wrap_point(&self, block_point: BlockPoint) -> WrapPoint { 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, &()); cursor.seek(&BlockRow(block_point.row), Bias::Right, &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
match transform.block.as_ref().map(|b| b.disposition()) { 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 { impl sum_tree::Summary for TransformSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.input_rows += summary.input_rows; self.input_rows += summary.input_rows;
self.output_rows += summary.output_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 { impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapRow {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += summary.input_rows; self.0 += summary.input_rows;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow { impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += summary.output_rows; self.0 += summary.output_rows;
} }

View File

@ -12,19 +12,34 @@ use crate::FoldPlaceholder;
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct CreaseId(usize); pub struct CreaseId(usize);
#[derive(Default)]
pub struct CreaseMap { pub struct CreaseMap {
snapshot: CreaseSnapshot, snapshot: CreaseSnapshot,
next_id: CreaseId, next_id: CreaseId,
id_to_range: HashMap<CreaseId, Range<Anchor>>, id_to_range: HashMap<CreaseId, Range<Anchor>>,
} }
#[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 { pub struct CreaseSnapshot {
creases: SumTree<CreaseItem>, creases: SumTree<CreaseItem>,
} }
impl CreaseSnapshot { impl CreaseSnapshot {
pub fn new(snapshot: &MultiBufferSnapshot) -> Self {
CreaseSnapshot {
creases: SumTree::new(snapshot),
}
}
/// Returns the first Crease starting on the specified buffer row. /// Returns the first Crease starting on the specified buffer row.
pub fn query_row<'a>( pub fn query_row<'a>(
&'a self, &'a self,
@ -32,7 +47,7 @@ impl CreaseSnapshot {
snapshot: &'a MultiBufferSnapshot, snapshot: &'a MultiBufferSnapshot,
) -> Option<&'a Crease> { ) -> Option<&'a Crease> {
let start = snapshot.anchor_before(Point::new(row.0, 0)); let start = snapshot.anchor_before(Point::new(row.0, 0));
let mut cursor = self.creases.cursor::<ItemSummary>(); let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
cursor.seek(&start, Bias::Left, snapshot); cursor.seek(&start, Bias::Left, snapshot);
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
match Ord::cmp(&item.crease.range.start.to_point(snapshot).row, &row.0) { match Ord::cmp(&item.crease.range.start.to_point(snapshot).row, &row.0) {
@ -56,7 +71,7 @@ impl CreaseSnapshot {
snapshot: &'a MultiBufferSnapshot, snapshot: &'a MultiBufferSnapshot,
) -> impl '_ + Iterator<Item = &'a Crease> { ) -> impl '_ + Iterator<Item = &'a Crease> {
let start = snapshot.anchor_before(Point::new(range.start.0, 0)); let start = snapshot.anchor_before(Point::new(range.start.0, 0));
let mut cursor = self.creases.cursor::<ItemSummary>(); let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
cursor.seek(&start, Bias::Left, snapshot); cursor.seek(&start, Bias::Left, snapshot);
std::iter::from_fn(move || { std::iter::from_fn(move || {
@ -79,7 +94,7 @@ impl CreaseSnapshot {
&self, &self,
snapshot: &MultiBufferSnapshot, snapshot: &MultiBufferSnapshot,
) -> Vec<(CreaseId, Range<Point>)> { ) -> Vec<(CreaseId, Range<Point>)> {
let mut cursor = self.creases.cursor::<ItemSummary>(); let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
let mut results = Vec::new(); let mut results = Vec::new();
cursor.next(snapshot); cursor.next(snapshot);
@ -194,8 +209,8 @@ impl CreaseMap {
) -> Vec<CreaseId> { ) -> Vec<CreaseId> {
let mut new_ids = Vec::new(); let mut new_ids = Vec::new();
self.snapshot.creases = { self.snapshot.creases = {
let mut new_creases = SumTree::new(); let mut new_creases = SumTree::new(snapshot);
let mut cursor = self.snapshot.creases.cursor::<ItemSummary>(); let mut cursor = self.snapshot.creases.cursor::<ItemSummary>(snapshot);
for crease in creases { for crease in creases {
new_creases.append(cursor.slice(&crease.range, Bias::Left, snapshot), snapshot); new_creases.append(cursor.slice(&crease.range, Bias::Left, snapshot), snapshot);
@ -227,8 +242,8 @@ impl CreaseMap {
}); });
self.snapshot.creases = { self.snapshot.creases = {
let mut new_creases = SumTree::new(); let mut new_creases = SumTree::new(snapshot);
let mut cursor = self.snapshot.creases.cursor::<ItemSummary>(); let mut cursor = self.snapshot.creases.cursor::<ItemSummary>(snapshot);
for (id, range) in removals { for (id, range) in removals {
new_creases.append(cursor.slice(&range, Bias::Left, snapshot), snapshot); new_creases.append(cursor.slice(&range, Bias::Left, snapshot), snapshot);
@ -264,6 +279,10 @@ impl Default for ItemSummary {
impl sum_tree::Summary for ItemSummary { impl sum_tree::Summary for ItemSummary {
type Context = MultiBufferSnapshot; type Context = MultiBufferSnapshot;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _snapshot: &MultiBufferSnapshot) { fn add_summary(&mut self, other: &Self, _snapshot: &MultiBufferSnapshot) {
self.range = other.range.clone(); self.range = other.range.clone();
} }
@ -303,7 +322,7 @@ mod test {
let text = "line1\nline2\nline3\nline4\nline5"; let text = "line1\nline2\nline3\nline4\nline5";
let buffer = MultiBuffer::build_simple(text, cx); let buffer = MultiBuffer::build_simple(text, cx);
let snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(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 // Insert creases
let creases = [ let creases = [
@ -350,7 +369,7 @@ mod test {
let text = "line1\nline2\nline3\nline4\nline5\nline6\nline7"; let text = "line1\nline2\nline3\nline4\nline5\nline6\nline7";
let buffer = MultiBuffer::build_simple(text, cx); let buffer = MultiBuffer::build_simple(text, cx);
let snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(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 = [ let creases = [
Crease::new( Crease::new(

View File

@ -79,7 +79,7 @@ impl FoldPoint {
} }
pub fn to_inlay_point(self, snapshot: &FoldSnapshot) -> InlayPoint { 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, &()); cursor.seek(&self, Bias::Right, &());
let overshoot = self.0 - cursor.start().0 .0; let overshoot = self.0 - cursor.start().0 .0;
InlayPoint(cursor.start().1 .0 + overshoot) InlayPoint(cursor.start().1 .0 + overshoot)
@ -88,7 +88,7 @@ impl FoldPoint {
pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset { pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<(FoldPoint, TransformSummary)>(); .cursor::<(FoldPoint, TransformSummary)>(&());
cursor.seek(&self, Bias::Right, &()); cursor.seek(&self, Bias::Right, &());
let overshoot = self.0 - cursor.start().1.output.lines; let overshoot = self.0 - cursor.start().1.output.lines;
let mut offset = cursor.start().1.output.len; let mut offset = cursor.start().1.output.len;
@ -105,6 +105,10 @@ impl FoldPoint {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.output.lines; 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)); folds.sort_unstable_by(|a, b| sum_tree::SeekTarget::cmp(&a.range, &b.range, buffer));
self.0.snapshot.folds = { self.0.snapshot.folds = {
let mut new_tree = SumTree::new(); let mut new_tree = SumTree::new(buffer);
let mut cursor = self.0.snapshot.folds.cursor::<FoldRange>(); let mut cursor = self.0.snapshot.folds.cursor::<FoldRange>(buffer);
for fold in folds { for fold in folds {
new_tree.append(cursor.slice(&fold.range, Bias::Right, buffer), buffer); new_tree.append(cursor.slice(&fold.range, Bias::Right, buffer), buffer);
new_tree.push(fold, buffer); new_tree.push(fold, buffer);
@ -202,8 +206,8 @@ impl<'a> FoldMapWriter<'a> {
fold_ixs_to_delete.dedup(); fold_ixs_to_delete.dedup();
self.0.snapshot.folds = { self.0.snapshot.folds = {
let mut cursor = self.0.snapshot.folds.cursor::<usize>(); let mut cursor = self.0.snapshot.folds.cursor::<usize>(buffer);
let mut folds = SumTree::new(); let mut folds = SumTree::new(buffer);
for fold_ix in fold_ixs_to_delete { for fold_ix in fold_ixs_to_delete {
folds.append(cursor.slice(&fold_ix, Bias::Right, buffer), buffer); folds.append(cursor.slice(&fold_ix, Bias::Right, buffer), buffer);
cursor.next(buffer); cursor.next(buffer);
@ -230,7 +234,7 @@ impl FoldMap {
pub(crate) fn new(inlay_snapshot: InlaySnapshot) -> (Self, FoldSnapshot) { pub(crate) fn new(inlay_snapshot: InlaySnapshot) -> (Self, FoldSnapshot) {
let this = Self { let this = Self {
snapshot: FoldSnapshot { snapshot: FoldSnapshot {
folds: Default::default(), folds: SumTree::new(&inlay_snapshot.buffer),
transforms: SumTree::from_item( transforms: SumTree::from_item(
Transform { Transform {
summary: TransformSummary { summary: TransformSummary {
@ -314,8 +318,8 @@ impl FoldMap {
} else { } else {
let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable(); let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable();
let mut new_transforms = SumTree::<Transform>::new(); let mut new_transforms = SumTree::<Transform>::default();
let mut cursor = self.snapshot.transforms.cursor::<InlayOffset>(); let mut cursor = self.snapshot.transforms.cursor::<InlayOffset>(&());
cursor.seek(&InlayOffset(0), Bias::Right, &()); cursor.seek(&InlayOffset(0), Bias::Right, &());
while let Some(mut edit) = inlay_edits_iter.next() { while let Some(mut edit) = inlay_edits_iter.next() {
@ -367,7 +371,10 @@ impl FoldMap {
let anchor = inlay_snapshot let anchor = inlay_snapshot
.buffer .buffer
.anchor_before(inlay_snapshot.to_buffer_offset(edit.new.start)); .anchor_before(inlay_snapshot.to_buffer_offset(edit.new.start));
let mut folds_cursor = self.snapshot.folds.cursor::<FoldRange>(); let mut folds_cursor = self
.snapshot
.folds
.cursor::<FoldRange>(&inlay_snapshot.buffer);
folds_cursor.seek( folds_cursor.seek(
&FoldRange(anchor..Anchor::max()), &FoldRange(anchor..Anchor::max()),
Bias::Left, Bias::Left,
@ -470,8 +477,8 @@ impl FoldMap {
let mut old_transforms = self let mut old_transforms = self
.snapshot .snapshot
.transforms .transforms
.cursor::<(InlayOffset, FoldOffset)>(); .cursor::<(InlayOffset, FoldOffset)>(&());
let mut new_transforms = new_transforms.cursor::<(InlayOffset, FoldOffset)>(); let mut new_transforms = new_transforms.cursor::<(InlayOffset, FoldOffset)>(&());
for mut edit in inlay_edits { for mut edit in inlay_edits {
old_transforms.seek(&edit.old.start, Bias::Left, &()); old_transforms.seek(&edit.old.start, Bias::Left, &());
@ -545,7 +552,7 @@ impl FoldSnapshot {
pub fn text_summary_for_range(&self, range: Range<FoldPoint>) -> TextSummary { pub fn text_summary_for_range(&self, range: Range<FoldPoint>) -> TextSummary {
let mut summary = TextSummary::default(); 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, &()); cursor.seek(&range.start, Bias::Right, &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let start_in_transform = range.start.0 - cursor.start().0 .0; 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 { 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, &()); cursor.seek(&point, Bias::Right, &());
if cursor.item().map_or(false, |t| t.is_fold()) { if cursor.item().map_or(false, |t| t.is_fold()) {
if bias == Bias::Left || point == cursor.start().0 { if bias == Bias::Left || point == cursor.start().0 {
@ -631,7 +638,7 @@ impl FoldSnapshot {
} }
let fold_point = FoldPoint::new(start_row, 0); 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, &()); cursor.seek(&fold_point, Bias::Left, &());
let overshoot = fold_point.0 - cursor.start().0 .0; 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 buffer_offset = offset.to_offset(&self.inlay_snapshot.buffer);
let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset); let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset);
let mut cursor = self.transforms.cursor::<InlayOffset>(); let mut cursor = self.transforms.cursor::<InlayOffset>(&());
cursor.seek(&inlay_offset, Bias::Right, &()); cursor.seek(&inlay_offset, Bias::Right, &());
cursor.item().map_or(false, |t| t.placeholder.is_some()) cursor.item().map_or(false, |t| t.placeholder.is_some())
} }
@ -681,7 +688,7 @@ impl FoldSnapshot {
let mut inlay_point = self let mut inlay_point = self
.inlay_snapshot .inlay_snapshot
.to_inlay_point(Point::new(buffer_row.0, 0)); .to_inlay_point(Point::new(buffer_row.0, 0));
let mut cursor = self.transforms.cursor::<InlayPoint>(); let mut cursor = self.transforms.cursor::<InlayPoint>(&());
cursor.seek(&inlay_point, Bias::Right, &()); cursor.seek(&inlay_point, Bias::Right, &());
loop { loop {
match cursor.item() { match cursor.item() {
@ -711,7 +718,7 @@ impl FoldSnapshot {
language_aware: bool, language_aware: bool,
highlights: Highlights<'a>, highlights: Highlights<'a>,
) -> FoldChunks<'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, &()); transform_cursor.seek(&range.start, Bias::Right, &());
let inlay_start = { let inlay_start = {
@ -766,7 +773,7 @@ impl FoldSnapshot {
} }
pub fn clip_point(&self, point: FoldPoint, bias: Bias) -> FoldPoint { 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, &()); cursor.seek(&point, Bias::Right, &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let transform_start = cursor.start().0 .0; let transform_start = cursor.start().0 .0;
@ -826,7 +833,7 @@ where
let buffer = &inlay_snapshot.buffer; let buffer = &inlay_snapshot.buffer;
let start = buffer.anchor_before(range.start.to_offset(buffer)); let start = buffer.anchor_before(range.start.to_offset(buffer));
let end = buffer.anchor_after(range.end.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 start_cmp = start.cmp(&summary.max_end, buffer);
let end_cmp = end.cmp(&summary.min_start, 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 { impl sum_tree::Summary for TransformSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
@ -1028,6 +1039,10 @@ impl Default for FoldSummary {
impl sum_tree::Summary for FoldSummary { impl sum_tree::Summary for FoldSummary {
type Context = MultiBufferSnapshot; type Context = MultiBufferSnapshot;
fn zero(_cx: &MultiBufferSnapshot) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less { if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less {
self.min_start = other.min_start; 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 { 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) { fn add_summary(&mut self, summary: &'a FoldSummary, _: &MultiBufferSnapshot) {
self.0.start = summary.start; self.0.start = summary.start;
self.0.end = summary.end; 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 { 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) { fn add_summary(&mut self, summary: &'a FoldSummary, _: &MultiBufferSnapshot) {
*self += summary.count; *self += summary.count;
} }
@ -1196,7 +1219,7 @@ impl FoldOffset {
pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint { pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<(FoldOffset, TransformSummary)>(); .cursor::<(FoldOffset, TransformSummary)>(&());
cursor.seek(&self, Bias::Right, &()); cursor.seek(&self, Bias::Right, &());
let overshoot = if cursor.item().map_or(true, |t| t.is_fold()) { let overshoot = if cursor.item().map_or(true, |t| t.is_fold()) {
Point::new(0, (self.0 - cursor.start().0 .0) as u32) Point::new(0, (self.0 - cursor.start().0 .0) as u32)
@ -1210,7 +1233,7 @@ impl FoldOffset {
#[cfg(test)] #[cfg(test)]
pub fn to_inlay_offset(self, snapshot: &FoldSnapshot) -> InlayOffset { 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, &()); cursor.seek(&self, Bias::Right, &());
let overshoot = self.0 - cursor.start().0 .0; let overshoot = self.0 - cursor.start().0 .0;
InlayOffset(cursor.start().1 .0 + overshoot) InlayOffset(cursor.start().1 .0 + overshoot)
@ -1240,18 +1263,30 @@ impl Sub for FoldOffset {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.output.len; self.0 += &summary.output.len;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.input.lines; self.0 += &summary.input.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.input.len; self.0 += &summary.input.len;
} }

View File

@ -97,6 +97,10 @@ struct TransformSummary {
impl sum_tree::Summary for TransformSummary { impl sum_tree::Summary for TransformSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
@ -137,6 +141,10 @@ impl SubAssign for InlayOffset {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.output.len; self.0 += &summary.output.len;
} }
@ -162,18 +170,30 @@ impl Sub for InlayPoint {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.output.lines; self.0 += &summary.output.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.input.len; *self += &summary.input.len;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point { impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.input.lines; *self += &summary.input.lines;
} }
@ -475,8 +495,8 @@ impl InlayMap {
(snapshot.clone(), Vec::new()) (snapshot.clone(), Vec::new())
} else { } else {
let mut inlay_edits = Patch::default(); let mut inlay_edits = Patch::default();
let mut new_transforms = SumTree::new(); let mut new_transforms = SumTree::default();
let mut cursor = snapshot.transforms.cursor::<(usize, InlayOffset)>(); let mut cursor = snapshot.transforms.cursor::<(usize, InlayOffset)>(&());
let mut buffer_edits_iter = buffer_edits.iter().peekable(); let mut buffer_edits_iter = buffer_edits.iter().peekable();
while let Some(buffer_edit) = buffer_edits_iter.next() { while let Some(buffer_edit) = buffer_edits_iter.next() {
new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left, &()), &()); 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 { pub fn to_point(&self, offset: InlayOffset) -> InlayPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<(InlayOffset, (InlayPoint, usize))>(); .cursor::<(InlayOffset, (InlayPoint, usize))>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
let overshoot = offset.0 - cursor.start().0 .0; let overshoot = offset.0 - cursor.start().0 .0;
match cursor.item() { match cursor.item() {
@ -723,7 +743,7 @@ impl InlaySnapshot {
pub fn to_offset(&self, point: InlayPoint) -> InlayOffset { pub fn to_offset(&self, point: InlayPoint) -> InlayOffset {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<(InlayPoint, (InlayOffset, Point))>(); .cursor::<(InlayPoint, (InlayOffset, Point))>(&());
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
let overshoot = point.0 - cursor.start().0 .0; let overshoot = point.0 - cursor.start().0 .0;
match cursor.item() { match cursor.item() {
@ -741,9 +761,8 @@ impl InlaySnapshot {
None => self.len(), None => self.len(),
} }
} }
pub fn to_buffer_point(&self, point: InlayPoint) -> Point { 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, &()); cursor.seek(&point, Bias::Right, &());
match cursor.item() { match cursor.item() {
Some(Transform::Isomorphic(_)) => { Some(Transform::Isomorphic(_)) => {
@ -754,9 +773,8 @@ impl InlaySnapshot {
None => self.buffer.max_point(), None => self.buffer.max_point(),
} }
} }
pub fn to_buffer_offset(&self, offset: InlayOffset) -> usize { 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, &()); cursor.seek(&offset, Bias::Right, &());
match cursor.item() { match cursor.item() {
Some(Transform::Isomorphic(_)) => { Some(Transform::Isomorphic(_)) => {
@ -769,7 +787,7 @@ impl InlaySnapshot {
} }
pub fn to_inlay_offset(&self, offset: usize) -> InlayOffset { 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, &()); cursor.seek(&offset, Bias::Left, &());
loop { loop {
match cursor.item() { match cursor.item() {
@ -801,9 +819,8 @@ impl InlaySnapshot {
} }
} }
} }
pub fn to_inlay_point(&self, point: Point) -> InlayPoint { 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, &()); cursor.seek(&point, Bias::Left, &());
loop { loop {
match cursor.item() { match cursor.item() {
@ -837,7 +854,7 @@ impl InlaySnapshot {
} }
pub fn clip_point(&self, mut point: InlayPoint, mut bias: Bias) -> InlayPoint { 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, &()); cursor.seek(&point, Bias::Left, &());
loop { loop {
match cursor.item() { match cursor.item() {
@ -934,7 +951,7 @@ impl InlaySnapshot {
pub fn text_summary_for_range(&self, range: Range<InlayOffset>) -> TextSummary { pub fn text_summary_for_range(&self, range: Range<InlayOffset>) -> TextSummary {
let mut summary = TextSummary::default(); 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, &()); cursor.seek(&range.start, Bias::Right, &());
let overshoot = range.start.0 - cursor.start().0 .0; let overshoot = range.start.0 - cursor.start().0 .0;
@ -982,7 +999,7 @@ impl InlaySnapshot {
} }
pub fn buffer_rows(&self, row: u32) -> InlayBufferRows<'_> { 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); let inlay_point = InlayPoint::new(row, 0);
cursor.seek(&inlay_point, Bias::Left, &()); cursor.seek(&inlay_point, Bias::Left, &());
@ -1024,7 +1041,7 @@ impl InlaySnapshot {
language_aware: bool, language_aware: bool,
highlights: Highlights<'a>, highlights: Highlights<'a>,
) -> InlayChunks<'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, &()); cursor.seek(&range.start, Bias::Right, &());
let mut highlight_endpoints = Vec::new(); let mut highlight_endpoints = Vec::new();

View File

@ -204,7 +204,7 @@ impl WrapMap {
} }
} else { } else {
let old_rows = self.snapshot.transforms.summary().output.lines.row + 1; 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(); let summary = self.snapshot.tab_snapshot.text_summary();
if !summary.lines.is_zero() { if !summary.lines.is_zero() {
self.snapshot self.snapshot
@ -303,7 +303,7 @@ impl WrapMap {
impl WrapSnapshot { impl WrapSnapshot {
fn new(tab_snapshot: TabSnapshot) -> Self { fn new(tab_snapshot: TabSnapshot) -> Self {
let mut transforms = SumTree::new(); let mut transforms = SumTree::default();
let extent = tab_snapshot.text_summary(); let extent = tab_snapshot.text_summary();
if !extent.lines.is_zero() { if !extent.lines.is_zero() {
transforms.push(Transform::isomorphic(extent), &()); transforms.push(Transform::isomorphic(extent), &());
@ -324,7 +324,7 @@ impl WrapSnapshot {
if tab_edits.is_empty() { if tab_edits.is_empty() {
new_transforms = self.transforms.clone(); new_transforms = self.transforms.clone();
} else { } else {
let mut old_cursor = self.transforms.cursor::<TabPoint>(); let mut old_cursor = self.transforms.cursor::<TabPoint>(&());
let mut tab_edits_iter = tab_edits.iter().peekable(); let mut tab_edits_iter = tab_edits.iter().peekable();
new_transforms = new_transforms =
@ -424,7 +424,7 @@ impl WrapSnapshot {
new_transforms = self.transforms.clone(); new_transforms = self.transforms.clone();
} else { } else {
let mut row_edits = row_edits.into_iter().peekable(); let mut row_edits = row_edits.into_iter().peekable();
let mut old_cursor = self.transforms.cursor::<TabPoint>(); let mut old_cursor = self.transforms.cursor::<TabPoint>(&());
new_transforms = old_cursor.slice( new_transforms = old_cursor.slice(
&TabPoint::new(row_edits.peek().unwrap().old_rows.start, 0), &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<u32> { fn compute_edits(&self, tab_edits: &[TabEdit], new_snapshot: &WrapSnapshot) -> Patch<u32> {
let mut wrap_edits = Vec::new(); let mut wrap_edits = Vec::new();
let mut old_cursor = self.transforms.cursor::<TransformSummary>(); let mut old_cursor = self.transforms.cursor::<TransformSummary>(&());
let mut new_cursor = new_snapshot.transforms.cursor::<TransformSummary>(); let mut new_cursor = new_snapshot.transforms.cursor::<TransformSummary>(&());
for mut tab_edit in tab_edits.iter().cloned() { for mut tab_edit in tab_edits.iter().cloned() {
tab_edit.old.start.0.column = 0; tab_edit.old.start.0.column = 0;
tab_edit.old.end.0 += Point::new(1, 0); tab_edit.old.end.0 += Point::new(1, 0);
@ -579,7 +579,7 @@ impl WrapSnapshot {
) -> WrapChunks<'a> { ) -> WrapChunks<'a> {
let output_start = WrapPoint::new(rows.start, 0); let output_start = WrapPoint::new(rows.start, 0);
let output_end = WrapPoint::new(rows.end, 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, &()); transforms.seek(&output_start, Bias::Right, &());
let mut input_start = TabPoint(transforms.start().1 .0); let mut input_start = TabPoint(transforms.start().1 .0);
if transforms.item().map_or(false, |t| t.is_isomorphic()) { if transforms.item().map_or(false, |t| t.is_isomorphic()) {
@ -606,7 +606,7 @@ impl WrapSnapshot {
} }
pub fn line_len(&self, row: u32) -> u32 { 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, &()); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Left, &());
if cursor if cursor
.item() .item()
@ -626,7 +626,7 @@ impl WrapSnapshot {
} }
pub fn soft_wrap_indent(&self, row: u32) -> Option<u32> { pub fn soft_wrap_indent(&self, row: u32) -> Option<u32> {
let mut cursor = self.transforms.cursor::<WrapPoint>(); let mut cursor = self.transforms.cursor::<WrapPoint>(&());
cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right, &()); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right, &());
cursor.item().and_then(|transform| { cursor.item().and_then(|transform| {
if transform.is_isomorphic() { if transform.is_isomorphic() {
@ -642,7 +642,7 @@ impl WrapSnapshot {
} }
pub fn buffer_rows(&self, start_row: u32) -> WrapBufferRows { 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, &()); transforms.seek(&WrapPoint::new(start_row, 0), Bias::Left, &());
let mut input_row = transforms.start().1.row(); let mut input_row = transforms.start().1.row();
if transforms.item().map_or(false, |t| t.is_isomorphic()) { 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 { 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, &()); cursor.seek(&point, Bias::Right, &());
let mut tab_point = cursor.start().1 .0; let mut tab_point = cursor.start().1 .0;
if cursor.item().map_or(false, |t| t.is_isomorphic()) { 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 { 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, &()); cursor.seek(&point, Bias::Right, &());
WrapPoint(cursor.start().1 .0 + (point.0 - cursor.start().0 .0)) WrapPoint(cursor.start().1 .0 + (point.0 - cursor.start().0 .0))
} }
pub fn clip_point(&self, mut point: WrapPoint, bias: Bias) -> WrapPoint { pub fn clip_point(&self, mut point: WrapPoint, bias: Bias) -> WrapPoint {
if bias == Bias::Left { if bias == Bias::Left {
let mut cursor = self.transforms.cursor::<WrapPoint>(); let mut cursor = self.transforms.cursor::<WrapPoint>(&());
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
if cursor.item().map_or(false, |t| !t.is_isomorphic()) { if cursor.item().map_or(false, |t| !t.is_isomorphic()) {
point = *cursor.start(); point = *cursor.start();
@ -705,7 +705,7 @@ impl WrapSnapshot {
*point.column_mut() = 0; *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, &()); cursor.seek(&point, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -725,7 +725,7 @@ impl WrapSnapshot {
pub fn next_row_boundary(&self, mut point: WrapPoint) -> Option<u32> { pub fn next_row_boundary(&self, mut point: WrapPoint) -> Option<u32> {
point.0 += Point::new(1, 0); 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, &()); cursor.seek(&point, Bias::Right, &());
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if transform.is_isomorphic() && cursor.start().1.column() == 0 { 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() { while let Some(transform) = transforms.next() {
if let Some(next_transform) = transforms.peek() { if let Some(next_transform) = transforms.peek() {
assert!(transform.is_isomorphic() != next_transform.is_isomorphic()); assert!(transform.is_isomorphic() != next_transform.is_isomorphic());
@ -982,6 +982,10 @@ impl WrapPoint {
impl sum_tree::Summary for TransformSummary { impl sum_tree::Summary for TransformSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
@ -989,6 +993,10 @@ impl sum_tree::Summary for TransformSummary {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for TabPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for TabPoint {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += summary.input.lines; 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 { impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapPoint {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += summary.output.lines; self.0 += summary.output.lines;
} }

View File

@ -37,12 +37,20 @@ impl sum_tree::Item for GitBlameEntry {
impl sum_tree::Summary for GitBlameEntrySummary { impl sum_tree::Summary for GitBlameEntrySummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _cx: &()) { fn add_summary(&mut self, summary: &Self, _cx: &()) {
self.rows += summary.rows; self.rows += summary.rows;
} }
} }
impl<'a> sum_tree::Dimension<'a, GitBlameEntrySummary> for u32 { impl<'a> sum_tree::Dimension<'a, GitBlameEntrySummary> for u32 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a GitBlameEntrySummary, _cx: &()) { fn add_summary(&mut self, summary: &'a GitBlameEntrySummary, _cx: &()) {
*self += summary.rows; *self += summary.rows;
} }
@ -191,7 +199,7 @@ impl GitBlame {
) -> impl 'a + Iterator<Item = Option<BlameEntry>> { ) -> impl 'a + Iterator<Item = Option<BlameEntry>> {
self.sync(cx); self.sync(cx);
let mut cursor = self.entries.cursor::<u32>(); let mut cursor = self.entries.cursor::<u32>(&());
rows.into_iter().map(move |row| { rows.into_iter().map(move |row| {
let row = row?; let row = row?;
cursor.seek_forward(&row.0, Bias::Right, &()); cursor.seek_forward(&row.0, Bias::Right, &());
@ -249,8 +257,8 @@ impl GitBlame {
}) })
.peekable(); .peekable();
let mut new_entries = SumTree::new(); let mut new_entries = SumTree::default();
let mut cursor = self.entries.cursor::<u32>(); let mut cursor = self.entries.cursor::<u32>(&());
while let Some(mut edit) = row_edits.next() { while let Some(mut edit) = row_edits.next() {
while let Some(next_edit) = row_edits.peek() { while let Some(next_edit) = row_edits.peek() {

View File

@ -48,6 +48,10 @@ pub struct DiffHunkSummary {
impl sum_tree::Summary for DiffHunkSummary { impl sum_tree::Summary for DiffHunkSummary {
type Context = text::BufferSnapshot; type Context = text::BufferSnapshot;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
self.buffer_range.start = self self.buffer_range.start = self
.buffer_range .buffer_range
@ -63,17 +67,11 @@ pub struct BufferDiff {
tree: SumTree<DiffHunk<Anchor>>, tree: SumTree<DiffHunk<Anchor>>,
} }
impl Default for BufferDiff {
fn default() -> Self {
Self::new()
}
}
impl BufferDiff { impl BufferDiff {
pub fn new() -> BufferDiff { pub fn new(buffer: &BufferSnapshot) -> BufferDiff {
BufferDiff { BufferDiff {
last_buffer_version: None, last_buffer_version: None,
tree: SumTree::new(), tree: SumTree::new(buffer),
} }
} }
@ -97,11 +95,13 @@ impl BufferDiff {
range: Range<Anchor>, range: Range<Anchor>,
buffer: &'a BufferSnapshot, buffer: &'a BufferSnapshot,
) -> impl 'a + Iterator<Item = DiffHunk<u32>> { ) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| { let mut cursor = self
let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); .tree
let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); .filter::<_, DiffHunkSummary>(buffer, move |summary| {
!before_start && !after_end 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 || { let anchor_iter = std::iter::from_fn(move || {
cursor.next(buffer); cursor.next(buffer);
@ -142,11 +142,13 @@ impl BufferDiff {
range: Range<Anchor>, range: Range<Anchor>,
buffer: &'a BufferSnapshot, buffer: &'a BufferSnapshot,
) -> impl 'a + Iterator<Item = DiffHunk<u32>> { ) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| { let mut cursor = self
let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt(); .tree
let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt(); .filter::<_, DiffHunkSummary>(buffer, move |summary| {
!before_start && !after_end 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 || { std::iter::from_fn(move || {
cursor.prev(buffer); cursor.prev(buffer);
@ -171,11 +173,11 @@ impl BufferDiff {
#[cfg(test)] #[cfg(test)]
fn clear(&mut self, buffer: &text::BufferSnapshot) { fn clear(&mut self, buffer: &text::BufferSnapshot) {
self.last_buffer_version = Some(buffer.version().clone()); 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) { 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 diff_base_text = diff_base.to_string();
let buffer_text = buffer.as_rope().to_string(); let buffer_text = buffer.as_rope().to_string();
@ -351,7 +353,7 @@ mod tests {
.unindent(); .unindent();
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text); 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)); smol::block_on(diff.update(&diff_base_rope, &buffer));
assert_hunks( assert_hunks(
diff.hunks(&buffer), diff.hunks(&buffer),
@ -412,7 +414,7 @@ mod tests {
.unindent(); .unindent();
let buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text); 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)); smol::block_on(diff.update(&diff_base_rope, &buffer));
assert_eq!(diff.hunks(&buffer).count(), 8); assert_eq!(diff.hunks(&buffer).count(), 8);

View File

@ -181,7 +181,7 @@ impl ListState {
last_layout_bounds: None, last_layout_bounds: None,
last_padding: None, last_padding: None,
render_item: Box::new(render_item), render_item: Box::new(render_item),
items: SumTree::new(), items: SumTree::default(),
logical_scroll_top: None, logical_scroll_top: None,
alignment, alignment,
overdraw, overdraw,
@ -228,7 +228,7 @@ impl ListState {
) { ) {
let state = &mut *self.0.borrow_mut(); let state = &mut *self.0.borrow_mut();
let mut old_items = state.items.cursor::<Count>(); let mut old_items = state.items.cursor::<Count>(&());
let mut new_items = old_items.slice(&Count(old_range.start), Bias::Right, &()); let mut new_items = old_items.slice(&Count(old_range.start), Bias::Right, &());
old_items.seek_forward(&Count(old_range.end), 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.item_ix = ix;
scroll_top.offset_in_item = px(0.); scroll_top.offset_in_item = px(0.);
} else { } else {
let mut cursor = state.items.cursor::<ListItemSummary>(); let mut cursor = state.items.cursor::<ListItemSummary>(&());
cursor.seek(&Count(ix + 1), Bias::Right, &()); cursor.seek(&Count(ix + 1), Bias::Right, &());
let bottom = cursor.start().height + padding.top; let bottom = cursor.start().height + padding.top;
let goal_top = px(0.).max(bottom - height + padding.bottom); let goal_top = px(0.).max(bottom - height + padding.bottom);
@ -326,7 +326,7 @@ impl ListState {
return None; 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, &()); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
let scroll_top = cursor.start().1 .0 + scroll_top.offset_in_item; let scroll_top = cursor.start().1 .0 + scroll_top.offset_in_item;
@ -348,7 +348,7 @@ impl ListState {
impl StateInner { impl StateInner {
fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> { fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> {
let mut cursor = self.items.cursor::<ListItemSummary>(); let mut cursor = self.items.cursor::<ListItemSummary>(&());
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
let start_y = cursor.start().height + scroll_top.offset_in_item; let start_y = cursor.start().height + scroll_top.offset_in_item;
cursor.seek_forward(&Height(start_y + height), Bias::Left, &()); 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 { if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max {
self.logical_scroll_top = None; self.logical_scroll_top = None;
} else { } else {
let mut cursor = self.items.cursor::<ListItemSummary>(); let mut cursor = self.items.cursor::<ListItemSummary>(&());
cursor.seek(&Height(new_scroll_top), Bias::Right, &()); cursor.seek(&Height(new_scroll_top), Bias::Right, &());
let item_ix = cursor.start().count; let item_ix = cursor.start().count;
let offset_in_item = new_scroll_top - cursor.start().height; 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 { fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels {
let mut cursor = self.items.cursor::<ListItemSummary>(); let mut cursor = self.items.cursor::<ListItemSummary>(&());
cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right, &()); cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right, &());
cursor.start().height + logical_scroll_top.offset_in_item cursor.start().height + logical_scroll_top.offset_in_item
} }
@ -445,7 +445,7 @@ impl StateInner {
AvailableSpace::MinContent, AvailableSpace::MinContent,
); );
let mut cursor = old_items.cursor::<Count>(); let mut cursor = old_items.cursor::<Count>(&());
// Render items after the scroll top, including those in the trailing overdraw // Render items after the scroll top, including those in the trailing overdraw
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); 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 measured_range = cursor.start().0..(cursor.start().0 + measured_items.len());
let mut cursor = old_items.cursor::<Count>(); let mut cursor = old_items.cursor::<Count>(&());
let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right, &()); let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right, &());
new_items.extend(measured_items, &()); new_items.extend(measured_items, &());
cursor.seek(&Count(measured_range.end), Bias::Right, &()); cursor.seek(&Count(measured_range.end), Bias::Right, &());
@ -573,7 +573,7 @@ impl StateInner {
if !rendered_focused_item { if !rendered_focused_item {
let mut cursor = self let mut cursor = self
.items .items
.filter::<_, Count>(|summary| summary.has_focus_handles); .filter::<_, Count>(&(), |summary| summary.has_focus_handles);
cursor.next(&()); cursor.next(&());
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
if item.contains_focused(cx) { if item.contains_focused(cx) {
@ -629,7 +629,7 @@ impl StateInner {
offset_in_item: autoscroll_bounds.top() - item_origin.y, offset_in_item: autoscroll_bounds.top() - item_origin.y,
}); });
} else if autoscroll_bounds.bottom() > bounds.bottom() { } else if autoscroll_bounds.bottom() > bounds.bottom() {
let mut cursor = self.items.cursor::<Count>(); let mut cursor = self.items.cursor::<Count>(&());
cursor.seek(&Count(item.index), Bias::Right, &()); cursor.seek(&Count(item.index), Bias::Right, &());
let mut height = bounds.size.height - padding.top - padding.bottom; 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 { impl sum_tree::Summary for ListItemSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.count += summary.count; self.count += summary.count;
self.rendered_count += summary.rendered_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 { impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.count; self.0 += summary.count;
} }
} }
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height { impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.height; self.0 += summary.height;
} }

View File

@ -722,7 +722,9 @@ impl Buffer {
capability: Capability, capability: Capability,
) -> Self { ) -> Self {
let saved_mtime = file.as_ref().and_then(|file| file.mtime()); 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 { Self {
saved_mtime, saved_mtime,
saved_version: buffer.version(), saved_version: buffer.version(),
@ -739,10 +741,10 @@ impl Buffer {
}) })
.map(Rope::from), .map(Rope::from),
diff_base_version: 0, diff_base_version: 0,
git_diff: git::diff::BufferDiff::new(), git_diff,
file, file,
capability, capability,
syntax_map: Mutex::new(SyntaxMap::new()), syntax_map,
parsing_in_background: false, parsing_in_background: false,
non_text_state_update_count: 0, non_text_state_update_count: 0,
sync_parse_timeout: Duration::from_millis(1), sync_parse_timeout: Duration::from_millis(1),
@ -809,7 +811,7 @@ impl Buffer {
/// Assign a language to the buffer. /// Assign a language to the buffer.
pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) { pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
self.non_text_state_update_count += 1; self.non_text_state_update_count += 1;
self.syntax_map.lock().clear(); self.syntax_map.lock().clear(&self.text);
self.language = language; self.language = language;
self.reparse(cx); self.reparse(cx);
cx.emit(BufferEvent::LanguageChanged); cx.emit(BufferEvent::LanguageChanged);

View File

@ -15,7 +15,7 @@ use text::{Anchor, FromAnchor, PointUtf16, ToOffset};
/// The diagnostics are stored in a [`SumTree`], which allows this struct /// The diagnostics are stored in a [`SumTree`], which allows this struct
/// to be cheaply copied, and allows for efficient retrieval of the /// to be cheaply copied, and allows for efficient retrieval of the
/// diagnostics that intersect a given range of the buffer. /// diagnostics that intersect a given range of the buffer.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug)]
pub struct DiagnosticSet { pub struct DiagnosticSet {
diagnostics: SumTree<DiagnosticEntry<Anchor>>, diagnostics: SumTree<DiagnosticEntry<Anchor>>,
} }
@ -135,7 +135,7 @@ impl DiagnosticSet {
{ {
let end_bias = if inclusive { Bias::Right } else { Bias::Left }; 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 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| { move |summary: &Summary| {
let start_cmp = range.start.cmp(&summary.max_end, buffer); let start_cmp = range.start.cmp(&summary.max_end, buffer);
let end_cmp = range.end.cmp(&summary.min_start, 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 { impl sum_tree::Summary for Summary {
type Context = text::BufferSnapshot; type Context = text::BufferSnapshot;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.min_start.cmp(&self.min_start, buffer).is_lt() { if other.min_start.cmp(&self.min_start, buffer).is_lt() {
self.min_start = other.min_start; self.min_start = other.min_start;

View File

@ -18,13 +18,12 @@ use sum_tree::{Bias, SeekTarget, SumTree};
use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree}; use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree};
#[derive(Default)]
pub struct SyntaxMap { pub struct SyntaxMap {
snapshot: SyntaxSnapshot, snapshot: SyntaxSnapshot,
language_registry: Option<Arc<LanguageRegistry>>, language_registry: Option<Arc<LanguageRegistry>>,
} }
#[derive(Clone, Default)] #[derive(Clone)]
pub struct SyntaxSnapshot { pub struct SyntaxSnapshot {
layers: SumTree<SyntaxLayerEntry>, layers: SumTree<SyntaxLayerEntry>,
parsed_version: clock::Global, parsed_version: clock::Global,
@ -212,8 +211,11 @@ struct ByteChunks<'a>(text::Chunks<'a>);
pub(crate) struct QueryCursorHandle(Option<QueryCursor>); pub(crate) struct QueryCursorHandle(Option<QueryCursor>);
impl SyntaxMap { impl SyntaxMap {
pub fn new() -> Self { pub fn new(text: &BufferSnapshot) -> Self {
Self::default() Self {
snapshot: SyntaxSnapshot::new(text),
language_registry: None,
}
} }
pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) { pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
@ -242,12 +244,21 @@ impl SyntaxMap {
self.snapshot = snapshot; self.snapshot = snapshot;
} }
pub fn clear(&mut self) { pub fn clear(&mut self, text: &BufferSnapshot) {
self.snapshot = SyntaxSnapshot::default(); self.snapshot = SyntaxSnapshot::new(text);
} }
} }
impl SyntaxSnapshot { 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 { pub fn is_empty(&self) -> bool {
self.layers.is_empty() self.layers.is_empty()
} }
@ -262,10 +273,10 @@ impl SyntaxSnapshot {
return; return;
} }
let mut layers = SumTree::new(); let mut layers = SumTree::new(text);
let mut first_edit_ix_for_depth = 0; let mut first_edit_ix_for_depth = 0;
let mut prev_depth = 0; let mut prev_depth = 0;
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
cursor.next(text); cursor.next(text);
'outer: loop { 'outer: loop {
@ -388,7 +399,7 @@ impl SyntaxSnapshot {
let mut resolved_injection_ranges = Vec::new(); let mut resolved_injection_ranges = Vec::new();
let mut cursor = self let mut cursor = self
.layers .layers
.filter::<_, ()>(|summary| summary.contains_unknown_injections); .filter::<_, ()>(text, |summary| summary.contains_unknown_injections);
cursor.next(text); cursor.next(text);
while let Some(layer) = cursor.item() { while let Some(layer) = cursor.item() {
let SyntaxLayerContent::Pending { language_name } = &layer.content else { let SyntaxLayerContent::Pending { language_name } = &layer.content else {
@ -430,9 +441,9 @@ impl SyntaxSnapshot {
log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges); log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges);
let max_depth = self.layers.summary().max_depth; let max_depth = self.layers.summary().max_depth;
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
cursor.next(text); cursor.next(text);
let mut layers = SumTree::new(); let mut layers = SumTree::new(text);
let mut changed_regions = ChangeRegionSet::default(); let mut changed_regions = ChangeRegionSet::default();
let mut queue = BinaryHeap::new(); let mut queue = BinaryHeap::new();
@ -823,7 +834,7 @@ impl SyntaxSnapshot {
let start = buffer.anchor_before(start_offset); let start = buffer.anchor_before(start_offset);
let end = buffer.anchor_after(end_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 { if summary.max_depth > summary.min_depth {
true true
} else { } else {
@ -1666,6 +1677,10 @@ impl Default for SyntaxLayerSummary {
impl sum_tree::Summary for SyntaxLayerSummary { impl sum_tree::Summary for SyntaxLayerSummary {
type Context = BufferSnapshot; type Context = BufferSnapshot;
fn zero(_cx: &BufferSnapshot) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.max_depth > self.max_depth { if other.max_depth > self.max_depth {
self.max_depth = other.max_depth; self.max_depth = other.max_depth;

View File

@ -103,7 +103,7 @@ fn test_syntax_map_layers_for_range(cx: &mut AppContext) {
.unindent(), .unindent(),
); );
let mut syntax_map = SyntaxMap::new(); let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone()); syntax_map.set_language_registry(registry.clone());
syntax_map.reparse(language.clone(), &buffer); syntax_map.reparse(language.clone(), &buffer);
@ -202,7 +202,7 @@ fn test_dynamic_language_injection(cx: &mut AppContext) {
.unindent(), .unindent(),
); );
let mut syntax_map = SyntaxMap::new(); let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone()); syntax_map.set_language_registry(registry.clone());
syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown.clone(), &buffer);
syntax_map.reparse(markdown_inline.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 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.set_language_registry(registry.clone());
syntax_map.reparse(language.clone(), &buffer); 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()); reference_syntax_map.set_language_registry(registry.clone());
log::info!("initial text:\n{}", buffer.text()); log::info!("initial text:\n{}", buffer.text());
@ -918,7 +918,7 @@ fn test_random_edits(
syntax_map.reparse(language.clone(), &buffer); syntax_map.reparse(language.clone(), &buffer);
reference_syntax_map.clear(); reference_syntax_map.clear(&buffer);
reference_syntax_map.reparse(language.clone(), &buffer); reference_syntax_map.reparse(language.clone(), &buffer);
} }
@ -931,7 +931,7 @@ fn test_random_edits(
syntax_map.interpolate(&buffer); syntax_map.interpolate(&buffer);
syntax_map.reparse(language.clone(), &buffer); syntax_map.reparse(language.clone(), &buffer);
reference_syntax_map.clear(); reference_syntax_map.clear(&buffer);
reference_syntax_map.reparse(language.clone(), &buffer); reference_syntax_map.reparse(language.clone(), &buffer);
assert_eq!( assert_eq!(
syntax_map.layers(&buffer).len(), syntax_map.layers(&buffer).len(),
@ -1082,7 +1082,7 @@ fn test_edit_sequence(
.unwrap(); .unwrap();
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), Default::default()); 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.set_language_registry(registry.clone());
mutated_syntax_map.reparse(language.clone(), &buffer); mutated_syntax_map.reparse(language.clone(), &buffer);
@ -1097,7 +1097,7 @@ fn test_edit_sequence(
// Create a second syntax map from scratch // Create a second syntax map from scratch
log::info!("fresh parse {i}: {marked_string:?}"); 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.set_language_registry(registry.clone());
reference_syntax_map.reparse(language.clone(), &buffer); reference_syntax_map.reparse(language.clone(), &buffer);

View File

@ -561,7 +561,7 @@ impl MultiBuffer {
} }
let mut buffer_edits: HashMap<BufferId, Vec<BufferEdit>> = Default::default(); let mut buffer_edits: HashMap<BufferId, Vec<BufferEdit>> = Default::default();
let mut edited_excerpt_ids = Vec::new(); let mut edited_excerpt_ids = Vec::new();
let mut cursor = snapshot.excerpts.cursor::<usize>(); let mut cursor = snapshot.excerpts.cursor::<usize>(&());
for (ix, (range, new_text)) in edits.enumerate() { for (ix, (range, new_text)) in edits.enumerate() {
let new_text: Arc<str> = new_text.into(); let new_text: Arc<str> = new_text.into();
let original_indent_column = original_indent_columns.get(ix).copied().unwrap_or(0); 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 mut ranges = Vec::new();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut cursor = snapshot.excerpts.cursor::<ExcerptSummary>(); let mut cursor = snapshot.excerpts.cursor::<ExcerptSummary>(&());
for (buffer_id, buffer_transaction) in &transaction.buffer_transactions { for (buffer_id, buffer_transaction) in &transaction.buffer_transactions {
let Some(buffer_state) = buffers.get(buffer_id) else { let Some(buffer_state) = buffers.get(buffer_id) else {
@ -957,7 +957,7 @@ impl MultiBuffer {
let mut selections_by_buffer: HashMap<BufferId, Vec<Selection<text::Anchor>>> = let mut selections_by_buffer: HashMap<BufferId, Vec<Selection<text::Anchor>>> =
Default::default(); Default::default();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&());
for selection in selections { for selection in selections {
let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id); let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id);
let end_locator = snapshot.excerpt_locator_for_id(selection.end.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 prev_locator = snapshot.excerpt_locator_for_id(prev_excerpt_id).clone();
let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids); let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&());
let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right, &()); let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right, &());
prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone(); prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone();
@ -1388,7 +1388,7 @@ impl MultiBuffer {
let mut excerpts = Vec::new(); let mut excerpts = Vec::new();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&());
for locator in buffers for locator in buffers
.get(&buffer.read(cx).remote_id()) .get(&buffer.read(cx).remote_id())
.map(|state| &state.excerpts) .map(|state| &state.excerpts)
@ -1432,7 +1432,7 @@ impl MultiBuffer {
let snapshot = self.read(cx); let snapshot = self.read(cx);
let position = position.to_offset(&snapshot); let position = position.to_offset(&snapshot);
let mut cursor = snapshot.excerpts.cursor::<usize>(); let mut cursor = snapshot.excerpts.cursor::<usize>(&());
cursor.seek(&position, Bias::Right, &()); cursor.seek(&position, Bias::Right, &());
cursor cursor
.item() .item()
@ -1459,7 +1459,7 @@ impl MultiBuffer {
) -> Option<(Model<Buffer>, usize, ExcerptId)> { ) -> Option<(Model<Buffer>, usize, ExcerptId)> {
let snapshot = self.read(cx); let snapshot = self.read(cx);
let offset = point.to_offset(&snapshot); let offset = point.to_offset(&snapshot);
let mut cursor = snapshot.excerpts.cursor::<usize>(); let mut cursor = snapshot.excerpts.cursor::<usize>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -1482,7 +1482,7 @@ impl MultiBuffer {
) -> Option<(Model<Buffer>, Point, ExcerptId)> { ) -> Option<(Model<Buffer>, Point, ExcerptId)> {
let snapshot = self.read(cx); let snapshot = self.read(cx);
let point = point.to_point(&snapshot); let point = point.to_point(&snapshot);
let mut cursor = snapshot.excerpts.cursor::<Point>(); let mut cursor = snapshot.excerpts.cursor::<Point>(&());
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -1507,7 +1507,7 @@ impl MultiBuffer {
let end = range.end.to_offset(&snapshot); let end = range.end.to_offset(&snapshot);
let mut result = Vec::new(); let mut result = Vec::new();
let mut cursor = snapshot.excerpts.cursor::<usize>(); let mut cursor = snapshot.excerpts.cursor::<usize>(&());
cursor.seek(&start, Bias::Right, &()); cursor.seek(&start, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -1546,8 +1546,8 @@ impl MultiBuffer {
let mut buffers = self.buffers.borrow_mut(); let mut buffers = self.buffers.borrow_mut();
let mut snapshot = self.snapshot.borrow_mut(); let mut snapshot = self.snapshot.borrow_mut();
let mut new_excerpts = SumTree::new(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&());
let mut edits = Vec::new(); let mut edits = Vec::new();
let mut excerpt_ids = ids.iter().copied().peekable(); let mut excerpt_ids = ids.iter().copied().peekable();
@ -1801,8 +1801,8 @@ impl MultiBuffer {
let ids = ids.into_iter().collect::<Vec<_>>(); let ids = ids.into_iter().collect::<Vec<_>>();
let snapshot = self.snapshot(cx); let snapshot = self.snapshot(cx);
let locators = snapshot.excerpt_locators_for_ids(ids.iter().copied()); let locators = snapshot.excerpt_locators_for_ids(ids.iter().copied());
let mut new_excerpts = SumTree::new(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&());
let mut edits = Vec::<Edit<usize>>::new(); let mut edits = Vec::<Edit<usize>>::new();
for locator in &locators { for locator in &locators {
@ -1927,8 +1927,8 @@ impl MultiBuffer {
excerpts_to_edit.sort_unstable_by_key(|(locator, _, _)| *locator); excerpts_to_edit.sort_unstable_by_key(|(locator, _, _)| *locator);
let mut edits = Vec::new(); let mut edits = Vec::new();
let mut new_excerpts = SumTree::new(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(); let mut cursor = snapshot.excerpts.cursor::<(Option<&Locator>, usize)>(&());
for (locator, buffer, buffer_edited) in excerpts_to_edit { for (locator, buffer, buffer_edited) in excerpts_to_edit {
new_excerpts.append(cursor.slice(&Some(locator), Bias::Left, &()), &()); new_excerpts.append(cursor.slice(&Some(locator), Bias::Left, &()), &());
@ -2230,7 +2230,7 @@ impl MultiBufferSnapshot {
pub fn reversed_chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ { pub fn reversed_chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ {
let mut offset = position.to_offset(self); let mut offset = position.to_offset(self);
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&offset, Bias::Left, &()); cursor.seek(&offset, Bias::Left, &());
let mut excerpt_chunks = cursor.item().map(|excerpt| { let mut excerpt_chunks = cursor.item().map(|excerpt| {
let end_before_footer = cursor.start() + excerpt.text_summary.len; let end_before_footer = cursor.start() + excerpt.text_summary.len;
@ -2357,7 +2357,7 @@ impl MultiBufferSnapshot {
return buffer.clip_offset(offset, bias); return buffer.clip_offset(offset, bias);
} }
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
@ -2376,7 +2376,7 @@ impl MultiBufferSnapshot {
return buffer.clip_point(point, bias); return buffer.clip_point(point, bias);
} }
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>(&());
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer);
@ -2395,7 +2395,7 @@ impl MultiBufferSnapshot {
return buffer.clip_offset_utf16(offset, bias); return buffer.clip_offset_utf16(offset, bias);
} }
let mut cursor = self.excerpts.cursor::<OffsetUtf16>(); let mut cursor = self.excerpts.cursor::<OffsetUtf16>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt.range.context.start.to_offset_utf16(&excerpt.buffer); 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); return buffer.clip_point_utf16(point, bias);
} }
let mut cursor = self.excerpts.cursor::<PointUtf16>(); let mut cursor = self.excerpts.cursor::<PointUtf16>(&());
cursor.seek(&point.0, Bias::Right, &()); cursor.seek(&point.0, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt let excerpt_start = excerpt
@ -2432,7 +2432,7 @@ impl MultiBufferSnapshot {
pub fn bytes_in_range<T: ToOffset>(&self, range: Range<T>) -> MultiBufferBytes { pub fn bytes_in_range<T: ToOffset>(&self, range: Range<T>) -> MultiBufferBytes {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut excerpts = self.excerpts.cursor::<usize>(); let mut excerpts = self.excerpts.cursor::<usize>(&());
excerpts.seek(&range.start, Bias::Right, &()); excerpts.seek(&range.start, Bias::Right, &());
let mut chunk = &[][..]; let mut chunk = &[][..];
@ -2457,7 +2457,7 @@ impl MultiBufferSnapshot {
range: Range<T>, range: Range<T>,
) -> ReversedMultiBufferBytes { ) -> ReversedMultiBufferBytes {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut excerpts = self.excerpts.cursor::<usize>(); let mut excerpts = self.excerpts.cursor::<usize>(&());
excerpts.seek(&range.end, Bias::Left, &()); excerpts.seek(&range.end, Bias::Left, &());
let mut chunk = &[][..]; let mut chunk = &[][..];
@ -2482,7 +2482,7 @@ impl MultiBufferSnapshot {
pub fn buffer_rows(&self, start_row: MultiBufferRow) -> MultiBufferRows { pub fn buffer_rows(&self, start_row: MultiBufferRow) -> MultiBufferRows {
let mut result = MultiBufferRows { let mut result = MultiBufferRows {
buffer_row_range: 0..0, buffer_row_range: 0..0,
excerpts: self.excerpts.cursor(), excerpts: self.excerpts.cursor(&()),
}; };
result.seek(start_row); result.seek(start_row);
result result
@ -2492,7 +2492,7 @@ impl MultiBufferSnapshot {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut chunks = MultiBufferChunks { let mut chunks = MultiBufferChunks {
range: range.clone(), range: range.clone(),
excerpts: self.excerpts.cursor(), excerpts: self.excerpts.cursor(&()),
excerpt_chunks: None, excerpt_chunks: None,
language_aware, language_aware,
}; };
@ -2505,7 +2505,7 @@ impl MultiBufferSnapshot {
return buffer.offset_to_point(offset); 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, &()); cursor.seek(&offset, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
@ -2526,7 +2526,7 @@ impl MultiBufferSnapshot {
return buffer.offset_to_point_utf16(offset); 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, &()); cursor.seek(&offset, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
@ -2547,7 +2547,7 @@ impl MultiBufferSnapshot {
return buffer.point_to_point_utf16(point); 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, &()); cursor.seek(&point, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
@ -2569,7 +2569,7 @@ impl MultiBufferSnapshot {
return buffer.point_to_offset(point); 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, &()); cursor.seek(&point, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_point, start_offset) = cursor.start(); let (start_point, start_offset) = cursor.start();
@ -2590,7 +2590,7 @@ impl MultiBufferSnapshot {
return buffer.offset_utf16_to_offset(offset_utf16); 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, &()); cursor.seek(&offset_utf16, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset_utf16, start_offset) = cursor.start(); let (start_offset_utf16, start_offset) = cursor.start();
@ -2612,7 +2612,7 @@ impl MultiBufferSnapshot {
return buffer.offset_to_offset_utf16(offset); 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, &()); cursor.seek(&offset, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_offset_utf16) = cursor.start(); let (start_offset, start_offset_utf16) = cursor.start();
@ -2636,7 +2636,7 @@ impl MultiBufferSnapshot {
return buffer.point_utf16_to_offset(point); 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, &()); cursor.seek(&point, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_point, start_offset) = cursor.start(); let (start_point, start_offset) = cursor.start();
@ -2659,7 +2659,7 @@ impl MultiBufferSnapshot {
point: T, point: T,
) -> Option<(&BufferSnapshot, usize)> { ) -> Option<(&BufferSnapshot, usize)> {
let offset = point.to_offset(self); let offset = point.to_offset(self);
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -2680,7 +2680,7 @@ impl MultiBufferSnapshot {
let mut result = BTreeMap::new(); let mut result = BTreeMap::new();
let mut rows_for_excerpt = Vec::new(); let mut rows_for_excerpt = Vec::new();
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>(&());
let mut rows = rows.into_iter().peekable(); let mut rows = rows.into_iter().peekable();
let mut prev_row = u32::MAX; let mut prev_row = u32::MAX;
let mut prev_language_indent_size = IndentSize::default(); let mut prev_language_indent_size = IndentSize::default();
@ -2769,7 +2769,7 @@ impl MultiBufferSnapshot {
&self, &self,
row: MultiBufferRow, row: MultiBufferRow,
) -> Option<(&BufferSnapshot, Range<Point>)> { ) -> Option<(&BufferSnapshot, Range<Point>)> {
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>(&());
let point = Point::new(row.0, 0); let point = Point::new(row.0, 0);
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
if cursor.item().is_none() && *cursor.start() == point { if cursor.item().is_none() && *cursor.start() == point {
@ -2803,9 +2803,9 @@ impl MultiBufferSnapshot {
D: TextDimension, D: TextDimension,
O: ToOffset, 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 range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&range.start, Bias::Right, &()); cursor.seek(&range.start, Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let mut end_before_newline = cursor.end(&()); let mut end_before_newline = cursor.end(&());
@ -2856,7 +2856,7 @@ impl MultiBufferSnapshot {
where where
D: TextDimension + Ord + Sub<D, Output = D>, D: TextDimension + Ord + Sub<D, Output = D>,
{ {
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(); let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&());
let locator = self.excerpt_locator_for_id(anchor.excerpt_id); let locator = self.excerpt_locator_for_id(anchor.excerpt_id);
cursor.seek(locator, Bias::Left, &()); cursor.seek(locator, Bias::Left, &());
@ -2894,7 +2894,7 @@ impl MultiBufferSnapshot {
} }
let mut anchors = anchors.into_iter().peekable(); let mut anchors = anchors.into_iter().peekable();
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(); let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&());
let mut summaries = Vec::new(); let mut summaries = Vec::new();
while let Some(anchor) = anchors.peek() { while let Some(anchor) = anchors.peek() {
let excerpt_id = anchor.excerpt_id; let excerpt_id = anchor.excerpt_id;
@ -2949,7 +2949,7 @@ impl MultiBufferSnapshot {
I: 'a + IntoIterator<Item = &'a Anchor>, I: 'a + IntoIterator<Item = &'a Anchor>,
{ {
let mut anchors = anchors.into_iter().enumerate().peekable(); let mut anchors = anchors.into_iter().enumerate().peekable();
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&());
cursor.next(&()); cursor.next(&());
let mut result = Vec::new(); let mut result = Vec::new();
@ -3064,7 +3064,7 @@ impl MultiBufferSnapshot {
}; };
} }
let mut cursor = self.excerpts.cursor::<(usize, Option<ExcerptId>)>(); let mut cursor = self.excerpts.cursor::<(usize, Option<ExcerptId>)>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
if cursor.item().is_none() && offset == cursor.start().0 && bias == Bias::Left { if cursor.item().is_none() && offset == cursor.start().0 && bias == Bias::Left {
cursor.prev(&()); cursor.prev(&());
@ -3099,7 +3099,7 @@ impl MultiBufferSnapshot {
text_anchor: text::Anchor, text_anchor: text::Anchor,
) -> Option<Anchor> { ) -> Option<Anchor> {
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&());
cursor.seek(locator, Bias::Left, &()); cursor.seek(locator, Bias::Left, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
if excerpt.id == excerpt_id { if excerpt.id == excerpt_id {
@ -3139,7 +3139,7 @@ impl MultiBufferSnapshot {
) -> impl Iterator<Item = (&Excerpt, usize)> + '_ { ) -> impl Iterator<Item = (&Excerpt, usize)> + '_ {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&range.start, Bias::Right, &()); cursor.seek(&range.start, Bias::Right, &());
cursor.prev(&()); cursor.prev(&());
@ -3183,7 +3183,7 @@ impl MultiBufferSnapshot {
}; };
let bounds = (start, end); 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, &()); cursor.seek(&start_offset, Bias::Right, &());
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(&()); cursor.prev(&());
@ -3550,7 +3550,7 @@ impl MultiBufferSnapshot {
&self, &self,
row_range: Range<MultiBufferRow>, row_range: Range<MultiBufferRow>,
) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ { ) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ {
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>(&());
cursor.seek(&Point::new(row_range.end.0, 0), Bias::Left, &()); cursor.seek(&Point::new(row_range.end.0, 0), Bias::Left, &());
if cursor.item().is_none() { if cursor.item().is_none() {
@ -3617,7 +3617,7 @@ impl MultiBufferSnapshot {
&self, &self,
row_range: Range<MultiBufferRow>, row_range: Range<MultiBufferRow>,
) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ { ) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ {
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>(&());
cursor.seek(&Point::new(row_range.start.0, 0), Bias::Left, &()); cursor.seek(&Point::new(row_range.start.0, 0), Bias::Left, &());
@ -3779,7 +3779,7 @@ impl MultiBufferSnapshot {
} else if id == ExcerptId::max() { } else if id == ExcerptId::max() {
Locator::max_ref() Locator::max_ref()
} else { } else {
let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(); let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(&());
cursor.seek(&id, Bias::Left, &()); cursor.seek(&id, Bias::Left, &());
if let Some(entry) = cursor.item() { if let Some(entry) = cursor.item() {
if entry.id == id { if entry.id == id {
@ -3814,7 +3814,7 @@ impl MultiBufferSnapshot {
} }
} }
let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(); let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(&());
for id in sorted_ids { for id in sorted_ids {
if cursor.seek_forward(&id, Bias::Left, &()) { if cursor.seek_forward(&id, Bias::Left, &()) {
locators.push(cursor.item().unwrap().locator.clone()); locators.push(cursor.item().unwrap().locator.clone());
@ -3839,7 +3839,7 @@ impl MultiBufferSnapshot {
&'a self, &'a self,
excerpt_id: ExcerptId, excerpt_id: ExcerptId,
) -> Option<Range<T>> { ) -> Option<Range<T>> {
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); let locator = self.excerpt_locator_for_id(excerpt_id);
if cursor.seek(&Some(locator), Bias::Left, &()) { if cursor.seek(&Some(locator), Bias::Left, &()) {
let start = cursor.start().1.clone(); let start = cursor.start().1.clone();
@ -3851,7 +3851,7 @@ impl MultiBufferSnapshot {
} }
fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> { fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&());
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
cursor.seek(&Some(locator), Bias::Left, &()); cursor.seek(&Some(locator), Bias::Left, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
@ -3866,7 +3866,7 @@ impl MultiBufferSnapshot {
pub fn excerpt_containing<T: ToOffset>(&self, range: Range<T>) -> Option<MultiBufferExcerpt> { pub fn excerpt_containing<T: ToOffset>(&self, range: Range<T>) -> Option<MultiBufferExcerpt> {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.seek(&range.start, Bias::Right, &()); cursor.seek(&range.start, Bias::Right, &());
let start_excerpt = cursor.item()?; let start_excerpt = cursor.item()?;
@ -3891,7 +3891,7 @@ impl MultiBufferSnapshot {
I: IntoIterator<Item = Range<Anchor>> + 'a, I: IntoIterator<Item = Range<Anchor>> + 'a,
{ {
let mut ranges = ranges.into_iter().map(|range| range.to_offset(self)); let mut ranges = ranges.into_iter().map(|range| range.to_offset(self));
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.next(&()); cursor.next(&());
let mut current_range = ranges.next(); let mut current_range = ranges.next();
iter::from_fn(move || { iter::from_fn(move || {
@ -3943,7 +3943,7 @@ impl MultiBufferSnapshot {
ranges: impl IntoIterator<Item = Range<Anchor>>, ranges: impl IntoIterator<Item = Range<Anchor>>,
) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, Range<usize>)> { ) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, Range<usize>)> {
let mut ranges = ranges.into_iter().map(|range| range.to_offset(self)); let mut ranges = ranges.into_iter().map(|range| range.to_offset(self));
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>(&());
cursor.next(&()); cursor.next(&());
let mut current_range = ranges.next(); let mut current_range = ranges.next();
iter::from_fn(move || { iter::from_fn(move || {
@ -3980,7 +3980,7 @@ impl MultiBufferSnapshot {
range: &'a Range<Anchor>, range: &'a Range<Anchor>,
include_local: bool, include_local: bool,
) -> impl 'a + Iterator<Item = (ReplicaId, bool, CursorShape, Selection<Anchor>)> { ) -> impl 'a + Iterator<Item = (ReplicaId, bool, CursorShape, Selection<Anchor>)> {
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(); let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&());
let start_locator = self.excerpt_locator_for_id(range.start.excerpt_id); let start_locator = self.excerpt_locator_for_id(range.start.excerpt_id);
let end_locator = self.excerpt_locator_for_id(range.end.excerpt_id); let end_locator = self.excerpt_locator_for_id(range.end.excerpt_id);
cursor.seek(start_locator, Bias::Left, &()); cursor.seek(start_locator, Bias::Left, &());
@ -4519,6 +4519,10 @@ impl sum_tree::KeyedItem for ExcerptIdMapping {
impl sum_tree::Summary for ExcerptId { impl sum_tree::Summary for ExcerptId {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
*self = *other; *self = *other;
} }
@ -4527,6 +4531,10 @@ impl sum_tree::Summary for ExcerptId {
impl sum_tree::Summary for ExcerptSummary { impl sum_tree::Summary for ExcerptSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
debug_assert!(summary.excerpt_locator > self.excerpt_locator); debug_assert!(summary.excerpt_locator > self.excerpt_locator);
self.excerpt_locator = summary.excerpt_locator.clone(); 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 { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for TextSummary {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self += &summary.text; *self += &summary.text;
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for usize { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for usize {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self += summary.text.len; *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 { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for OffsetUtf16 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self += summary.text.len_utf16; *self += summary.text.len_utf16;
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Point { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Point {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self += summary.text.lines; *self += summary.text.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for PointUtf16 { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for PointUtf16 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self += summary.text.lines_utf16() *self += summary.text.lines_utf16()
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a Locator> { 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, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self = Some(&summary.excerpt_locator); *self = Some(&summary.excerpt_locator);
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<ExcerptId> { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<ExcerptId> {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) {
*self = Some(summary.excerpt_id); *self = Some(summary.excerpt_id);
} }

View File

@ -137,13 +137,12 @@ impl NotificationStore {
return None; return None;
} }
let ix = count - 1 - ix; let ix = count - 1 - ix;
let mut cursor = self.notifications.cursor::<Count>(); let mut cursor = self.notifications.cursor::<Count>(&());
cursor.seek(&Count(ix), Bias::Right, &()); cursor.seek(&Count(ix), Bias::Right, &());
cursor.item() cursor.item()
} }
pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> { pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> {
let mut cursor = self.notifications.cursor::<NotificationId>(); let mut cursor = self.notifications.cursor::<NotificationId>(&());
cursor.seek(&NotificationId(id), Bias::Left, &()); cursor.seek(&NotificationId(id), Bias::Left, &());
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if item.id == id { if item.id == id {
@ -372,8 +371,8 @@ impl NotificationStore {
is_new: bool, is_new: bool,
cx: &mut ModelContext<'_, NotificationStore>, cx: &mut ModelContext<'_, NotificationStore>,
) { ) {
let mut cursor = self.notifications.cursor::<(NotificationId, Count)>(); let mut cursor = self.notifications.cursor::<(NotificationId, Count)>(&());
let mut new_notifications = SumTree::new(); let mut new_notifications = SumTree::default();
let mut old_range = 0..0; let mut old_range = 0..0;
for (i, (id, new_notification)) in notifications.into_iter().enumerate() { 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 { impl sum_tree::Summary for NotificationSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.max_id = self.max_id.max(summary.max_id); self.max_id = self.max_id.max(summary.max_id);
self.count += summary.count; self.count += summary.count;
@ -476,6 +479,10 @@ impl sum_tree::Summary for NotificationSummary {
} }
impl<'a> sum_tree::Dimension<'a, NotificationSummary> for NotificationId { impl<'a> sum_tree::Dimension<'a, NotificationSummary> for NotificationId {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { fn add_summary(&mut self, summary: &NotificationSummary, _: &()) {
debug_assert!(summary.max_id > self.0); debug_assert!(summary.max_id > self.0);
self.0 = summary.max_id; 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 { impl<'a> sum_tree::Dimension<'a, NotificationSummary> for Count {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { fn add_summary(&mut self, summary: &NotificationSummary, _: &()) {
self.0 += summary.count; self.0 += summary.count;
} }

View File

@ -2753,7 +2753,7 @@ impl LspStore {
if let Some(language) = buffer.language().cloned() { if let Some(language) = buffer.language().cloned() {
for adapter in self.languages.lsp_adapters(&language.name()) { for adapter in self.languages.lsp_adapters(&language.name()) {
if let Some(server_id) = ids.get(&(worktree_id, adapter.name.clone())) { 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| { self.buffer_store.update(cx, |buffer_store, cx| {
for buffer in buffer_store.buffers() { for buffer in buffer_store.buffers() {
buffer.update(cx, |buffer, cx| { buffer.update(cx, |buffer, cx| {
buffer.update_diagnostics(server_id, Default::default(), cx); buffer.update_diagnostics(
server_id,
DiagnosticSet::new([], buffer),
cx,
);
}); });
} }
}); });

View File

@ -36,7 +36,7 @@ impl Rope {
} }
pub fn append(&mut self, rope: Rope) { pub fn append(&mut self, rope: Rope) {
let mut chunks = rope.chunks.cursor::<()>(); let mut chunks = rope.chunks.cursor::<()>(&());
chunks.next(&()); chunks.next(&());
if let Some(chunk) = chunks.item() { if let Some(chunk) = chunks.item() {
if self.chunks.last().map_or(false, |c| c.0.len() < CHUNK_BASE) 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. // Ensure all chunks except maybe the last one are not underflowing.
// Allow some wiggle room for multibyte characters at chunk boundaries. // 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() { while let Some(chunk) = chunks.next() {
if chunks.peek().is_some() { if chunks.peek().is_some() {
assert!(chunk.0.len() + 3 >= CHUNK_BASE); assert!(chunk.0.len() + 3 >= CHUNK_BASE);
@ -245,7 +245,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().len_utf16; 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, &()); cursor.seek(&offset, Bias::Left, &());
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@ -258,7 +258,7 @@ impl Rope {
if offset >= self.summary().len_utf16 { if offset >= self.summary().len_utf16 {
return self.summary().len; 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, &()); cursor.seek(&offset, Bias::Left, &());
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@ -271,7 +271,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().lines; 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, &()); cursor.seek(&offset, Bias::Left, &());
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@ -284,7 +284,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().lines_utf16(); 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, &()); cursor.seek(&offset, Bias::Left, &());
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@ -297,7 +297,7 @@ impl Rope {
if point >= self.summary().lines { if point >= self.summary().lines {
return self.summary().lines_utf16(); 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, &()); cursor.seek(&point, Bias::Left, &());
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@ -310,7 +310,7 @@ impl Rope {
if point >= self.summary().lines { if point >= self.summary().lines {
return self.summary().len; 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, &()); cursor.seek(&point, Bias::Left, &());
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@ -331,7 +331,7 @@ impl Rope {
if point >= self.summary().lines_utf16() { if point >= self.summary().lines_utf16() {
return self.summary().len; 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, &()); cursor.seek(&point, Bias::Left, &());
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@ -344,7 +344,7 @@ impl Rope {
if point.0 >= self.summary().lines_utf16() { if point.0 >= self.summary().lines_utf16() {
return self.summary().lines; 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, &()); cursor.seek(&point.0, Bias::Left, &());
let overshoot = Unclipped(point.0 - cursor.start().0); let overshoot = Unclipped(point.0 - cursor.start().0);
cursor.start().1 cursor.start().1
@ -354,7 +354,7 @@ impl Rope {
} }
pub fn clip_offset(&self, mut offset: usize, bias: Bias) -> usize { pub fn clip_offset(&self, mut offset: usize, bias: Bias) -> usize {
let mut cursor = self.chunks.cursor::<usize>(); let mut cursor = self.chunks.cursor::<usize>(&());
cursor.seek(&offset, Bias::Left, &()); cursor.seek(&offset, Bias::Left, &());
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let mut ix = offset - cursor.start(); let mut ix = offset - cursor.start();
@ -377,7 +377,7 @@ impl Rope {
} }
pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 { pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
let mut cursor = self.chunks.cursor::<OffsetUtf16>(); let mut cursor = self.chunks.cursor::<OffsetUtf16>(&());
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = offset - cursor.start(); let overshoot = offset - cursor.start();
@ -388,7 +388,7 @@ impl Rope {
} }
pub fn clip_point(&self, point: Point, bias: Bias) -> Point { pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
let mut cursor = self.chunks.cursor::<Point>(); let mut cursor = self.chunks.cursor::<Point>(&());
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = point - cursor.start(); let overshoot = point - cursor.start();
@ -399,7 +399,7 @@ impl Rope {
} }
pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 { pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 {
let mut cursor = self.chunks.cursor::<PointUtf16>(); let mut cursor = self.chunks.cursor::<PointUtf16>(&());
cursor.seek(&point.0, Bias::Right, &()); cursor.seek(&point.0, Bias::Right, &());
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = Unclipped(point.0 - cursor.start()); let overshoot = Unclipped(point.0 - cursor.start());
@ -472,7 +472,7 @@ pub struct Cursor<'a> {
impl<'a> Cursor<'a> { impl<'a> Cursor<'a> {
pub fn new(rope: &'a Rope, offset: usize) -> Self { 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, &()); chunks.seek(&offset, Bias::Right, &());
Self { Self {
rope, rope,
@ -521,7 +521,7 @@ impl<'a> Cursor<'a> {
pub fn summary<D: TextDimension>(&mut self, end_offset: usize) -> D { pub fn summary<D: TextDimension>(&mut self, end_offset: usize) -> D {
debug_assert!(end_offset >= self.offset); debug_assert!(end_offset >= self.offset);
let mut summary = D::default(); let mut summary = D::zero(&());
if let Some(start_chunk) = self.chunks.item() { if let Some(start_chunk) = self.chunks.item() {
let start_ix = self.offset - self.chunks.start(); let start_ix = self.offset - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end(&())) - 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> { impl<'a> Chunks<'a> {
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self { pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
let mut chunks = rope.chunks.cursor(); let mut chunks = rope.chunks.cursor(&());
let offset = if reversed { let offset = if reversed {
chunks.seek(&range.end, Bias::Left, &()); chunks.seek(&range.end, Bias::Left, &());
range.end range.end
@ -774,7 +774,7 @@ pub struct Bytes<'a> {
impl<'a> Bytes<'a> { impl<'a> Bytes<'a> {
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self { pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
let mut chunks = rope.chunks.cursor(); let mut chunks = rope.chunks.cursor(&());
if reversed { if reversed {
chunks.seek(&range.end, Bias::Left, &()); chunks.seek(&range.end, Bias::Left, &());
} else { } else {
@ -1180,6 +1180,10 @@ impl<'a> From<&'a str> for ChunkSummary {
impl sum_tree::Summary for ChunkSummary { impl sum_tree::Summary for ChunkSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.text += &summary.text; self.text += &summary.text;
} }
@ -1263,6 +1267,10 @@ impl<'a> From<&'a str> for TextSummary {
impl sum_tree::Summary for TextSummary { impl sum_tree::Summary for TextSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self, _: &Self::Context) {
*self += summary; *self += summary;
} }
@ -1333,6 +1341,10 @@ impl<D1: TextDimension, D2: TextDimension> TextDimension for (D1, D2) {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for TextSummary { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for TextSummary {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
*self += &summary.text; *self += &summary.text;
} }
@ -1349,6 +1361,10 @@ impl TextDimension for TextSummary {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for usize { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for usize {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
*self += summary.text.len; *self += summary.text.len;
} }
@ -1365,6 +1381,10 @@ impl TextDimension for usize {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for OffsetUtf16 { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for OffsetUtf16 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
*self += summary.text.len_utf16; *self += summary.text.len_utf16;
} }
@ -1381,6 +1401,10 @@ impl TextDimension for OffsetUtf16 {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for Point { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for Point {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
*self += summary.text.lines; *self += summary.text.lines;
} }
@ -1397,6 +1421,10 @@ impl TextDimension for Point {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for PointUtf16 { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for PointUtf16 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
*self += summary.text.lines_utf16(); *self += summary.text.lines_utf16();
} }
@ -1890,7 +1918,7 @@ mod tests {
impl Rope { impl Rope {
fn text(&self) -> String { fn text(&self) -> String {
let mut text = String::new(); let mut text = String::new();
for chunk in self.chunks.cursor::<()>() { for chunk in self.chunks.cursor::<()>(&()) {
text.push_str(&chunk.0); text.push_str(&chunk.0);
} }
text text

View File

@ -13,6 +13,10 @@ impl<T> From<T> for Unclipped<T> {
impl<'a, T: sum_tree::Dimension<'a, ChunkSummary>> sum_tree::Dimension<'a, ChunkSummary> impl<'a, T: sum_tree::Dimension<'a, ChunkSummary>> sum_tree::Dimension<'a, ChunkSummary>
for Unclipped<T> for Unclipped<T>
{ {
fn zero(_: &()) -> Self {
Self(T::zero(&()))
}
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) {
self.0.add_summary(summary, &()); self.0.add_summary(summary, &());
} }

View File

@ -28,21 +28,21 @@ where
T: Item, T: Item,
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
{ {
pub fn new(tree: &'a SumTree<T>) -> Self { pub fn new(tree: &'a SumTree<T>, cx: &<T::Summary as Summary>::Context) -> Self {
Self { Self {
tree, tree,
stack: ArrayVec::new(), stack: ArrayVec::new(),
position: D::default(), position: D::zero(cx),
did_seek: false, did_seek: false,
at_end: tree.is_empty(), at_end: tree.is_empty(),
} }
} }
fn reset(&mut self) { fn reset(&mut self, cx: &<T::Summary as Summary>::Context) {
self.did_seek = false; self.did_seek = false;
self.at_end = self.tree.is_empty(); self.at_end = self.tree.is_empty();
self.stack.truncate(0); self.stack.truncate(0);
self.position = D::default(); self.position = D::zero(cx);
} }
pub fn start(&self) -> &D { pub fn start(&self) -> &D {
@ -192,7 +192,7 @@ where
} }
if self.at_end { if self.at_end {
self.position = D::default(); self.position = D::zero(cx);
self.at_end = self.tree.is_empty(); self.at_end = self.tree.is_empty();
if !self.tree.is_empty() { if !self.tree.is_empty() {
self.stack.push(StackEntry { self.stack.push(StackEntry {
@ -208,7 +208,7 @@ where
if let Some(StackEntry { position, .. }) = self.stack.iter().rev().nth(1) { if let Some(StackEntry { position, .. }) = self.stack.iter().rev().nth(1) {
self.position = position.clone(); self.position = position.clone();
} else { } else {
self.position = D::default(); self.position = D::zero(cx);
} }
let entry = self.stack.last_mut().unwrap(); let entry = self.stack.last_mut().unwrap();
@ -232,7 +232,7 @@ where
if descending { if descending {
let tree = &child_trees[entry.index]; let tree = &child_trees[entry.index];
self.stack.push(StackEntry { self.stack.push(StackEntry {
position: D::default(), position: D::zero(cx),
tree, tree,
index: tree.0.child_summaries().len() - 1, index: tree.0.child_summaries().len() - 1,
}) })
@ -264,7 +264,7 @@ where
self.stack.push(StackEntry { self.stack.push(StackEntry {
tree: self.tree, tree: self.tree,
index: 0, index: 0,
position: D::default(), position: D::zero(cx),
}); });
descend = true; descend = true;
} }
@ -364,7 +364,7 @@ where
where where
Target: SeekTarget<'a, T::Summary, D>, Target: SeekTarget<'a, T::Summary, D>,
{ {
self.reset(); self.reset(cx);
self.seek_internal(pos, bias, &mut (), cx) self.seek_internal(pos, bias, &mut (), cx)
} }
@ -392,10 +392,10 @@ where
Target: SeekTarget<'a, T::Summary, D>, Target: SeekTarget<'a, T::Summary, D>,
{ {
let mut slice = SliceSeekAggregate { let mut slice = SliceSeekAggregate {
tree: SumTree::new(), tree: SumTree::new(cx),
leaf_items: ArrayVec::new(), leaf_items: ArrayVec::new(),
leaf_item_summaries: ArrayVec::new(), leaf_item_summaries: ArrayVec::new(),
leaf_summary: T::Summary::default(), leaf_summary: <T::Summary as Summary>::zero(cx),
}; };
self.seek_internal(end, bias, &mut slice, cx); self.seek_internal(end, bias, &mut slice, cx);
slice.tree slice.tree
@ -417,7 +417,7 @@ where
Target: SeekTarget<'a, T::Summary, D>, Target: SeekTarget<'a, T::Summary, D>,
Output: Dimension<'a, T::Summary>, 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); self.seek_internal(end, bias, &mut summary, cx);
summary.0 summary.0
} }
@ -443,7 +443,7 @@ where
self.stack.push(StackEntry { self.stack.push(StackEntry {
tree: self.tree, tree: self.tree,
index: 0, index: 0,
position: Default::default(), position: D::zero(cx),
}); });
} }
@ -633,8 +633,12 @@ where
T: Item, T: Item,
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
{ {
pub fn new(tree: &'a SumTree<T>, filter_node: F) -> Self { pub fn new(
let cursor = tree.cursor::<D>(); tree: &'a SumTree<T>,
cx: &<T::Summary as Summary>::Context,
filter_node: F,
) -> Self {
let cursor = tree.cursor::<D>(cx);
Self { Self {
cursor, cursor,
filter_node, filter_node,
@ -727,7 +731,7 @@ impl<'a, T: Item> SeekAggregate<'a, T> for SliceSeekAggregate<T> {
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) { fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) {
self.tree.append( self.tree.append(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: mem::take(&mut self.leaf_summary), summary: mem::replace(&mut self.leaf_summary, <T::Summary as Summary>::zero(cx)),
items: mem::take(&mut self.leaf_items), items: mem::take(&mut self.leaf_items),
item_summaries: mem::take(&mut self.leaf_item_summaries), item_summaries: mem::take(&mut self.leaf_item_summaries),
})), })),

View File

@ -34,9 +34,11 @@ pub trait KeyedItem: Item {
/// ///
/// Each Summary type can have multiple [`Dimensions`] that it measures, /// Each Summary type can have multiple [`Dimensions`] that it measures,
/// which can be used to navigate the tree /// which can be used to navigate the tree
pub trait Summary: Default + Clone + fmt::Debug { pub trait Summary: Clone + fmt::Debug {
type Context; type Context;
fn zero(cx: &Self::Context) -> Self;
fn add_summary(&mut self, summary: &Self, cx: &Self::Context); fn add_summary(&mut self, summary: &Self, cx: &Self::Context);
} }
@ -47,17 +49,23 @@ pub trait Summary: Default + Clone + fmt::Debug {
/// # Example: /// # Example:
/// Zed's rope has a `TextSummary` type that summarizes lines, characters, and bytes. /// 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 /// Each of these are different dimensions we may want to seek to
pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug + Default { pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug {
fn add_summary(&mut self, _summary: &'a S, _: &S::Context); 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 { 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.add_summary(summary, cx);
dimension dimension
} }
} }
impl<'a, T: Summary> Dimension<'a, T> for T { 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) { fn add_summary(&mut self, summary: &'a T, cx: &T::Context) {
Summary::add_summary(self, summary, cx); 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 () { impl<'a, T: Summary> Dimension<'a, T> for () {
fn zero(_: &T::Context) -> Self {
()
}
fn add_summary(&mut self, _: &'a T, _: &T::Context) {} 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) { 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) { fn add_summary(&mut self, summary: &'a T, cx: &T::Context) {
self.0.add_summary(summary, cx); self.0.add_summary(summary, cx);
self.1.add_summary(summary, cx); self.1.add_summary(summary, cx);
@ -161,16 +177,16 @@ impl Bias {
pub struct SumTree<T: Item>(Arc<Node<T>>); pub struct SumTree<T: Item>(Arc<Node<T>>);
impl<T: Item> SumTree<T> { impl<T: Item> SumTree<T> {
pub fn new() -> Self { pub fn new(cx: &<T::Summary as Summary>::Context) -> Self {
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: T::Summary::default(), summary: <T::Summary as Summary>::zero(cx),
items: ArrayVec::new(), items: ArrayVec::new(),
item_summaries: ArrayVec::new(), item_summaries: ArrayVec::new(),
})) }))
} }
pub fn from_item(item: T, cx: &<T::Summary as Summary>::Context) -> Self { pub fn from_item(item: T, cx: &<T::Summary as Summary>::Context) -> Self {
let mut tree = Self::new(); let mut tree = Self::new(cx);
tree.push(item, cx); tree.push(item, cx);
tree tree
} }
@ -206,7 +222,7 @@ impl<T: Item> SumTree<T> {
let mut current_parent_node = None; let mut current_parent_node = None;
for child_node in nodes.drain(..) { for child_node in nodes.drain(..) {
let parent_node = current_parent_node.get_or_insert_with(|| Node::Internal { let parent_node = current_parent_node.get_or_insert_with(|| Node::Internal {
summary: T::Summary::default(), summary: <T::Summary as Summary>::zero(cx),
height, height,
child_summaries: ArrayVec::new(), child_summaries: ArrayVec::new(),
child_trees: ArrayVec::new(), child_trees: ArrayVec::new(),
@ -234,7 +250,7 @@ impl<T: Item> SumTree<T> {
} }
if nodes.is_empty() { if nodes.is_empty() {
Self::new() Self::new(cx)
} else { } else {
debug_assert_eq!(nodes.len(), 1); debug_assert_eq!(nodes.len(), 1);
Self(Arc::new(nodes.pop().unwrap())) Self(Arc::new(nodes.pop().unwrap()))
@ -296,7 +312,7 @@ impl<T: Item> SumTree<T> {
} }
if nodes.is_empty() { if nodes.is_empty() {
Self::new() Self::new(cx)
} else { } else {
debug_assert_eq!(nodes.len(), 1); debug_assert_eq!(nodes.len(), 1);
nodes.pop().unwrap() nodes.pop().unwrap()
@ -306,7 +322,7 @@ impl<T: Item> SumTree<T> {
#[allow(unused)] #[allow(unused)]
pub fn items(&self, cx: &<T::Summary as Summary>::Context) -> Vec<T> { pub fn items(&self, cx: &<T::Summary as Summary>::Context) -> Vec<T> {
let mut items = Vec::new(); let mut items = Vec::new();
let mut cursor = self.cursor::<()>(); let mut cursor = self.cursor::<()>(cx);
cursor.next(cx); cursor.next(cx);
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
items.push(item.clone()); items.push(item.clone());
@ -319,21 +335,25 @@ impl<T: Item> SumTree<T> {
Iter::new(self) Iter::new(self)
} }
pub fn cursor<'a, S>(&'a self) -> Cursor<T, S> pub fn cursor<'a, S>(&'a self, cx: &<T::Summary as Summary>::Context) -> Cursor<T, S>
where where
S: Dimension<'a, T::Summary>, 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 /// Note: If the summary type requires a non `()` context, then the filter cursor
/// that is returned cannot be used with Rust's iterators. /// that is returned cannot be used with Rust's iterators.
pub fn filter<'a, F, U>(&'a self, filter_node: F) -> FilterCursor<F, T, U> pub fn filter<'a, F, U>(
&'a self,
cx: &<T::Summary as Summary>::Context,
filter_node: F,
) -> FilterCursor<F, T, U>
where where
F: FnMut(&T::Summary) -> bool, F: FnMut(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>, U: Dimension<'a, T::Summary>,
{ {
FilterCursor::new(self, filter_node) FilterCursor::new(self, cx, filter_node)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -389,7 +409,7 @@ impl<T: Item> SumTree<T> {
&'a self, &'a self,
cx: &<T::Summary as Summary>::Context, cx: &<T::Summary as Summary>::Context,
) -> D { ) -> D {
let mut extent = D::default(); let mut extent = D::zero(cx);
match self.0.as_ref() { match self.0.as_ref() {
Node::Internal { summary, .. } | Node::Leaf { summary, .. } => { Node::Internal { summary, .. } | Node::Leaf { summary, .. } => {
extent.add_summary(summary, cx); extent.add_summary(summary, cx);
@ -636,7 +656,7 @@ impl<T: KeyedItem> SumTree<T> {
) -> Option<T> { ) -> Option<T> {
let mut replaced = None; let mut replaced = None;
*self = { *self = {
let mut cursor = self.cursor::<T::Key>(); let mut cursor = self.cursor::<T::Key>(cx);
let mut new_tree = cursor.slice(&item.key(), Bias::Left, cx); let mut new_tree = cursor.slice(&item.key(), Bias::Left, cx);
if let Some(cursor_item) = cursor.item() { if let Some(cursor_item) = cursor.item() {
if cursor_item.key() == item.key() { if cursor_item.key() == item.key() {
@ -654,7 +674,7 @@ impl<T: KeyedItem> SumTree<T> {
pub fn remove(&mut self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<T> { pub fn remove(&mut self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<T> {
let mut removed = None; let mut removed = None;
*self = { *self = {
let mut cursor = self.cursor::<T::Key>(); let mut cursor = self.cursor::<T::Key>(cx);
let mut new_tree = cursor.slice(key, Bias::Left, cx); let mut new_tree = cursor.slice(key, Bias::Left, cx);
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if item.key() == *key { if item.key() == *key {
@ -681,11 +701,11 @@ impl<T: KeyedItem> SumTree<T> {
edits.sort_unstable_by_key(|item| item.key()); edits.sort_unstable_by_key(|item| item.key());
*self = { *self = {
let mut cursor = self.cursor::<T::Key>(); let mut cursor = self.cursor::<T::Key>(cx);
let mut new_tree = SumTree::new(); let mut new_tree = SumTree::new(cx);
let mut buffered_items = Vec::new(); 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 { for edit in edits {
let new_key = edit.key(); let new_key = edit.key();
let mut old_item = cursor.item(); let mut old_item = cursor.item();
@ -724,7 +744,7 @@ impl<T: KeyedItem> SumTree<T> {
} }
pub fn get(&self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<&T> { pub fn get(&self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<&T> {
let mut cursor = self.cursor::<T::Key>(); let mut cursor = self.cursor::<T::Key>(cx);
if cursor.seek(key, Bias::Left, cx) { if cursor.seek(key, Bias::Left, cx) {
cursor.item() cursor.item()
} else { } else {
@ -733,9 +753,13 @@ impl<T: KeyedItem> SumTree<T> {
} }
} }
impl<T: Item> Default for SumTree<T> { impl<T, S> Default for SumTree<T>
where
T: Item<Summary = S>,
S: Summary<Context = ()>,
{
fn default() -> Self { fn default() -> Self {
Self::new() Self::new(&())
} }
} }
@ -824,7 +848,7 @@ where
T: 'a + Summary, T: 'a + Summary,
I: Iterator<Item = &'a T>, I: Iterator<Item = &'a T>,
{ {
let mut sum = T::default(); let mut sum = T::zero(cx);
for value in iter { for value in iter {
sum.add_summary(value, cx); sum.add_summary(value, cx);
} }
@ -846,10 +870,10 @@ mod tests {
#[test] #[test]
fn test_extend_and_push_tree() { fn test_extend_and_push_tree() {
let mut tree1 = SumTree::new(); let mut tree1 = SumTree::default();
tree1.extend(0..20, &()); tree1.extend(0..20, &());
let mut tree2 = SumTree::new(); let mut tree2 = SumTree::default();
tree2.extend(50..100, &()); tree2.extend(50..100, &());
tree1.append(tree2, &()); tree1.append(tree2, &());
@ -877,7 +901,7 @@ mod tests {
let mut rng = StdRng::seed_from_u64(seed); let mut rng = StdRng::seed_from_u64(seed);
let rng = &mut rng; let rng = &mut rng;
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::default();
let count = rng.gen_range(0..10); let count = rng.gen_range(0..10);
if rng.gen() { if rng.gen() {
tree.extend(rng.sample_iter(distributions::Standard).take(count), &()); 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()); reference_items.splice(splice_start..splice_end, new_items.clone());
tree = { tree = {
let mut cursor = tree.cursor::<Count>(); let mut cursor = tree.cursor::<Count>(&());
let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right, &()); let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right, &());
if rng.gen() { if rng.gen() {
new_tree.extend(new_items, &()); new_tree.extend(new_items, &());
@ -918,12 +942,13 @@ mod tests {
assert_eq!(tree.items(&()), reference_items); assert_eq!(tree.items(&()), reference_items);
assert_eq!( assert_eq!(
tree.iter().collect::<Vec<_>>(), tree.iter().collect::<Vec<_>>(),
tree.cursor::<()>().collect::<Vec<_>>() tree.cursor::<()>(&()).collect::<Vec<_>>()
); );
log::info!("tree items: {:?}", tree.items(&())); 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 let expected_filtered_items = tree
.items(&()) .items(&())
.into_iter() .into_iter()
@ -964,7 +989,7 @@ mod tests {
assert_eq!(filter_cursor.item(), None); assert_eq!(filter_cursor.item(), None);
let mut before_start = false; let mut before_start = false;
let mut cursor = tree.cursor::<Count>(); let mut cursor = tree.cursor::<Count>(&());
let start_pos = rng.gen_range(0..=reference_items.len()); let start_pos = rng.gen_range(0..=reference_items.len());
cursor.seek(&Count(start_pos), Bias::Right, &()); cursor.seek(&Count(start_pos), Bias::Right, &());
let mut pos = rng.gen_range(start_pos..=reference_items.len()); 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 start_bias = if rng.gen() { Bias::Left } else { Bias::Right };
let end_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::<Count>(); let mut cursor = tree.cursor::<Count>(&());
cursor.seek(&Count(start), start_bias, &()); cursor.seek(&Count(start), start_bias, &());
let slice = cursor.slice(&Count(end), end_bias, &()); let slice = cursor.slice(&Count(end), end_bias, &());
@ -1030,8 +1055,8 @@ mod tests {
#[test] #[test]
fn test_cursor() { fn test_cursor() {
// Empty tree // Empty tree
let tree = SumTree::<u8>::new(); let tree = SumTree::<u8>::default();
let mut cursor = tree.cursor::<IntegersSummary>(); let mut cursor = tree.cursor::<IntegersSummary>(&());
assert_eq!( assert_eq!(
cursor.slice(&Count(0), Bias::Right, &()).items(&()), cursor.slice(&Count(0), Bias::Right, &()).items(&()),
Vec::<u8>::new() Vec::<u8>::new()
@ -1052,9 +1077,9 @@ mod tests {
assert_eq!(cursor.start().sum, 0); assert_eq!(cursor.start().sum, 0);
// Single-element tree // Single-element tree
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::default();
tree.extend(vec![1], &()); tree.extend(vec![1], &());
let mut cursor = tree.cursor::<IntegersSummary>(); let mut cursor = tree.cursor::<IntegersSummary>(&());
assert_eq!( assert_eq!(
cursor.slice(&Count(0), Bias::Right, &()).items(&()), cursor.slice(&Count(0), Bias::Right, &()).items(&()),
Vec::<u8>::new() Vec::<u8>::new()
@ -1076,7 +1101,7 @@ mod tests {
assert_eq!(cursor.next_item(), None); assert_eq!(cursor.next_item(), None);
assert_eq!(cursor.start().sum, 0); assert_eq!(cursor.start().sum, 0);
let mut cursor = tree.cursor::<IntegersSummary>(); let mut cursor = tree.cursor::<IntegersSummary>(&());
assert_eq!(cursor.slice(&Count(1), Bias::Right, &()).items(&()), [1]); assert_eq!(cursor.slice(&Count(1), Bias::Right, &()).items(&()), [1]);
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&1)); assert_eq!(cursor.prev_item(), Some(&1));
@ -1096,9 +1121,9 @@ mod tests {
assert_eq!(cursor.start().sum, 1); assert_eq!(cursor.start().sum, 1);
// Multiple-element tree // Multiple-element tree
let mut tree = SumTree::new(); let mut tree = SumTree::default();
tree.extend(vec![1, 2, 3, 4, 5, 6], &()); tree.extend(vec![1, 2, 3, 4, 5, 6], &());
let mut cursor = tree.cursor::<IntegersSummary>(); let mut cursor = tree.cursor::<IntegersSummary>(&());
assert_eq!(cursor.slice(&Count(2), Bias::Right, &()).items(&()), [1, 2]); assert_eq!(cursor.slice(&Count(2), Bias::Right, &()).items(&()), [1, 2]);
assert_eq!(cursor.item(), Some(&3)); assert_eq!(cursor.item(), Some(&3));
@ -1179,7 +1204,7 @@ mod tests {
assert_eq!(cursor.next_item(), Some(&2)); assert_eq!(cursor.next_item(), Some(&2));
assert_eq!(cursor.start().sum, 0); assert_eq!(cursor.start().sum, 0);
let mut cursor = tree.cursor::<IntegersSummary>(); let mut cursor = tree.cursor::<IntegersSummary>(&());
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(&()), Bias::Right, &()) .slice(&tree.extent::<Count>(&()), Bias::Right, &())
@ -1227,7 +1252,7 @@ mod tests {
#[test] #[test]
fn test_edit() { fn test_edit() {
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::default();
let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &()); let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &());
assert_eq!(tree.items(&()), vec![0, 1, 2]); assert_eq!(tree.items(&()), vec![0, 1, 2]);
@ -1305,6 +1330,10 @@ mod tests {
impl Summary for IntegersSummary { impl Summary for IntegersSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
self.count += other.count; self.count += other.count;
self.sum += other.sum; self.sum += other.sum;
@ -1314,12 +1343,20 @@ mod tests {
} }
impl<'a> Dimension<'a, IntegersSummary> for u8 { impl<'a> Dimension<'a, IntegersSummary> for u8 {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
*self = summary.max; *self = summary.max;
} }
} }
impl<'a> Dimension<'a, IntegersSummary> for Count { impl<'a> Dimension<'a, IntegersSummary> for Count {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
self.0 += summary.count; self.0 += summary.count;
} }
@ -1332,6 +1369,10 @@ mod tests {
} }
impl<'a> Dimension<'a, IntegersSummary> for Sum { impl<'a> Dimension<'a, IntegersSummary> for Sum {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
self.0 += summary.sum; self.0 += summary.sum;
} }

View File

@ -53,7 +53,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
} }
pub fn get(&self, key: &K) -> Option<&V> { pub fn get(&self, key: &K) -> Option<&V> {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
cursor.seek(&MapKeyRef(Some(key)), Bias::Left, &()); cursor.seek(&MapKeyRef(Some(key)), Bias::Left, &());
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if Some(key) == item.key().0.as_ref() { if Some(key) == item.key().0.as_ref() {
@ -72,7 +72,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
pub fn remove(&mut self, key: &K) -> Option<V> { pub fn remove(&mut self, key: &K) -> Option<V> {
let mut removed = None; let mut removed = None;
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
let mut new_tree = cursor.slice(&key, Bias::Left, &()); let mut new_tree = cursor.slice(&key, Bias::Left, &());
if key.cmp(&cursor.end(&()), &()) == Ordering::Equal { if key.cmp(&cursor.end(&()), &()) == Ordering::Equal {
@ -88,7 +88,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
pub fn remove_range(&mut self, start: &impl MapSeekTarget<K>, end: &impl MapSeekTarget<K>) { pub fn remove_range(&mut self, start: &impl MapSeekTarget<K>, end: &impl MapSeekTarget<K>) {
let start = MapSeekTargetAdaptor(start); let start = MapSeekTargetAdaptor(start);
let end = MapSeekTargetAdaptor(end); let end = MapSeekTargetAdaptor(end);
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
let mut new_tree = cursor.slice(&start, Bias::Left, &()); let mut new_tree = cursor.slice(&start, Bias::Left, &());
cursor.seek(&end, Bias::Left, &()); cursor.seek(&end, Bias::Left, &());
new_tree.append(cursor.suffix(&()), &()); new_tree.append(cursor.suffix(&()), &());
@ -98,7 +98,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
/// Returns the key-value pair with the greatest key less than or equal to the given key. /// 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)> { pub fn closest(&self, key: &K) -> Option<(&K, &V)> {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
cursor.seek(&key, Bias::Right, &()); cursor.seek(&key, Bias::Right, &());
cursor.prev(&()); cursor.prev(&());
@ -106,7 +106,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
} }
pub fn iter_from<'a>(&'a self, from: &'a K) -> impl Iterator<Item = (&K, &V)> + '_ { pub fn iter_from<'a>(&'a self, from: &'a K) -> impl Iterator<Item = (&K, &V)> + '_ {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
let from_key = MapKeyRef(Some(from)); let from_key = MapKeyRef(Some(from));
cursor.seek(&from_key, Bias::Left, &()); cursor.seek(&from_key, Bias::Left, &());
@ -117,7 +117,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
where where
F: FnOnce(&mut V) -> T, F: FnOnce(&mut V) -> T,
{ {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
let mut new_tree = cursor.slice(&key, Bias::Left, &()); let mut new_tree = cursor.slice(&key, Bias::Left, &());
let mut result = None; let mut result = None;
@ -136,7 +136,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
pub fn retain<F: FnMut(&K, &V) -> bool>(&mut self, mut predicate: F) { pub fn retain<F: FnMut(&K, &V) -> bool>(&mut self, mut predicate: F) {
let mut new_map = SumTree::<MapEntry<K, V>>::default(); let mut new_map = SumTree::<MapEntry<K, V>>::default();
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&());
cursor.next(&()); cursor.next(&());
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
if predicate(&item.key, &item.value) { if predicate(&item.key, &item.value) {
@ -247,6 +247,10 @@ where
{ {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
*self = summary.clone() *self = summary.clone()
} }
@ -256,6 +260,10 @@ impl<'a, K> Dimension<'a, MapKey<K>> for MapKeyRef<'a, K>
where where
K: Clone + Debug + Ord, K: Clone + Debug + Ord,
{ {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a MapKey<K>, _: &()) { fn add_summary(&mut self, summary: &'a MapKey<K>, _: &()) {
self.0 = summary.0.as_ref(); self.0 = summary.0.as_ref();
} }

View File

@ -100,7 +100,7 @@ impl Anchor {
false false
} else { } else {
let fragment_id = buffer.fragment_id_for_anchor(self); 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.seek(&Some(fragment_id), Bias::Left, &None);
fragment_cursor fragment_cursor
.item() .item()

View File

@ -85,6 +85,10 @@ impl sum_tree::KeyedItem for Locator {
impl sum_tree::Summary for Locator { impl sum_tree::Summary for Locator {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
self.assign(summary); self.assign(summary);
} }

View File

@ -34,7 +34,7 @@ impl<T: Operation> Default for OperationQueue<T> {
impl<T: Operation> OperationQueue<T> { impl<T: Operation> OperationQueue<T> {
pub fn new() -> Self { pub fn new() -> Self {
OperationQueue(SumTree::new()) OperationQueue(SumTree::default())
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
@ -58,7 +58,7 @@ impl<T: Operation> OperationQueue<T> {
pub fn drain(&mut self) -> Self { pub fn drain(&mut self) -> Self {
let clone = self.clone(); let clone = self.clone();
self.0 = SumTree::new(); self.0 = SumTree::default();
clone clone
} }
@ -70,6 +70,10 @@ impl<T: Operation> OperationQueue<T> {
impl Summary for OperationSummary { impl Summary for OperationSummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self, _: &()) {
assert!(self.key < other.key); assert!(self.key < other.key);
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 { impl<'a> Dimension<'a, OperationSummary> for OperationKey {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &OperationSummary, _: &()) { fn add_summary(&mut self, summary: &OperationSummary, _: &()) {
assert!(*self <= summary.key); assert!(*self <= summary.key);
*self = summary.key; *self = summary.key;

View File

@ -492,6 +492,10 @@ struct FragmentTextSummary {
} }
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary { impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) { fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
self.visible += summary.text.visible; self.visible += summary.text.visible;
self.deleted += summary.text.deleted; self.deleted += summary.text.deleted;
@ -654,8 +658,8 @@ impl Buffer {
normalized: Rope, normalized: Rope,
) -> Buffer { ) -> Buffer {
let history = History::new(normalized); let history = History::new(normalized);
let mut fragments = SumTree::new(); let mut fragments = SumTree::new(&None);
let mut insertions = SumTree::new(); let mut insertions = SumTree::default();
let mut lamport_clock = clock::Lamport::new(replica_id); let mut lamport_clock = clock::Lamport::new(replica_id);
let mut version = clock::Global::new(); let mut version = clock::Global::new();
@ -772,7 +776,7 @@ impl Buffer {
let mut new_ropes = let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>(); let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>(&None);
let mut new_fragments = let mut new_fragments =
old_fragments.slice(&edits.peek().unwrap().0.start, Bias::Right, &None); old_fragments.slice(&edits.peek().unwrap().0.start, Bias::Right, &None);
new_ropes.append(new_fragments.summary().text); new_ropes.append(new_fragments.summary().text);
@ -992,7 +996,7 @@ impl Buffer {
let mut insertion_offset = 0; let mut insertion_offset = 0;
let mut new_ropes = let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); 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( let mut new_fragments = old_fragments.slice(
&VersionedFullOffset::Offset(ranges[0].start), &VersionedFullOffset::Offset(ranges[0].start),
Bias::Left, Bias::Left,
@ -1185,7 +1189,7 @@ impl Buffer {
// Get all of the fragments corresponding to these insertion slices. // Get all of the fragments corresponding to these insertion slices.
let mut fragment_ids = Vec::new(); let mut fragment_ids = Vec::new();
let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(); let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
for insertion_slice in &insertion_slices { for insertion_slice in &insertion_slices {
if insertion_slice.insertion_id != insertions_cursor.start().timestamp if insertion_slice.insertion_id != insertions_cursor.start().timestamp
|| insertion_slice.range.start > insertions_cursor.start().split_offset || insertion_slice.range.start > insertions_cursor.start().split_offset
@ -1217,8 +1221,8 @@ impl Buffer {
self.snapshot.undo_map.insert(undo); self.snapshot.undo_map.insert(undo);
let mut edits = Patch::default(); let mut edits = Patch::default();
let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(); let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
let mut new_fragments = SumTree::new(); let mut new_fragments = SumTree::new(&None);
let mut new_ropes = let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0)); RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
@ -1455,7 +1459,7 @@ impl Buffer {
D: TextDimension, D: TextDimension,
{ {
// get fragment ranges // 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 let offset_ranges = self
.fragment_ids_for_edits(transaction.edit_ids.iter()) .fragment_ids_for_edits(transaction.edit_ids.iter())
.into_iter() .into_iter()
@ -1485,7 +1489,7 @@ impl Buffer {
}); });
// convert to the desired text dimension. // 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); let mut rope_cursor = self.visible_text.cursor(0);
disjoint_ranges.map(move |range| { disjoint_ranges.map(move |range| {
position.add_assign(&rope_cursor.summary(range.start)); position.add_assign(&rope_cursor.summary(range.start));
@ -1665,8 +1669,8 @@ impl Buffer {
); );
} }
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(); let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(&None);
for insertion_fragment in self.snapshot.insertions.cursor::<()>() { for insertion_fragment in self.snapshot.insertions.cursor::<()>(&()) {
cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left, &None); cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left, &None);
let fragment = cursor.item().unwrap(); let fragment = cursor.item().unwrap();
assert_eq!(insertion_fragment.fragment_id, fragment.id); assert_eq!(insertion_fragment.fragment_id, fragment.id);
@ -1783,7 +1787,7 @@ impl BufferSnapshot {
let mut cursor = self let mut cursor = self
.fragments .fragments
.filter::<_, FragmentTextSummary>(move |summary| { .filter::<_, FragmentTextSummary>(&None, move |summary| {
!version.observed_all(&summary.max_version) !version.observed_all(&summary.max_version)
}); });
cursor.next(&None); cursor.next(&None);
@ -2110,14 +2114,14 @@ impl BufferSnapshot {
A: 'a + IntoIterator<Item = (&'a Anchor, T)>, A: 'a + IntoIterator<Item = (&'a Anchor, T)>,
{ {
let anchors = anchors.into_iter(); let anchors = anchors.into_iter();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(); let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
let mut text_cursor = self.visible_text.cursor(0); let mut text_cursor = self.visible_text.cursor(0);
let mut position = D::default(); let mut position = D::zero(&());
anchors.map(move |(anchor, payload)| { anchors.map(move |(anchor, payload)| {
if *anchor == Anchor::MIN { if *anchor == Anchor::MIN {
return (D::default(), payload); return (D::zero(&()), payload);
} else if *anchor == Anchor::MAX { } else if *anchor == Anchor::MAX {
return (D::from_text_summary(&self.visible_text.summary()), payload); return (D::from_text_summary(&self.visible_text.summary()), payload);
} }
@ -2159,7 +2163,7 @@ impl BufferSnapshot {
D: TextDimension, D: TextDimension,
{ {
if *anchor == Anchor::MIN { if *anchor == Anchor::MIN {
D::default() D::zero(&())
} else if *anchor == Anchor::MAX { } else if *anchor == Anchor::MAX {
D::from_text_summary(&self.visible_text.summary()) D::from_text_summary(&self.visible_text.summary())
} else { } else {
@ -2167,7 +2171,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp, timestamp: anchor.timestamp,
split_offset: anchor.offset, split_offset: anchor.offset,
}; };
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
insertion_cursor.seek(&anchor_key, anchor.bias, &()); insertion_cursor.seek(&anchor_key, anchor.bias, &());
if let Some(insertion) = insertion_cursor.item() { if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); 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); fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None);
let fragment = fragment_cursor.item().unwrap(); let fragment = fragment_cursor.item().unwrap();
let mut fragment_offset = fragment_cursor.start().1; let mut fragment_offset = fragment_cursor.start().1;
@ -2213,7 +2217,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp, timestamp: anchor.timestamp,
split_offset: anchor.offset, split_offset: anchor.offset,
}; };
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
insertion_cursor.seek(&anchor_key, anchor.bias, &()); insertion_cursor.seek(&anchor_key, anchor.bias, &());
if let Some(insertion) = insertion_cursor.item() { if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
@ -2263,7 +2267,7 @@ impl BufferSnapshot {
} else if bias == Bias::Right && offset == self.len() { } else if bias == Bias::Right && offset == self.len() {
Anchor::MAX Anchor::MAX
} else { } else {
let mut fragment_cursor = self.fragments.cursor::<usize>(); let mut fragment_cursor = self.fragments.cursor::<usize>(&None);
fragment_cursor.seek(&offset, bias, &None); fragment_cursor.seek(&offset, bias, &None);
let fragment = fragment_cursor.item().unwrap(); let fragment = fragment_cursor.item().unwrap();
let overshoot = offset - *fragment_cursor.start(); let overshoot = offset - *fragment_cursor.start();
@ -2341,15 +2345,15 @@ impl BufferSnapshot {
let fragments_cursor = if *since == self.version { let fragments_cursor = if *since == self.version {
None None
} else { } else {
let mut cursor = self let mut cursor = self.fragments.filter(&None, move |summary| {
.fragments !since.observed_all(&summary.max_version)
.filter(move |summary| !since.observed_all(&summary.max_version)); });
cursor.next(&None); cursor.next(&None);
Some(cursor) Some(cursor)
}; };
let mut cursor = self let mut cursor = self
.fragments .fragments
.cursor::<(Option<&Locator>, FragmentTextSummary)>(); .cursor::<(Option<&Locator>, FragmentTextSummary)>(&None);
let start_fragment_id = self.fragment_id_for_anchor(&range.start); let start_fragment_id = self.fragment_id_for_anchor(&range.start);
cursor.seek(&Some(start_fragment_id), Bias::Left, &None); cursor.seek(&Some(start_fragment_id), Bias::Left, &None);
@ -2371,8 +2375,8 @@ impl BufferSnapshot {
fragments_cursor, fragments_cursor,
undos: &self.undo_map, undos: &self.undo_map,
since, since,
old_end: Default::default(), old_end: D::zero(&()),
new_end: Default::default(), new_end: D::zero(&()),
range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset), range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
buffer_id: self.remote_id, buffer_id: self.remote_id,
} }
@ -2382,9 +2386,9 @@ impl BufferSnapshot {
if *since != self.version { if *since != self.version {
let start_fragment_id = self.fragment_id_for_anchor(&range.start); let start_fragment_id = self.fragment_id_for_anchor(&range.start);
let end_fragment_id = self.fragment_id_for_anchor(&range.end); let end_fragment_id = self.fragment_id_for_anchor(&range.end);
let mut cursor = self let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
.fragments !since.observed_all(&summary.max_version)
.filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version)); });
cursor.next(&None); cursor.next(&None);
while let Some(fragment) = cursor.item() { while let Some(fragment) = cursor.item() {
if fragment.id > *end_fragment_id { if fragment.id > *end_fragment_id {
@ -2405,9 +2409,9 @@ impl BufferSnapshot {
pub fn has_edits_since(&self, since: &clock::Global) -> bool { pub fn has_edits_since(&self, since: &clock::Global) -> bool {
if *since != self.version { if *since != self.version {
let mut cursor = self let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
.fragments !since.observed_all(&summary.max_version)
.filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version)); });
cursor.next(&None); cursor.next(&None);
while let Some(fragment) = cursor.item() { while let Some(fragment) = cursor.item() {
let was_visible = fragment.was_visible(since, &self.undo_map); 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 { impl sum_tree::Summary for FragmentSummary {
type Context = Option<clock::Global>; type Context = Option<clock::Global>;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &Self::Context) { fn add_summary(&mut self, other: &Self, _: &Self::Context) {
self.max_id.assign(&other.max_id); self.max_id.assign(&other.max_id);
self.text.visible += &other.text.visible; self.text.visible += &other.text.visible;
@ -2704,6 +2712,10 @@ impl InsertionFragment {
impl sum_tree::Summary for InsertionFragmentKey { impl sum_tree::Summary for InsertionFragmentKey {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self, _: &()) {
*self = *summary; *self = *summary;
} }
@ -2736,18 +2748,30 @@ impl ops::Sub for FullOffset {
} }
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize { impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) { fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
*self += summary.text.visible; *self += summary.text.visible;
} }
} }
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset { impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) { fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
self.0 += summary.text.visible + summary.text.deleted; self.0 += summary.text.visible + summary.text.deleted;
} }
} }
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> { impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) { fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
*self = Some(&summary.max_id); *self = Some(&summary.max_id);
} }
@ -2786,6 +2810,10 @@ impl Default for VersionedFullOffset {
} }
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset { impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
fn zero(_cx: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) { fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
if let Self::Offset(offset) = self { if let Self::Offset(offset) = self {
let version = cx.as_ref().unwrap(); let version = cx.as_ref().unwrap();

View File

@ -33,6 +33,10 @@ struct UndoMapKey {
impl sum_tree::Summary for UndoMapKey { impl sum_tree::Summary for UndoMapKey {
type Context = (); type Context = ();
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self, _: &Self::Context) {
*self = cmp::max(*self, *summary); *self = cmp::max(*self, *summary);
} }
@ -62,9 +66,8 @@ impl UndoMap {
pub fn is_undone(&self, edit_id: clock::Lamport) -> bool { pub fn is_undone(&self, edit_id: clock::Lamport) -> bool {
self.undo_count(edit_id) % 2 == 1 self.undo_count(edit_id) % 2 == 1
} }
pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool { pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool {
let mut cursor = self.0.cursor::<UndoMapKey>(); let mut cursor = self.0.cursor::<UndoMapKey>(&());
cursor.seek( cursor.seek(
&UndoMapKey { &UndoMapKey {
edit_id, edit_id,
@ -89,7 +92,7 @@ impl UndoMap {
} }
pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 { pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 {
let mut cursor = self.0.cursor::<UndoMapKey>(); let mut cursor = self.0.cursor::<UndoMapKey>(&());
cursor.seek( cursor.seek(
&UndoMapKey { &UndoMapKey {
edit_id, edit_id,

View File

@ -2049,7 +2049,7 @@ impl Snapshot {
fn delete_entry(&mut self, entry_id: ProjectEntryId) -> Option<Arc<Path>> { fn delete_entry(&mut self, entry_id: ProjectEntryId) -> Option<Arc<Path>> {
let removed_entry = self.entries_by_id.remove(&entry_id, &())?; let removed_entry = self.entries_by_id.remove(&entry_id, &())?;
self.entries_by_path = { self.entries_by_path = {
let mut cursor = self.entries_by_path.cursor::<TraversalProgress>(); let mut cursor = self.entries_by_path.cursor::<TraversalProgress>(&());
let mut new_entries_by_path = let mut new_entries_by_path =
cursor.slice(&TraversalTarget::Path(&removed_entry.path), Bias::Left, &()); cursor.slice(&TraversalTarget::Path(&removed_entry.path), Bias::Left, &());
while let Some(entry) = cursor.item() { while let Some(entry) = cursor.item() {
@ -2192,7 +2192,7 @@ impl Snapshot {
include_ignored: bool, include_ignored: bool,
start_offset: usize, start_offset: usize,
) -> Traversal { ) -> Traversal {
let mut cursor = self.entries_by_path.cursor(); let mut cursor = self.entries_by_path.cursor(&());
cursor.seek( cursor.seek(
&TraversalTarget::Count { &TraversalTarget::Count {
count: start_offset, count: start_offset,
@ -2302,7 +2302,7 @@ impl Snapshot {
pub fn propagate_git_statuses(&self, result: &mut [Entry]) { pub fn propagate_git_statuses(&self, result: &mut [Entry]) {
let mut cursor = self let mut cursor = self
.entries_by_path .entries_by_path
.cursor::<(TraversalProgress, GitStatuses)>(); .cursor::<(TraversalProgress, GitStatuses)>(&());
let mut entry_stack = Vec::<(usize, GitStatuses)>::new(); let mut entry_stack = Vec::<(usize, GitStatuses)>::new();
let mut result_ix = 0; let mut result_ix = 0;
@ -2358,13 +2358,13 @@ impl Snapshot {
pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> { pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> {
let empty_path = Path::new(""); let empty_path = Path::new("");
self.entries_by_path self.entries_by_path
.cursor::<()>() .cursor::<()>(&())
.filter(move |entry| entry.path.as_ref() != empty_path) .filter(move |entry| entry.path.as_ref() != empty_path)
.map(|entry| &entry.path) .map(|entry| &entry.path)
} }
pub fn child_entries<'a>(&'a self, parent_path: &'a Path) -> ChildEntriesIter<'a> { 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, &()); cursor.seek(&TraversalTarget::Path(parent_path), Bias::Right, &());
let traversal = Traversal { let traversal = Traversal {
cursor, cursor,
@ -2581,7 +2581,7 @@ impl LocalSnapshot {
#[cfg(test)] #[cfg(test)]
pub(crate) fn expanded_entries(&self) -> impl Iterator<Item = &Entry> { pub(crate) fn expanded_entries(&self) -> impl Iterator<Item = &Entry> {
self.entries_by_path self.entries_by_path
.cursor::<()>() .cursor::<()>(&())
.filter(|entry| entry.kind == EntryKind::Dir && (entry.is_external || entry.is_ignored)) .filter(|entry| entry.kind == EntryKind::Dir && (entry.is_external || entry.is_ignored))
} }
@ -2591,11 +2591,11 @@ impl LocalSnapshot {
assert_eq!( assert_eq!(
self.entries_by_path self.entries_by_path
.cursor::<()>() .cursor::<()>(&())
.map(|e| (&e.path, e.id)) .map(|e| (&e.path, e.id))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.entries_by_id self.entries_by_id
.cursor::<()>() .cursor::<()>(&())
.map(|e| (&e.path, e.id)) .map(|e| (&e.path, e.id))
.collect::<collections::BTreeSet<_>>() .collect::<collections::BTreeSet<_>>()
.into_iter() .into_iter()
@ -2605,7 +2605,7 @@ impl LocalSnapshot {
let mut files = self.files(true, 0); let mut files = self.files(true, 0);
let mut visible_files = self.files(false, 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() { if entry.is_file() {
assert_eq!(files.next().unwrap().inode, entry.inode); assert_eq!(files.next().unwrap().inode, entry.inode);
if !entry.is_ignored && !entry.is_external { if !entry.is_ignored && !entry.is_external {
@ -2633,7 +2633,7 @@ impl LocalSnapshot {
let dfs_paths_via_iter = self let dfs_paths_via_iter = self
.entries_by_path .entries_by_path
.cursor::<()>() .cursor::<()>(&())
.map(|e| e.path.as_ref()) .map(|e| e.path.as_ref())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!(bfs_paths, dfs_paths_via_iter); assert_eq!(bfs_paths, dfs_paths_via_iter);
@ -2679,7 +2679,7 @@ impl LocalSnapshot {
#[cfg(test)] #[cfg(test)]
pub fn entries_without_ids(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> { pub fn entries_without_ids(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> {
let mut paths = Vec::new(); 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 { if include_ignored || !entry.is_ignored {
paths.push((entry.path.as_ref(), entry.inode, 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 mut new_entries;
let removed_entries; let removed_entries;
{ {
let mut cursor = self.snapshot.entries_by_path.cursor::<TraversalProgress>(); let mut cursor = self
.snapshot
.entries_by_path
.cursor::<TraversalProgress>(&());
new_entries = cursor.slice(&TraversalTarget::Path(path), Bias::Left, &()); new_entries = cursor.slice(&TraversalTarget::Path(path), Bias::Left, &());
removed_entries = cursor.slice(&TraversalTarget::PathSuccessor(path), Bias::Left, &()); removed_entries = cursor.slice(&TraversalTarget::PathSuccessor(path), Bias::Left, &());
new_entries.append(cursor.suffix(&()), &()); new_entries.append(cursor.suffix(&()), &());
@ -2847,7 +2850,7 @@ impl BackgroundScannerState {
self.snapshot.entries_by_path = new_entries; self.snapshot.entries_by_path = new_entries;
let mut removed_ids = Vec::with_capacity(removed_entries.summary().count); 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) { match self.removed_entries.entry(entry.inode) {
hash_map::Entry::Occupied(mut e) => { hash_map::Entry::Occupied(mut e) => {
let prev_removed_entry = e.get_mut(); let prev_removed_entry = e.get_mut();
@ -3403,6 +3406,10 @@ impl Default for EntrySummary {
impl sum_tree::Summary for EntrySummary { impl sum_tree::Summary for EntrySummary {
type Context = (); type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, rhs: &Self, _: &()) { fn add_summary(&mut self, rhs: &Self, _: &()) {
self.max_path = rhs.max_path.clone(); self.max_path = rhs.max_path.clone();
self.count += rhs.count; self.count += rhs.count;
@ -3445,12 +3452,20 @@ struct PathEntrySummary {
impl sum_tree::Summary for PathEntrySummary { impl sum_tree::Summary for PathEntrySummary {
type Context = (); type Context = ();
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self, _: &Self::Context) {
self.max_id = summary.max_id; self.max_id = summary.max_id;
} }
} }
impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId { impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a PathEntrySummary, _: &()) { fn add_summary(&mut self, summary: &'a PathEntrySummary, _: &()) {
*self = summary.max_id; *self = summary.max_id;
} }
@ -3466,6 +3481,10 @@ impl Default for PathKey {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
self.0 = summary.max_path.clone(); self.0 = summary.max_path.clone();
} }
@ -4629,8 +4648,8 @@ impl BackgroundScanner {
// Identify which paths have changed. Use the known set of changed // Identify which paths have changed. Use the known set of changed
// parent paths to optimize the search. // parent paths to optimize the search.
let mut changes = Vec::new(); let mut changes = Vec::new();
let mut old_paths = old_snapshot.entries_by_path.cursor::<PathKey>(); let mut old_paths = old_snapshot.entries_by_path.cursor::<PathKey>(&());
let mut new_paths = new_snapshot.entries_by_path.cursor::<PathKey>(); let mut new_paths = new_snapshot.entries_by_path.cursor::<PathKey>(&());
let mut last_newly_loaded_dir_path = None; let mut last_newly_loaded_dir_path = None;
old_paths.next(&()); old_paths.next(&());
new_paths.next(&()); new_paths.next(&());
@ -4981,6 +5000,10 @@ impl<'a> TraversalProgress<'a> {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> for 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, _: &()) { fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
self.max_path = summary.max_path.as_ref(); self.max_path = summary.max_path.as_ref();
self.count += summary.count; self.count += summary.count;
@ -5030,6 +5053,10 @@ impl Sub for GitStatuses {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> 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, _: &()) { fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
*self += summary.statuses *self += summary.statuses
} }
@ -5050,7 +5077,7 @@ impl<'a> Traversal<'a> {
include_ignored: bool, include_ignored: bool,
start_path: &Path, start_path: &Path,
) -> Self { ) -> Self {
let mut cursor = entries.cursor(); let mut cursor = entries.cursor(&());
cursor.seek(&TraversalTarget::Path(start_path), Bias::Left, &()); cursor.seek(&TraversalTarget::Path(start_path), Bias::Left, &());
let mut traversal = Self { let mut traversal = Self {
cursor, cursor,