mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-31 06:50:10 +00:00
Implement MultiBuffer::remove_excerpts
We'll need this for updating project diagnostics
This commit is contained in:
parent
a93f5e5fb4
commit
a888620e5f
1 changed files with 96 additions and 8 deletions
|
@ -641,6 +641,57 @@ impl MultiBuffer {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn excerpt_ids_for_buffer(&self, buffer: &ModelHandle<Buffer>) -> Vec<ExcerptId> {
|
||||||
|
self.buffers
|
||||||
|
.borrow()
|
||||||
|
.get(&buffer.id())
|
||||||
|
.map_or(Vec::new(), |state| state.excerpts.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_excerpts<'a>(
|
||||||
|
&mut self,
|
||||||
|
excerpt_ids: impl IntoIterator<Item = &'a ExcerptId>,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) {
|
||||||
|
let mut buffers = self.buffers.borrow_mut();
|
||||||
|
let mut snapshot = self.snapshot.borrow_mut();
|
||||||
|
let mut new_excerpts = SumTree::new();
|
||||||
|
let mut cursor = snapshot.excerpts.cursor::<(Option<&ExcerptId>, usize)>();
|
||||||
|
let mut edits = Vec::new();
|
||||||
|
for excerpt_id in excerpt_ids {
|
||||||
|
new_excerpts.push_tree(cursor.slice(&Some(excerpt_id), Bias::Left, &()), &());
|
||||||
|
if let Some(excerpt) = cursor.item() {
|
||||||
|
if excerpt.id == *excerpt_id {
|
||||||
|
let mut old_start = cursor.start().1;
|
||||||
|
let old_end = cursor.end(&()).1;
|
||||||
|
cursor.next(&());
|
||||||
|
|
||||||
|
if let Some(buffer_state) = buffers.get_mut(&excerpt.buffer_id) {
|
||||||
|
buffer_state.excerpts.retain(|id| id != excerpt_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When removing the last excerpt, remove the trailing newline from
|
||||||
|
// the previous excerpt.
|
||||||
|
if cursor.item().is_none() && old_start > 0 {
|
||||||
|
old_start -= 1;
|
||||||
|
new_excerpts.update_last(|e| e.has_trailing_newline = false, &());
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_start = new_excerpts.summary().text.bytes;
|
||||||
|
edits.push(Edit {
|
||||||
|
old: old_start..old_end,
|
||||||
|
new: new_start..new_start,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_excerpts.push_tree(cursor.suffix(&()), &());
|
||||||
|
drop(cursor);
|
||||||
|
snapshot.excerpts = new_excerpts;
|
||||||
|
self.subscriptions.publish_mut(edits);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
fn on_buffer_event(
|
fn on_buffer_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ModelHandle<Buffer>,
|
_: ModelHandle<Buffer>,
|
||||||
|
@ -2063,8 +2114,9 @@ mod tests {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let snapshot = multibuffer.read(cx).snapshot(cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.read(cx).snapshot(cx).text(),
|
snapshot.text(),
|
||||||
concat!(
|
concat!(
|
||||||
"bbbb\n", // Preserve newlines
|
"bbbb\n", // Preserve newlines
|
||||||
"c\n", //
|
"c\n", //
|
||||||
|
@ -2083,27 +2135,44 @@ mod tests {
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
|
|
||||||
let multibuffer = multibuffer.read(cx).snapshot(cx);
|
let snapshot = multibuffer.read(cx).snapshot(cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.clip_point(Point::new(0, 5), Bias::Left),
|
snapshot.clip_point(Point::new(0, 5), Bias::Left),
|
||||||
Point::new(0, 4)
|
Point::new(0, 4)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.clip_point(Point::new(0, 5), Bias::Right),
|
snapshot.clip_point(Point::new(0, 5), Bias::Right),
|
||||||
Point::new(0, 4)
|
Point::new(0, 4)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.clip_point(Point::new(5, 1), Bias::Right),
|
snapshot.clip_point(Point::new(5, 1), Bias::Right),
|
||||||
Point::new(5, 1)
|
Point::new(5, 1)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.clip_point(Point::new(5, 2), Bias::Right),
|
snapshot.clip_point(Point::new(5, 2), Bias::Right),
|
||||||
Point::new(5, 2)
|
Point::new(5, 2)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
multibuffer.clip_point(Point::new(5, 3), Bias::Right),
|
snapshot.clip_point(Point::new(5, 3), Bias::Right),
|
||||||
Point::new(5, 2)
|
Point::new(5, 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let snapshot = multibuffer.update(cx, |multibuffer, cx| {
|
||||||
|
let buffer_2_excerpt_id = multibuffer.excerpt_ids_for_buffer(&buffer_2)[0].clone();
|
||||||
|
multibuffer.remove_excerpts(&[buffer_2_excerpt_id], cx);
|
||||||
|
multibuffer.snapshot(cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.text(),
|
||||||
|
concat!(
|
||||||
|
"bbbb\n", // Preserve newlines
|
||||||
|
"c\n", //
|
||||||
|
"cc\n", //
|
||||||
|
"ddd\n", //
|
||||||
|
"eeee", //
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -2201,7 +2270,7 @@ mod tests {
|
||||||
let mut buffers: Vec<ModelHandle<Buffer>> = Vec::new();
|
let mut buffers: Vec<ModelHandle<Buffer>> = Vec::new();
|
||||||
let list = cx.add_model(|_| MultiBuffer::new(0));
|
let list = cx.add_model(|_| MultiBuffer::new(0));
|
||||||
let mut excerpt_ids = Vec::new();
|
let mut excerpt_ids = Vec::new();
|
||||||
let mut expected_excerpts = Vec::new();
|
let mut expected_excerpts = Vec::<(ModelHandle<Buffer>, Range<text::Anchor>)>::new();
|
||||||
let mut old_versions = Vec::new();
|
let mut old_versions = Vec::new();
|
||||||
|
|
||||||
for _ in 0..operations {
|
for _ in 0..operations {
|
||||||
|
@ -2210,6 +2279,20 @@ mod tests {
|
||||||
let buffer = buffers.choose(&mut rng).unwrap();
|
let buffer = buffers.choose(&mut rng).unwrap();
|
||||||
buffer.update(cx, |buf, cx| buf.randomly_edit(&mut rng, 5, cx));
|
buffer.update(cx, |buf, cx| buf.randomly_edit(&mut rng, 5, cx));
|
||||||
}
|
}
|
||||||
|
20..=29 if !expected_excerpts.is_empty() => {
|
||||||
|
let ix = rng.gen_range(0..expected_excerpts.len());
|
||||||
|
let id = excerpt_ids.remove(ix);
|
||||||
|
let (buffer, range) = expected_excerpts.remove(ix);
|
||||||
|
let buffer = buffer.read(cx);
|
||||||
|
log::info!(
|
||||||
|
"Removing excerpt {}: {:?}",
|
||||||
|
ix,
|
||||||
|
buffer
|
||||||
|
.text_for_range(range.to_offset(&buffer))
|
||||||
|
.collect::<String>(),
|
||||||
|
);
|
||||||
|
list.update(cx, |list, cx| list.remove_excerpts(&[id], cx));
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) {
|
let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) {
|
||||||
let base_text = RandomCharIter::new(&mut rng).take(10).collect::<String>();
|
let base_text = RandomCharIter::new(&mut rng).take(10).collect::<String>();
|
||||||
|
@ -2275,6 +2358,11 @@ mod tests {
|
||||||
expected_text.pop();
|
expected_text.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always report one buffer row
|
||||||
|
if expected_buffer_rows.is_empty() {
|
||||||
|
expected_buffer_rows.push(Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(snapshot.text(), expected_text);
|
assert_eq!(snapshot.text(), expected_text);
|
||||||
log::info!("MultiBuffer text: {:?}", expected_text);
|
log::info!("MultiBuffer text: {:?}", expected_text);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue