diff --git a/crates/multi_buffer/src/anchor.rs b/crates/multi_buffer/src/anchor.rs index 6a8e3b86af0075..849e9932c2a16e 100644 --- a/crates/multi_buffer/src/anchor.rs +++ b/crates/multi_buffer/src/anchor.rs @@ -232,6 +232,9 @@ impl ExcerptAnchor { let Some(excerpt) = cursor.item() else { return false; }; + if excerpt.buffer_id != buffer_snapshot.remote_id() { + return false; + } let is_valid = self.text_anchor == excerpt.range.context.start || self.text_anchor == excerpt.range.context.end || self.text_anchor.is_valid(&buffer_snapshot); diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index a7f4b18cc42395..dbe2ce4133d927 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -6206,3 +6206,54 @@ fn test_resolving_max_anchor_for_buffer(cx: &mut TestAppContext) { assert_eq!(point, Point::new(10, 0)); }) } + +#[gpui::test] +fn test_is_valid_anchor_past_last_excerpt_for_buffer(cx: &mut TestAppContext) { + let buffer_a = cx.new(|cx| Buffer::local("aaa\nbbb\nccc\n", cx)); + buffer_a.update(cx, |buffer, cx| { + let len = buffer.len(); + buffer.edit([(len..len, "ddd\neee\n")], None, cx); + }); + let buffer_b = cx.new(|cx| Buffer::local("xxx\n", cx)); + for line in ["yyy\n", "zzz\n", "www\n", "vvv\n"] { + buffer_b.update(cx, |buffer, cx| { + let len = buffer.len(); + buffer.edit([(len..len, line)], None, cx); + }); + } + + let path_a = PathKey::with_sort_prefix(0, rel_path("aaa.rs").into_arc()); + let path_b = PathKey::with_sort_prefix(1, rel_path("bbb.rs").into_arc()); + + let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite)); + + multibuffer.update(cx, |multibuffer, cx| { + multibuffer.set_excerpts_for_path( + path_a.clone(), + buffer_a.clone(), + vec![Point::new(1, 0)..Point::new(2, 3)], + 0, + cx, + ); + multibuffer.set_excerpts_for_path( + path_b.clone(), + buffer_b.clone(), + vec![Point::new(1, 0)..Point::new(3, 3)], + 0, + cx, + ); + }); + + multibuffer.read_with(cx, |multibuffer, cx| { + let snapshot = multibuffer.snapshot(cx); + + let buffer_a_snapshot = buffer_a.read(cx).snapshot(); + let anchor_past_excerpt = buffer_a_snapshot.anchor_after(Point::new(4, 0)); + let mb_anchor = snapshot.anchor_in_buffer(anchor_past_excerpt).unwrap(); + + assert!( + !mb_anchor.is_valid(&snapshot), + "anchor past the last excerpt for its buffer should not be valid" + ); + }); +}