Implement MultiBuffer::insert_excerpt_after

This commit is contained in:
Max Brunsfeld 2021-12-22 17:40:00 -08:00
parent a86ba57983
commit 435d405d10

View file

@ -589,6 +589,18 @@ impl MultiBuffer {
props: ExcerptProperties<O>,
cx: &mut ModelContext<Self>,
) -> ExcerptId
where
O: text::ToOffset,
{
self.insert_excerpt_after(&ExcerptId::max(), props, cx)
}
pub fn insert_excerpt_after<O>(
&mut self,
prev_excerpt_id: &ExcerptId,
props: ExcerptProperties<O>,
cx: &mut ModelContext<Self>,
) -> ExcerptId
where
O: text::ToOffset,
{
@ -599,19 +611,28 @@ impl MultiBuffer {
let range = buffer_snapshot.anchor_before(&props.range.start)
..buffer_snapshot.anchor_after(&props.range.end);
let mut snapshot = self.snapshot.borrow_mut();
let mut prev_id = None;
let edit_start = snapshot.excerpts.summary().text.bytes;
snapshot.excerpts.update_last(
let mut cursor = snapshot.excerpts.cursor::<Option<&ExcerptId>>();
let mut new_excerpts = cursor.slice(&Some(prev_excerpt_id), Bias::Right, &());
let mut prev_id = ExcerptId::min();
let edit_start = new_excerpts.summary().text.bytes;
new_excerpts.update_last(
|excerpt| {
excerpt.has_trailing_newline = true;
prev_id = Some(excerpt.id.clone());
prev_id = excerpt.id.clone();
},
&(),
);
let id = ExcerptId::between(&prev_id.unwrap_or(ExcerptId::min()), &ExcerptId::max());
self.buffers
.borrow_mut()
let mut next_id = ExcerptId::max();
if let Some(next_excerpt) = cursor.item() {
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(props.buffer.id())
.or_insert_with(|| BufferState {
last_version: buffer_snapshot.version().clone(),
@ -623,14 +644,28 @@ impl MultiBuffer {
cx.subscribe(&props.buffer, Self::on_buffer_event),
],
buffer: props.buffer.clone(),
})
.excerpts
.push(id.clone());
let excerpt = Excerpt::new(id.clone(), props.buffer.id(), buffer_snapshot, range, false);
snapshot.excerpts.push(excerpt, &());
});
if let Err(ix) = buffer_state.excerpts.binary_search(&id) {
buffer_state.excerpts.insert(ix, id.clone());
}
let excerpt = Excerpt::new(
id.clone(),
props.buffer.id(),
buffer_snapshot,
range,
cursor.item().is_some(),
);
new_excerpts.push(excerpt, &());
let edit_end = new_excerpts.summary().text.bytes;
new_excerpts.push_tree(cursor.suffix(&()), &());
drop(cursor);
snapshot.excerpts = new_excerpts;
self.subscriptions.publish_mut([Edit {
old: edit_start..edit_start,
new: edit_start..snapshot.excerpts.summary().text.bytes,
new: edit_start..edit_end,
}]);
cx.notify();
@ -2302,8 +2337,17 @@ mod tests {
let end_ix = buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right);
let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
let anchor_range = buffer.anchor_before(start_ix)..buffer.anchor_after(end_ix);
let prev_excerpt_ix = rng.gen_range(0..=expected_excerpts.len());
let prev_excerpt_id = excerpt_ids
.get(prev_excerpt_ix)
.cloned()
.unwrap_or(ExcerptId::max());
let excerpt_ix = (prev_excerpt_ix + 1).min(expected_excerpts.len());
log::info!(
"Pushing excerpt for buffer {}: {:?}[{:?}] = {:?}",
"Inserting excerpt at {} of {} for buffer {}: {:?}[{:?}] = {:?}",
excerpt_ix,
expected_excerpts.len(),
buffer_handle.id(),
buffer.text(),
start_ix..end_ix,
@ -2311,7 +2355,8 @@ mod tests {
);
let excerpt_id = list.update(cx, |list, cx| {
list.push_excerpt(
list.insert_excerpt_after(
&prev_excerpt_id,
ExcerptProperties {
buffer: &buffer_handle,
range: start_ix..end_ix,
@ -2319,8 +2364,9 @@ mod tests {
cx,
)
});
excerpt_ids.push(excerpt_id);
expected_excerpts.push((buffer_handle.clone(), anchor_range));
excerpt_ids.insert(excerpt_ix, excerpt_id);
expected_excerpts.insert(excerpt_ix, (buffer_handle.clone(), anchor_range));
}
}