@@ -544,17 +544,28 @@ impl DisplayMap {
let all_blocks: Vec<_> = self.block_map.blocks_raw().map(Clone::clone).collect();
companion_display_map.update(cx, |companion_display_map, cx| {
+ // Sync folded buffers from RHS to LHS. Also clean up stale
+ // entries: the block map doesn't remove buffers from
+ // `folded_buffers` when they leave the multibuffer, so we
+ // unfold any RHS buffers whose companion mapping is missing.
+ let mut buffers_to_unfold = Vec::new();
for my_buffer in self.folded_buffers() {
- let their_buffer = companion
- .read(cx)
- .rhs_buffer_to_lhs_buffer
- .get(my_buffer)
- .unwrap();
+ let their_buffer = companion.read(cx).rhs_buffer_to_lhs_buffer.get(my_buffer);
+
+ let Some(their_buffer) = their_buffer else {
+ buffers_to_unfold.push(*my_buffer);
+ continue;
+ };
+
companion_display_map
.block_map
.folded_buffers
.insert(*their_buffer);
}
+ for buffer_id in buffers_to_unfold {
+ self.block_map.folded_buffers.remove(&buffer_id);
+ }
+
for block in all_blocks {
let Some(their_block) = block_map::balancing_block(
&block.properties(),
@@ -5755,4 +5755,106 @@ mod tests {
&mut cx,
);
}
+
+ #[gpui::test]
+ async fn test_split_after_removing_folded_buffer(cx: &mut gpui::TestAppContext) {
+ use rope::Point;
+ use unindent::Unindent as _;
+
+ let (editor, mut cx) = init_test(cx, SoftWrap::None, DiffViewStyle::Unified).await;
+
+ let base_text_a = "
+ aaa
+ bbb
+ ccc
+ "
+ .unindent();
+ let current_text_a = "
+ aaa
+ bbb modified
+ ccc
+ "
+ .unindent();
+
+ let base_text_b = "
+ xxx
+ yyy
+ zzz
+ "
+ .unindent();
+ let current_text_b = "
+ xxx
+ yyy modified
+ zzz
+ "
+ .unindent();
+
+ let (buffer_a, diff_a) = buffer_with_diff(&base_text_a, ¤t_text_a, &mut cx);
+ let (buffer_b, diff_b) = buffer_with_diff(&base_text_b, ¤t_text_b, &mut cx);
+
+ let path_a = cx.read(|cx| PathKey::for_buffer(&buffer_a, cx));
+ let path_b = cx.read(|cx| PathKey::for_buffer(&buffer_b, cx));
+
+ editor.update(cx, |editor, cx| {
+ editor.set_excerpts_for_path(
+ path_a.clone(),
+ buffer_a.clone(),
+ vec![Point::new(0, 0)..buffer_a.read(cx).max_point()],
+ 0,
+ diff_a.clone(),
+ cx,
+ );
+ editor.set_excerpts_for_path(
+ path_b.clone(),
+ buffer_b.clone(),
+ vec![Point::new(0, 0)..buffer_b.read(cx).max_point()],
+ 0,
+ diff_b.clone(),
+ cx,
+ );
+ });
+
+ cx.run_until_parked();
+
+ let buffer_a_id = buffer_a.read_with(cx, |buffer, _| buffer.remote_id());
+ editor.update(cx, |editor, cx| {
+ editor.rhs_editor().update(cx, |right_editor, cx| {
+ right_editor.fold_buffer(buffer_a_id, cx)
+ });
+ });
+
+ cx.run_until_parked();
+
+ editor.update(cx, |editor, cx| {
+ editor.remove_excerpts_for_path(path_a.clone(), cx);
+ });
+ cx.run_until_parked();
+
+ editor.update_in(cx, |editor, window, cx| editor.split(window, cx));
+ cx.run_until_parked();
+
+ editor.update(cx, |editor, cx| {
+ editor.set_excerpts_for_path(
+ path_a.clone(),
+ buffer_a.clone(),
+ vec![Point::new(0, 0)..buffer_a.read(cx).max_point()],
+ 0,
+ diff_a.clone(),
+ cx,
+ );
+ assert!(
+ !editor
+ .lhs_editor()
+ .unwrap()
+ .read(cx)
+ .is_buffer_folded(buffer_a_id, cx)
+ );
+ assert!(
+ !editor
+ .rhs_editor()
+ .read(cx)
+ .is_buffer_folded(buffer_a_id, cx)
+ );
+ });
+ }
}