Compare commits

...

1 Commits

Author SHA1 Message Date
Conrad Irwin
111583b863 WIP: enforce buffer ordering in multibuffer 2025-01-29 22:44:17 -07:00
7 changed files with 125 additions and 109 deletions

View File

@@ -466,8 +466,7 @@ impl ProjectDiagnosticsEditor {
} }
let excerpt_id = excerpts let excerpt_id = excerpts
.insert_excerpts_after( .push_excerpts(
prev_excerpt_id,
buffer.clone(), buffer.clone(),
[ExcerptRange { [ExcerptRange {
context: context_range.clone(), context: context_range.clone(),

View File

@@ -13338,11 +13338,7 @@ impl Editor {
refresh_linked_ranges(self, window, cx); refresh_linked_ranges(self, window, cx);
telemetry.log_edit_event("editor", is_via_ssh); telemetry.log_edit_event("editor", is_via_ssh);
} }
multi_buffer::Event::ExcerptsAdded { multi_buffer::Event::ExcerptsAdded { buffer, excerpts } => {
buffer,
predecessor,
excerpts,
} => {
self.tasks_update_task = Some(self.refresh_runnables(window, cx)); self.tasks_update_task = Some(self.refresh_runnables(window, cx));
let buffer_id = buffer.read(cx).remote_id(); let buffer_id = buffer.read(cx).remote_id();
if self.buffer.read(cx).change_set_for(buffer_id).is_none() { if self.buffer.read(cx).change_set_for(buffer_id).is_none() {
@@ -13357,7 +13353,6 @@ impl Editor {
} }
cx.emit(EditorEvent::ExcerptsAdded { cx.emit(EditorEvent::ExcerptsAdded {
buffer: buffer.clone(), buffer: buffer.clone(),
predecessor: *predecessor,
excerpts: excerpts.clone(), excerpts: excerpts.clone(),
}); });
self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx); self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx);
@@ -15251,7 +15246,6 @@ pub enum EditorEvent {
}, },
ExcerptsAdded { ExcerptsAdded {
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
predecessor: ExcerptId,
excerpts: Vec<(ExcerptId, ExcerptRange<language::Anchor>)>, excerpts: Vec<(ExcerptId, ExcerptRange<language::Anchor>)>,
}, },
ExcerptsRemoved { ExcerptsRemoved {

View File

@@ -10431,8 +10431,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) {
], ],
cx, cx,
); );
multibuffer.insert_excerpts_after( multibuffer.push_excerpts(
excerpt_ids[0],
buffer_2.clone(), buffer_2.clone(),
[ [
ExcerptRange { ExcerptRange {

View File

@@ -856,8 +856,7 @@ impl ProjectDiffEditor {
for (_, buffer, hunk_ranges) in excerpts_to_add { for (_, buffer, hunk_ranges) in excerpts_to_add {
let buffer_snapshot = buffer.read(cx).snapshot(); let buffer_snapshot = buffer.read(cx).snapshot();
let max_point = buffer_snapshot.max_point(); let max_point = buffer_snapshot.max_point();
let new_excerpts = multi_buffer.insert_excerpts_after( let new_excerpts = multi_buffer.push_excerpts(
after_excerpt_id,
buffer, buffer,
hunk_ranges.into_iter().map(|range| { hunk_ranges.into_iter().map(|range| {
let mut extended_point_range = range.to_point(&buffer_snapshot); let mut extended_point_range = range.to_point(&buffer_snapshot);

View File

@@ -255,16 +255,12 @@ impl FollowableItem for Editor {
match update { match update {
proto::update_view::Variant::Editor(update) => match event { proto::update_view::Variant::Editor(update) => match event {
EditorEvent::ExcerptsAdded { EditorEvent::ExcerptsAdded { buffer, excerpts } => {
buffer,
predecessor,
excerpts,
} => {
let buffer_id = buffer.read(cx).remote_id(); let buffer_id = buffer.read(cx).remote_id();
let mut excerpts = excerpts.iter(); let mut excerpts = excerpts.iter();
if let Some((id, range)) = excerpts.next() { if let Some((id, range)) = excerpts.next() {
update.inserted_excerpts.push(proto::ExcerptInsertion { update.inserted_excerpts.push(proto::ExcerptInsertion {
previous_excerpt_id: Some(predecessor.to_proto()), previous_excerpt_id: None,
excerpt: serialize_excerpt(buffer_id, id, range), excerpt: serialize_excerpt(buffer_id, id, range),
}); });
update.inserted_excerpts.extend(excerpts.map(|(id, range)| { update.inserted_excerpts.extend(excerpts.map(|(id, range)| {
@@ -394,8 +390,7 @@ async fn update_editor_from_message(
} }
}); });
multibuffer.insert_excerpts_with_ids_after( multibuffer.insert_excerpts_with_ids(
ExcerptId::from_proto(previous_excerpt_id),
buffer, buffer,
[excerpt] [excerpt]
.into_iter() .into_iter()

View File

@@ -5,6 +5,7 @@ mod position;
pub use anchor::{Anchor, AnchorRangeExt, Offset}; pub use anchor::{Anchor, AnchorRangeExt, Offset};
pub use position::{TypedOffset, TypedPoint, TypedRow}; pub use position::{TypedOffset, TypedPoint, TypedRow};
use std::path::Path;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clock::ReplicaId; use clock::ReplicaId;
@@ -79,7 +80,6 @@ pub struct MultiBuffer {
pub enum Event { pub enum Event {
ExcerptsAdded { ExcerptsAdded {
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
predecessor: ExcerptId,
excerpts: Vec<(ExcerptId, ExcerptRange<language::Anchor>)>, excerpts: Vec<(ExcerptId, ExcerptRange<language::Anchor>)>,
}, },
ExcerptsRemoved { ExcerptsRemoved {
@@ -195,11 +195,39 @@ pub trait ToPointUtf16: 'static + fmt::Debug {
fn to_point_utf16(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16; fn to_point_utf16(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16;
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
enum BufferLocation {
#[default]
Min,
Unsaved(BufferId),
Path(Arc<Path>),
Max,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
struct ExcerptLocator {
buffer_location: BufferLocation,
locator: Option<Locator>,
}
impl ExcerptLocator {
const MIN: ExcerptLocator = ExcerptLocator {
buffer_location: BufferLocation::Min,
locator: None,
};
const MAX: ExcerptLocator = ExcerptLocator {
buffer_location: BufferLocation::Max,
locator: None,
};
}
struct BufferState { struct BufferState {
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
last_version: clock::Global, last_version: clock::Global,
last_non_text_state_update_count: usize, last_non_text_state_update_count: usize,
excerpts: Vec<Locator>, buffer_location: BufferLocation,
excerpts: Vec<ExcerptLocator>,
start_anchors: Vec<text::Anchor>,
_subscriptions: [gpui::Subscription; 2], _subscriptions: [gpui::Subscription; 2],
} }
@@ -298,7 +326,7 @@ struct Excerpt {
/// The unique identifier for this excerpt /// The unique identifier for this excerpt
id: ExcerptId, id: ExcerptId,
/// The location of the excerpt in the [`MultiBuffer`] /// The location of the excerpt in the [`MultiBuffer`]
locator: Locator, locator: ExcerptLocator,
/// The buffer being excerpted /// The buffer being excerpted
buffer_id: BufferId, buffer_id: BufferId,
/// A snapshot of the buffer being excerpted /// A snapshot of the buffer being excerpted
@@ -329,7 +357,7 @@ pub struct MultiBufferExcerpt<'a> {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct ExcerptIdMapping { struct ExcerptIdMapping {
id: ExcerptId, id: ExcerptId,
locator: Locator, locator: ExcerptLocator,
} }
/// A range of text from a single [`Buffer`], to be shown as an [`Excerpt`]. /// A range of text from a single [`Buffer`], to be shown as an [`Excerpt`].
@@ -347,7 +375,7 @@ pub struct ExcerptRange<T> {
pub struct ExcerptSummary { pub struct ExcerptSummary {
excerpt_id: ExcerptId, excerpt_id: ExcerptId,
/// The location of the last [`Excerpt`] being summarized /// The location of the last [`Excerpt`] being summarized
excerpt_locator: Locator, excerpt_locator: ExcerptLocator,
widest_line_number: u32, widest_line_number: u32,
text: TextSummary, text: TextSummary,
} }
@@ -530,10 +558,12 @@ impl MultiBuffer {
buffers.insert( buffers.insert(
*buffer_id, *buffer_id,
BufferState { BufferState {
buffer_location: buffer_state.buffer_location.clone(),
buffer: buffer_state.buffer.clone(), buffer: buffer_state.buffer.clone(),
last_version: buffer_state.last_version.clone(), last_version: buffer_state.last_version.clone(),
last_non_text_state_update_count: buffer_state.last_non_text_state_update_count, last_non_text_state_update_count: buffer_state.last_non_text_state_update_count,
excerpts: buffer_state.excerpts.clone(), excerpts: buffer_state.excerpts.clone(),
start_anchors: buffer_state.start_anchors.clone(),
_subscriptions: [ _subscriptions: [
new_cx.observe(&buffer_state.buffer, |_, _, cx| cx.notify()), new_cx.observe(&buffer_state.buffer, |_, _, cx| cx.notify()),
new_cx.subscribe(&buffer_state.buffer, Self::on_buffer_event), new_cx.subscribe(&buffer_state.buffer, Self::on_buffer_event),
@@ -1172,7 +1202,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<&ExcerptLocator>>(&());
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);
@@ -1337,18 +1367,6 @@ impl MultiBuffer {
} }
} }
pub fn push_excerpts<O>(
&mut self,
buffer: Entity<Buffer>,
ranges: impl IntoIterator<Item = ExcerptRange<O>>,
cx: &mut Context<Self>,
) -> Vec<ExcerptId>
where
O: text::ToOffset,
{
self.insert_excerpts_after(ExcerptId::max(), buffer, ranges, cx)
}
pub fn push_excerpts_with_context_lines<O>( pub fn push_excerpts_with_context_lines<O>(
&mut self, &mut self,
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
@@ -1475,9 +1493,8 @@ impl MultiBuffer {
}) })
} }
pub fn insert_excerpts_after<O>( pub fn push_excerpts<O>(
&mut self, &mut self,
prev_excerpt_id: ExcerptId,
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
ranges: impl IntoIterator<Item = ExcerptRange<O>>, ranges: impl IntoIterator<Item = ExcerptRange<O>>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
@@ -1492,8 +1509,7 @@ impl MultiBuffer {
} else { } else {
1 1
}; };
self.insert_excerpts_with_ids_after( self.insert_excerpts_with_ids(
prev_excerpt_id,
buffer, buffer,
ranges.into_iter().map(|range| { ranges.into_iter().map(|range| {
let id = ExcerptId(post_inc(&mut next_excerpt_id)); let id = ExcerptId(post_inc(&mut next_excerpt_id));
@@ -1505,9 +1521,8 @@ impl MultiBuffer {
ids ids
} }
pub fn insert_excerpts_with_ids_after<O>( pub fn insert_excerpts_with_ids<O>(
&mut self, &mut self,
prev_excerpt_id: ExcerptId,
buffer: Entity<Buffer>, buffer: Entity<Buffer>,
ranges: impl IntoIterator<Item = (ExcerptId, ExcerptRange<O>)>, ranges: impl IntoIterator<Item = (ExcerptId, ExcerptRange<O>)>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
@@ -1529,7 +1544,12 @@ impl MultiBuffer {
let buffer_state = buffers.entry(buffer_id).or_insert_with(|| BufferState { let buffer_state = buffers.entry(buffer_id).or_insert_with(|| BufferState {
last_version: buffer_snapshot.version().clone(), last_version: buffer_snapshot.version().clone(),
last_non_text_state_update_count: buffer_snapshot.non_text_state_update_count(), last_non_text_state_update_count: buffer_snapshot.non_text_state_update_count(),
buffer_location: buffer_snapshot
.file()
.map(|f| BufferLocation::Path(Arc::from(f.full_path(cx))))
.unwrap_or(BufferLocation::Unsaved(buffer_id)),
excerpts: Default::default(), excerpts: Default::default(),
start_anchors: Default::default(),
_subscriptions: [ _subscriptions: [
cx.observe(&buffer, |_, _, cx| cx.notify()), cx.observe(&buffer, |_, _, cx| cx.notify()),
cx.subscribe(&buffer, Self::on_buffer_event), cx.subscribe(&buffer, Self::on_buffer_event),
@@ -1539,35 +1559,46 @@ impl MultiBuffer {
let mut snapshot = self.snapshot.borrow_mut(); let mut snapshot = self.snapshot.borrow_mut();
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<&ExcerptLocator>>(&());
let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right, &());
prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone();
let edit_start = ExcerptOffset::new(new_excerpts.summary().text.len); let mut edit_start = None;
new_excerpts.update_last(
|excerpt| {
excerpt.has_trailing_newline = true;
},
&(),
);
let next_locator = if let Some(excerpt) = cursor.item() { let mut new_excerpts = SumTree::default();
excerpt.locator.clone()
} else {
Locator::max()
};
let mut excerpts = Vec::new(); let mut excerpts = Vec::new();
while let Some((id, range)) = ranges.next() { while let Some((id, range)) = ranges.next() {
let locator = Locator::between(&prev_locator, &next_locator); let context_start = buffer_snapshot.anchor_before(&range.context.start);
if let Err(ix) = buffer_state.excerpts.binary_search(&locator) { let locator = if let Err(ix) = buffer_state
buffer_state.excerpts.insert(ix, locator.clone()); .start_anchors
} .binary_search_by(|anchor| anchor.cmp(&context_start, &buffer_snapshot))
{
let prev_locator = if ix > 0 {
buffer_state.excerpts[ix - 1].locator.as_ref().unwrap()
} else {
Locator::min_ref()
};
let next_locator = if ix < buffer_state.excerpts.len() {
buffer_state.excerpts[ix].locator.as_ref().unwrap()
} else {
Locator::max_ref()
};
let locator = Locator::between(prev_locator, next_locator);
// todo: we shouldn't need to create these, but the dimension is defined by reference...
let excerpt_locator = ExcerptLocator {
buffer_location: buffer_state.buffer_location.clone(),
locator: Some(locator),
};
buffer_state.excerpts.insert(ix, excerpt_locator.clone());
buffer_state.start_anchors.insert(ix, context_start);
excerpt_locator
} else {
panic!("excerpt already exists")
};
new_excerpts.append(cursor.slice(&locator, Bias::Right, &()), &());
let range = ExcerptRange { let range = ExcerptRange {
context: buffer_snapshot.anchor_before(&range.context.start) context: context_start..buffer_snapshot.anchor_after(&range.context.end),
..buffer_snapshot.anchor_after(&range.context.end),
primary: range.primary.map(|primary| { primary: range.primary.map(|primary| {
buffer_snapshot.anchor_before(&primary.start) buffer_snapshot.anchor_before(&primary.start)
..buffer_snapshot.anchor_after(&primary.end) ..buffer_snapshot.anchor_after(&primary.end)
@@ -1582,8 +1613,16 @@ impl MultiBuffer {
range, range,
ranges.peek().is_some() || cursor.item().is_some(), ranges.peek().is_some() || cursor.item().is_some(),
); );
if edit_start == None {
edit_start = Some(ExcerptOffset::new(new_excerpts.summary().text.len));
}
new_excerpts.update_last(
|excerpt| {
excerpt.has_trailing_newline = true;
},
&(),
);
new_excerpts.push(excerpt, &()); new_excerpts.push(excerpt, &());
prev_locator = locator.clone();
if let Some(last_mapping_entry) = new_excerpt_ids.last() { if let Some(last_mapping_entry) = new_excerpt_ids.last() {
assert!(id > last_mapping_entry.id, "excerpt ids must be increasing"); assert!(id > last_mapping_entry.id, "excerpt ids must be increasing");
@@ -1606,8 +1645,8 @@ impl MultiBuffer {
self.sync_diff_transforms( self.sync_diff_transforms(
snapshot, snapshot,
vec![Edit { vec![Edit {
old: edit_start..edit_start, old: edit_start.unwrap()..edit_start.unwrap(),
new: edit_start..edit_end, new: edit_start.unwrap()..edit_end,
}], }],
DiffChangeKind::BufferEdited, DiffChangeKind::BufferEdited,
); );
@@ -1615,11 +1654,7 @@ impl MultiBuffer {
singleton_buffer_edited: false, singleton_buffer_edited: false,
edited_buffer: None, edited_buffer: None,
}); });
cx.emit(Event::ExcerptsAdded { cx.emit(Event::ExcerptsAdded { buffer, excerpts });
buffer,
predecessor: prev_excerpt_id,
excerpts,
});
cx.notify(); cx.notify();
} }
@@ -1660,7 +1695,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<&ExcerptLocator>>(&());
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)
@@ -1683,7 +1718,7 @@ impl MultiBuffer {
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut excerpts = snapshot let mut excerpts = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptDimension<Point>)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptDimension<Point>)>(&());
let mut diff_transforms = snapshot let mut diff_transforms = snapshot
.diff_transforms .diff_transforms
.cursor::<(ExcerptDimension<Point>, OutputDimension<Point>)>(&()); .cursor::<(ExcerptDimension<Point>, OutputDimension<Point>)>(&());
@@ -1849,7 +1884,7 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
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();
@@ -2047,7 +2082,7 @@ impl MultiBuffer {
for locator in &buffer_state.excerpts { for locator in &buffer_state.excerpts {
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
cursor.seek_forward(&Some(locator), Bias::Left, &()); cursor.seek_forward(&Some(locator), Bias::Left, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
if excerpt.locator == *locator { if excerpt.locator == *locator {
@@ -2308,7 +2343,7 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
let mut edits = Vec::<Edit<ExcerptOffset>>::new(); let mut edits = Vec::<Edit<ExcerptOffset>>::new();
let prefix = cursor.slice(&Some(locator), Bias::Left, &()); let prefix = cursor.slice(&Some(locator), Bias::Left, &());
@@ -2380,7 +2415,7 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
let mut edits = Vec::<Edit<ExcerptOffset>>::new(); let mut edits = Vec::<Edit<ExcerptOffset>>::new();
for locator in &locators { for locator in &locators {
@@ -2515,7 +2550,7 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
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, &()), &());
@@ -4318,7 +4353,7 @@ impl MultiBufferSnapshot {
fn excerpt_offset_for_anchor(&self, anchor: &Anchor) -> ExcerptOffset { fn excerpt_offset_for_anchor(&self, anchor: &Anchor) -> ExcerptOffset {
let mut cursor = self let mut cursor = self
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptOffset)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptOffset)>(&());
let locator = self.excerpt_locator_for_id(anchor.excerpt_id); let locator = self.excerpt_locator_for_id(anchor.excerpt_id);
cursor.seek(&Some(locator), Bias::Left, &()); cursor.seek(&Some(locator), Bias::Left, &());
@@ -4467,7 +4502,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<&ExcerptLocator>>(&());
cursor.next(&()); cursor.next(&());
let mut result = Vec::new(); let mut result = Vec::new();
@@ -4665,7 +4700,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<&ExcerptLocator>>(&());
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 {
@@ -4719,7 +4754,7 @@ impl MultiBufferSnapshot {
let start_locator = self.excerpt_locator_for_id(id); let start_locator = self.excerpt_locator_for_id(id);
let mut excerpts = self let mut excerpts = self
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptDimension<usize>)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptDimension<usize>)>(&());
excerpts.seek(&Some(start_locator), Bias::Left, &()); excerpts.seek(&Some(start_locator), Bias::Left, &());
excerpts.prev(&()); excerpts.prev(&());
@@ -5510,11 +5545,11 @@ impl MultiBufferSnapshot {
)) ))
} }
fn excerpt_locator_for_id(&self, id: ExcerptId) -> &Locator { fn excerpt_locator_for_id(&self, id: ExcerptId) -> &ExcerptLocator {
if id == ExcerptId::min() { if id == ExcerptId::min() {
Locator::min_ref() &ExcerptLocator::MIN
} else if id == ExcerptId::max() { } else if id == ExcerptId::max() {
Locator::max_ref() &ExcerptLocator::MAX
} 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, &());
@@ -5531,7 +5566,7 @@ impl MultiBufferSnapshot {
fn excerpt_locators_for_ids( fn excerpt_locators_for_ids(
&self, &self,
ids: impl IntoIterator<Item = ExcerptId>, ids: impl IntoIterator<Item = ExcerptId>,
) -> SmallVec<[Locator; 1]> { ) -> SmallVec<[ExcerptLocator; 1]> {
let mut sorted_ids = ids.into_iter().collect::<SmallVec<[_; 1]>>(); let mut sorted_ids = ids.into_iter().collect::<SmallVec<[_; 1]>>();
sorted_ids.sort_unstable(); sorted_ids.sort_unstable();
let mut locators = SmallVec::new(); let mut locators = SmallVec::new();
@@ -5575,7 +5610,7 @@ impl MultiBufferSnapshot {
pub fn range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<Point>> { pub fn range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<Point>> {
let mut cursor = self let mut cursor = self
.excerpts .excerpts
.cursor::<(Option<&Locator>, ExcerptDimension<Point>)>(&()); .cursor::<(Option<&ExcerptLocator>, ExcerptDimension<Point>)>(&());
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();
@@ -5596,7 +5631,7 @@ impl MultiBufferSnapshot {
} }
pub fn buffer_range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<text::Anchor>> { pub fn buffer_range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<text::Anchor>> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = self.excerpts.cursor::<Option<&ExcerptLocator>>(&());
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, &()) {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
@@ -5607,7 +5642,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<&ExcerptLocator>>(&());
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() {
@@ -5727,7 +5762,7 @@ impl MultiBufferSnapshot {
for (ix, excerpt) in excerpts.iter().enumerate() { for (ix, excerpt) in excerpts.iter().enumerate() {
if ix == 0 { if ix == 0 {
if excerpt.locator <= Locator::min() { if excerpt.locator <= ExcerptLocator::MIN {
panic!("invalid first excerpt locator {:?}", excerpt.locator); panic!("invalid first excerpt locator {:?}", excerpt.locator);
} }
} else if excerpt.locator <= excerpts[ix - 1].locator { } else if excerpt.locator <= excerpts[ix - 1].locator {
@@ -6202,7 +6237,7 @@ impl History {
impl Excerpt { impl Excerpt {
fn new( fn new(
id: ExcerptId, id: ExcerptId,
locator: Locator, locator: ExcerptLocator,
buffer_id: BufferId, buffer_id: BufferId,
buffer: BufferSnapshot, buffer: BufferSnapshot,
range: ExcerptRange<text::Anchor>, range: ExcerptRange<text::Anchor>,
@@ -6585,13 +6620,13 @@ impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for ExcerptOff
} }
} }
impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, Option<&'a Locator>> for Locator { impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, Option<&'a ExcerptLocator>> for ExcerptLocator {
fn cmp(&self, cursor_location: &Option<&'a Locator>, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &Option<&'a ExcerptLocator>, _: &()) -> cmp::Ordering {
Ord::cmp(&Some(self), cursor_location) Ord::cmp(&Some(self), cursor_location)
} }
} }
impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for Locator { impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for ExcerptLocator {
fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering {
Ord::cmp(self, &cursor_location.excerpt_locator) Ord::cmp(self, &cursor_location.excerpt_locator)
} }
@@ -6619,7 +6654,7 @@ impl<'a, D: TextDimension + Default> sum_tree::Dimension<'a, ExcerptSummary>
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a Locator> { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a ExcerptLocator> {
fn zero(_cx: &()) -> Self { fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }

View File

@@ -669,10 +669,8 @@ fn test_excerpt_events(cx: &mut App) {
&leader_multibuffer, &leader_multibuffer,
move |follower, _, event, cx| match event.clone() { move |follower, _, event, cx| match event.clone() {
Event::ExcerptsAdded { Event::ExcerptsAdded {
buffer, buffer, excerpts, ..
predecessor, } => follower.insert_excerpts_with_ids(buffer, excerpts, cx),
excerpts,
} => follower.insert_excerpts_with_ids_after(predecessor, buffer, excerpts, cx),
Event::ExcerptsRemoved { ids } => follower.remove_excerpts(ids, cx), Event::ExcerptsRemoved { ids } => follower.remove_excerpts(ids, cx),
Event::Edited { .. } => { Event::Edited { .. } => {
*follower_edit_event_count.write() += 1; *follower_edit_event_count.write() += 1;
@@ -698,8 +696,7 @@ fn test_excerpt_events(cx: &mut App) {
], ],
cx, cx,
); );
leader.insert_excerpts_after( leader.push_excerpts(
leader.excerpt_ids()[0],
buffer_2.clone(), buffer_2.clone(),
[ [
ExcerptRange { ExcerptRange {
@@ -1155,8 +1152,7 @@ fn test_resolving_anchors_after_replacing_their_excerpts(cx: &mut App) {
let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| { let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| {
multibuffer.remove_excerpts([excerpt_id_3], cx); multibuffer.remove_excerpts([excerpt_id_3], cx);
multibuffer multibuffer
.insert_excerpts_after( .push_excerpts(
excerpt_id_2,
buffer_2.clone(), buffer_2.clone(),
[ExcerptRange { [ExcerptRange {
context: 5..8, context: 5..8,
@@ -2249,8 +2245,7 @@ async fn test_random_multibuffer(cx: &mut TestAppContext, mut rng: StdRng) {
let excerpt_id = multibuffer.update(cx, |multibuffer, cx| { let excerpt_id = multibuffer.update(cx, |multibuffer, cx| {
multibuffer multibuffer
.insert_excerpts_after( .push_excerpts(
prev_excerpt_id,
buffer_handle.clone(), buffer_handle.clone(),
[ExcerptRange { [ExcerptRange {
context: range, context: range,