Fix multibuffer anchors before the ends of excerpts

This commit is contained in:
Max Brunsfeld 2021-12-14 13:37:05 -08:00
parent 06e241117c
commit 60e2c6bc52

View file

@ -1151,6 +1151,9 @@ impl MultiBufferSnapshot {
let offset = position.to_offset(self);
let mut cursor = self.excerpts.cursor::<(usize, Option<&ExcerptId>)>();
cursor.seek(&offset, Bias::Right, &());
if cursor.item().is_none() && offset == cursor.start().0 && bias == Bias::Left {
cursor.prev(&());
}
if let Some(excerpt) = cursor.item() {
let start_after_header = cursor.start().0 + excerpt.header_height as usize;
let buffer_start = excerpt.range.start.to_offset(&excerpt.buffer);
@ -1662,7 +1665,6 @@ mod tests {
fn test_excerpt_buffer(cx: &mut MutableAppContext) {
let buffer_1 = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6, 'a'), cx));
let buffer_2 = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6, 'g'), cx));
let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
let subscription = multibuffer.update(cx, |multibuffer, cx| {
@ -1765,6 +1767,73 @@ mod tests {
);
}
#[gpui::test]
fn test_singleton_multibuffer_anchors(cx: &mut MutableAppContext) {
let buffer = cx.add_model(|cx| Buffer::new(0, "abcd", cx));
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
let old_snapshot = multibuffer.read(cx).snapshot(cx);
buffer.update(cx, |buffer, cx| {
buffer.edit([0..0], "X", cx);
buffer.edit([5..5], "Y", cx);
});
let new_snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(old_snapshot.text(), "abcd");
assert_eq!(new_snapshot.text(), "XabcdY");
assert_eq!(old_snapshot.anchor_before(0).to_offset(&new_snapshot), 0);
assert_eq!(old_snapshot.anchor_after(0).to_offset(&new_snapshot), 1);
assert_eq!(old_snapshot.anchor_before(4).to_offset(&new_snapshot), 5);
assert_eq!(old_snapshot.anchor_after(4).to_offset(&new_snapshot), 6);
}
#[gpui::test]
fn test_multibuffer_anchors(cx: &mut MutableAppContext) {
let buffer_1 = cx.add_model(|cx| Buffer::new(0, "abcd", cx));
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(
ExcerptProperties {
buffer: &buffer_1,
range: 0..4,
header_height: 1,
},
cx,
);
multibuffer.push_excerpt(
ExcerptProperties {
buffer: &buffer_2,
range: 0..5,
header_height: 1,
},
cx,
);
multibuffer
});
let old_snapshot = multibuffer.read(cx).snapshot(cx);
buffer_1.update(cx, |buffer, cx| {
buffer.edit([0..0], "W", cx);
buffer.edit([5..5], "X", cx);
});
buffer_2.update(cx, |buffer, cx| {
buffer.edit([0..0], "Y", cx);
buffer.edit([6..0], "Z", cx);
});
let new_snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(old_snapshot.text(), "\nabcd\n\nefghi\n");
assert_eq!(new_snapshot.text(), "\nWabcdX\n\nYefghiZ\n");
assert_eq!(old_snapshot.anchor_before(0).to_offset(&new_snapshot), 0);
assert_eq!(old_snapshot.anchor_after(0).to_offset(&new_snapshot), 1);
assert_eq!(old_snapshot.anchor_before(1).to_offset(&new_snapshot), 0);
assert_eq!(old_snapshot.anchor_after(1).to_offset(&new_snapshot), 1);
assert_eq!(old_snapshot.anchor_before(7).to_offset(&new_snapshot), 9);
assert_eq!(old_snapshot.anchor_after(7).to_offset(&new_snapshot), 10);
}
#[gpui::test(iterations = 100)]
fn test_random_excerpts(cx: &mut MutableAppContext, mut rng: StdRng) {
let operations = env::var("OPERATIONS")