diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index e667a0c61d..1076c7da3b 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -333,12 +333,15 @@ impl ProjectDiagnosticsEditor { Point::new(range.end.row + CONTEXT_LINE_COUNT, u32::MAX), Bias::Left, ); - let excerpt_id = excerpts.insert_excerpt_after( - &prev_excerpt_id, - buffer.clone(), - excerpt_start..excerpt_end, - excerpts_cx, - ); + let excerpt_id = excerpts + .insert_excerpts_after( + &prev_excerpt_id, + buffer.clone(), + [excerpt_start..excerpt_end], + excerpts_cx, + ) + .pop() + .unwrap(); prev_excerpt_id = excerpt_id.clone(); first_excerpt_id.get_or_insert_with(|| prev_excerpt_id.clone()); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 5de2d39231..d281724334 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7870,8 +7870,14 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpt(buffer.clone(), Point::new(0, 0)..Point::new(0, 4), cx); - multibuffer.push_excerpt(buffer.clone(), Point::new(1, 0)..Point::new(1, 4), cx); + multibuffer.push_excerpts( + buffer.clone(), + [ + Point::new(0, 0)..Point::new(0, 4), + Point::new(1, 0)..Point::new(1, 4), + ], + cx, + ); multibuffer }); @@ -7909,8 +7915,14 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(3, 4, 'a'), cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpt(buffer, Point::new(0, 0)..Point::new(1, 4), cx); - multibuffer.push_excerpt(buffer, Point::new(1, 0)..Point::new(2, 4), cx); + multibuffer.push_excerpts( + buffer, + [ + Point::new(0, 0)..Point::new(1, 4), + Point::new(1, 0)..Point::new(2, 4), + ], + cx, + ); multibuffer }); @@ -7961,12 +7973,17 @@ mod tests { let mut excerpt1_id = None; let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - excerpt1_id = Some(multibuffer.push_excerpt( - buffer.clone(), - Point::new(0, 0)..Point::new(1, 4), - cx, - )); - multibuffer.push_excerpt(buffer.clone(), Point::new(1, 0)..Point::new(2, 4), cx); + excerpt1_id = multibuffer + .push_excerpts( + buffer.clone(), + [ + Point::new(0, 0)..Point::new(1, 4), + Point::new(1, 0)..Point::new(2, 4), + ], + cx, + ) + .into_iter() + .next(); multibuffer }); assert_eq!( diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 58bf12f2ae..5951e2c20d 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -239,8 +239,14 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndefg\nhijkl\nmn", cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpt(buffer.clone(), Point::new(0, 0)..Point::new(1, 4), cx); - multibuffer.push_excerpt(buffer.clone(), Point::new(2, 0)..Point::new(3, 2), cx); + multibuffer.push_excerpts( + buffer.clone(), + [ + Point::new(0, 0)..Point::new(1, 4), + Point::new(2, 0)..Point::new(3, 2), + ], + cx, + ); multibuffer }); diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 7ac890eeae..6828696b90 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -173,7 +173,7 @@ impl MultiBuffer { pub fn singleton(buffer: ModelHandle, cx: &mut ModelContext) -> Self { let mut this = Self::new(buffer.read(cx).replica_id()); this.singleton = true; - this.push_excerpt(buffer, text::Anchor::min()..text::Anchor::max(), cx); + this.push_excerpts(buffer, [text::Anchor::min()..text::Anchor::max()], cx); this.snapshot.borrow_mut().singleton = true; this } @@ -574,25 +574,25 @@ impl MultiBuffer { None } - pub fn push_excerpt( + pub fn push_excerpts( &mut self, buffer: ModelHandle, - range: Range, + ranges: impl IntoIterator>, cx: &mut ModelContext, - ) -> ExcerptId + ) -> Vec where O: text::ToOffset, { - self.insert_excerpt_after(&ExcerptId::max(), buffer, range, cx) + self.insert_excerpts_after(&ExcerptId::max(), buffer, ranges, cx) } - pub fn insert_excerpt_after( + pub fn insert_excerpts_after( &mut self, prev_excerpt_id: &ExcerptId, buffer: ModelHandle, - range: Range, + ranges: impl IntoIterator>, cx: &mut ModelContext, - ) -> ExcerptId + ) -> Vec where O: text::ToOffset, { @@ -601,8 +601,22 @@ impl MultiBuffer { let buffer_id = buffer.id(); let buffer_snapshot = buffer.read(cx).snapshot(); - let range = - buffer_snapshot.anchor_before(&range.start)..buffer_snapshot.anchor_after(&range.end); + + let mut buffers = self.buffers.borrow_mut(); + let buffer_state = buffers.entry(buffer_id).or_insert_with(|| BufferState { + last_version: buffer_snapshot.version().clone(), + last_parse_count: buffer_snapshot.parse_count(), + last_selections_update_count: buffer_snapshot.selections_update_count(), + last_diagnostics_update_count: buffer_snapshot.diagnostics_update_count(), + last_file_update_count: buffer_snapshot.file_update_count(), + excerpts: Default::default(), + _subscriptions: [ + cx.observe(&buffer, |_, _, cx| cx.notify()), + cx.subscribe(&buffer, Self::on_buffer_event), + ], + buffer, + }); + let mut snapshot = self.snapshot.borrow_mut(); let mut cursor = snapshot.excerpts.cursor::>(); let mut new_excerpts = cursor.slice(&Some(prev_excerpt_id), Bias::Right, &()); @@ -622,34 +636,27 @@ impl MultiBuffer { next_id = next_excerpt.id.clone(); } - let id = ExcerptId::between(&prev_id, &next_id); - - let mut buffers = self.buffers.borrow_mut(); - let buffer_state = buffers.entry(buffer_id).or_insert_with(|| BufferState { - last_version: buffer_snapshot.version().clone(), - last_parse_count: buffer_snapshot.parse_count(), - last_selections_update_count: buffer_snapshot.selections_update_count(), - last_diagnostics_update_count: buffer_snapshot.diagnostics_update_count(), - last_file_update_count: buffer_snapshot.file_update_count(), - excerpts: Default::default(), - _subscriptions: [ - cx.observe(&buffer, |_, _, cx| cx.notify()), - cx.subscribe(&buffer, Self::on_buffer_event), - ], - buffer, - }); - if let Err(ix) = buffer_state.excerpts.binary_search(&id) { - buffer_state.excerpts.insert(ix, id.clone()); + let mut ids = Vec::new(); + let mut ranges = ranges.into_iter().peekable(); + while let Some(range) = ranges.next() { + let id = ExcerptId::between(&prev_id, &next_id); + if let Err(ix) = buffer_state.excerpts.binary_search(&id) { + buffer_state.excerpts.insert(ix, id.clone()); + } + let range = buffer_snapshot.anchor_before(&range.start) + ..buffer_snapshot.anchor_after(&range.end); + let excerpt = Excerpt::new( + id.clone(), + buffer_id, + buffer_snapshot.clone(), + range, + ranges.peek().is_some() || cursor.item().is_some(), + ); + new_excerpts.push(excerpt, &()); + prev_id = id.clone(); + ids.push(id); } - let excerpt = Excerpt::new( - id.clone(), - buffer_id, - buffer_snapshot, - range, - cursor.item().is_some(), - ); - new_excerpts.push(excerpt, &()); let edit_end = new_excerpts.summary().text.bytes; let suffix = cursor.suffix(&()); @@ -667,7 +674,7 @@ impl MultiBuffer { }]); cx.notify(); - id + ids } pub fn excerpt_ids_for_buffer(&self, buffer: &ModelHandle) -> Vec { @@ -1072,7 +1079,7 @@ impl MultiBuffer { &buffer.text()[start_ix..end_ix] ); - let excerpt_id = self.push_excerpt(buffer_handle.clone(), start_ix..end_ix, cx); + let excerpt_id = self.push_excerpts(buffer_handle.clone(), [start_ix..end_ix], cx); log::info!("Inserted with id: {:?}", excerpt_id); } else { let remove_count = rng.gen_range(1..=excerpt_ids.len()); @@ -2667,7 +2674,7 @@ mod tests { let subscription = multibuffer.update(cx, |multibuffer, cx| { let subscription = multibuffer.subscribe(); - multibuffer.push_excerpt(buffer_1.clone(), Point::new(1, 2)..Point::new(2, 5), cx); + multibuffer.push_excerpts(buffer_1.clone(), [Point::new(1, 2)..Point::new(2, 5)], cx); assert_eq!( subscription.consume().into_inner(), [Edit { @@ -2676,8 +2683,8 @@ mod tests { }] ); - multibuffer.push_excerpt(buffer_1.clone(), Point::new(3, 3)..Point::new(4, 4), cx); - multibuffer.push_excerpt(buffer_2.clone(), Point::new(3, 1)..Point::new(3, 3), cx); + multibuffer.push_excerpts(buffer_1.clone(), [Point::new(3, 3)..Point::new(4, 4)], cx); + multibuffer.push_excerpts(buffer_2.clone(), [Point::new(3, 1)..Point::new(3, 3)], cx); assert_eq!( subscription.consume().into_inner(), [Edit { @@ -2879,8 +2886,8 @@ mod tests { let buffer_2 = cx.add_model(|cx| Buffer::new(0, "efghi", cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpt(buffer_1.clone(), 0..4, cx); - multibuffer.push_excerpt(buffer_2.clone(), 0..5, cx); + multibuffer.push_excerpts(buffer_1.clone(), [0..4], cx); + multibuffer.push_excerpts(buffer_2.clone(), [0..5], cx); multibuffer }); let old_snapshot = multibuffer.read(cx).snapshot(cx); @@ -2929,20 +2936,22 @@ mod tests { // Add an excerpt from buffer 1 that spans this new insertion. buffer_1.update(cx, |buffer, cx| buffer.edit([4..4], "123", cx)); let excerpt_id_1 = multibuffer.update(cx, |multibuffer, cx| { - multibuffer.push_excerpt(buffer_1.clone(), 0..7, cx) + multibuffer + .push_excerpts(buffer_1.clone(), [0..7], cx) + .pop() + .unwrap() }); let snapshot_1 = multibuffer.read(cx).snapshot(cx); assert_eq!(snapshot_1.text(), "abcd123"); // Replace the buffer 1 excerpt with new excerpts from buffer 2. - let (excerpt_id_2, excerpt_id_3, _) = multibuffer.update(cx, |multibuffer, cx| { + let (excerpt_id_2, excerpt_id_3) = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([&excerpt_id_1], cx); - ( - multibuffer.push_excerpt(buffer_2.clone(), 0..4, cx), - multibuffer.push_excerpt(buffer_2.clone(), 6..10, cx), - multibuffer.push_excerpt(buffer_2.clone(), 12..16, cx), - ) + let mut ids = multibuffer + .push_excerpts(buffer_2.clone(), [0..4, 6..10, 12..16], cx) + .into_iter(); + (ids.next().unwrap(), ids.next().unwrap()) }); let snapshot_2 = multibuffer.read(cx).snapshot(cx); assert_eq!(snapshot_2.text(), "ABCD\nGHIJ\nMNOP"); @@ -2979,7 +2988,10 @@ mod tests { // that intersects the old excerpt. let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([&excerpt_id_3], cx); - multibuffer.insert_excerpt_after(&excerpt_id_3, buffer_2.clone(), 5..8, cx) + multibuffer + .insert_excerpts_after(&excerpt_id_3, buffer_2.clone(), [5..8], cx) + .pop() + .unwrap() }); let snapshot_3 = multibuffer.read(cx).snapshot(cx); @@ -3119,12 +3131,15 @@ mod tests { ); let excerpt_id = multibuffer.update(cx, |multibuffer, cx| { - multibuffer.insert_excerpt_after( - &prev_excerpt_id, - buffer_handle.clone(), - start_ix..end_ix, - cx, - ) + multibuffer + .insert_excerpts_after( + &prev_excerpt_id, + buffer_handle.clone(), + [start_ix..end_ix], + cx, + ) + .pop() + .unwrap() }); excerpt_ids.insert(excerpt_ix, excerpt_id); @@ -3428,8 +3443,8 @@ mod tests { let multibuffer = cx.add_model(|_| MultiBuffer::new(0)); let group_interval = multibuffer.read(cx).history.group_interval; multibuffer.update(cx, |multibuffer, cx| { - multibuffer.push_excerpt(buffer_1.clone(), 0..buffer_1.read(cx).len(), cx); - multibuffer.push_excerpt(buffer_2.clone(), 0..buffer_2.read(cx).len(), cx); + multibuffer.push_excerpts(buffer_1.clone(), [0..buffer_1.read(cx).len()], cx); + multibuffer.push_excerpts(buffer_2.clone(), [0..buffer_2.read(cx).len()], cx); }); let mut now = Instant::now();