Unfold buffers in multibuffers when editing them (#25677)

Release Notes:

- Multibuffers: Unfold excerpts when editing their contents.

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
João Marcos 2025-02-26 17:39:33 -03:00 committed by GitHub
parent b5a1ae6526
commit be1ac78e11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 98 additions and 43 deletions

View file

@ -1239,26 +1239,45 @@ impl<'a> BlockMapWriter<'a> {
self.remove(blocks_to_remove);
}
pub fn fold_buffer(&mut self, buffer_id: BufferId, multi_buffer: &MultiBuffer, cx: &App) {
self.0.folded_buffers.insert(buffer_id);
self.recompute_blocks_for_buffer(buffer_id, multi_buffer, cx);
}
pub fn unfold_buffer(&mut self, buffer_id: BufferId, multi_buffer: &MultiBuffer, cx: &App) {
self.0.folded_buffers.remove(&buffer_id);
self.recompute_blocks_for_buffer(buffer_id, multi_buffer, cx);
}
fn recompute_blocks_for_buffer(
pub fn fold_buffers(
&mut self,
buffer_id: BufferId,
buffer_ids: impl IntoIterator<Item = BufferId>,
multi_buffer: &MultiBuffer,
cx: &App,
) {
let wrap_snapshot = self.0.wrap_snapshot.borrow().clone();
self.fold_or_unfold_buffers(true, buffer_ids, multi_buffer, cx);
}
pub fn unfold_buffers(
&mut self,
buffer_ids: impl IntoIterator<Item = BufferId>,
multi_buffer: &MultiBuffer,
cx: &App,
) {
self.fold_or_unfold_buffers(false, buffer_ids, multi_buffer, cx);
}
fn fold_or_unfold_buffers(
&mut self,
fold: bool,
buffer_ids: impl IntoIterator<Item = BufferId>,
multi_buffer: &MultiBuffer,
cx: &App,
) {
let mut ranges = Vec::new();
for buffer_id in buffer_ids {
if fold {
self.0.folded_buffers.insert(buffer_id);
} else {
self.0.folded_buffers.remove(&buffer_id);
}
ranges.extend(multi_buffer.excerpt_ranges_for_buffer(buffer_id, cx));
}
ranges.sort_unstable_by_key(|range| range.start);
let mut edits = Patch::default();
for range in multi_buffer.excerpt_ranges_for_buffer(buffer_id, cx) {
let wrap_snapshot = self.0.wrap_snapshot.borrow().clone();
for range in ranges {
let last_edit_row = cmp::min(
wrap_snapshot.make_wrap_point(range.end, Bias::Right).row() + 1,
wrap_snapshot.max_point().row(),
@ -2730,7 +2749,7 @@ mod tests {
let mut writer = block_map.write(wrap_snapshot.clone(), Patch::default());
buffer.read_with(cx, |buffer, cx| {
writer.fold_buffer(buffer_id_1, buffer, cx);
writer.fold_buffers([buffer_id_1], buffer, cx);
});
let excerpt_blocks_1 = writer.insert(vec![BlockProperties {
style: BlockStyle::Fixed,
@ -2805,7 +2824,7 @@ mod tests {
let mut writer = block_map.write(wrap_snapshot.clone(), Patch::default());
buffer.read_with(cx, |buffer, cx| {
writer.fold_buffer(buffer_id_2, buffer, cx);
writer.fold_buffers([buffer_id_2], buffer, cx);
});
let blocks_snapshot = block_map.read(wrap_snapshot.clone(), Patch::default());
let blocks = blocks_snapshot
@ -2861,7 +2880,7 @@ mod tests {
let mut writer = block_map.write(wrap_snapshot.clone(), Patch::default());
buffer.read_with(cx, |buffer, cx| {
writer.unfold_buffer(buffer_id_1, buffer, cx);
writer.unfold_buffers([buffer_id_1], buffer, cx);
});
let blocks_snapshot = block_map.read(wrap_snapshot.clone(), Patch::default());
let blocks = blocks_snapshot
@ -2922,7 +2941,7 @@ mod tests {
let mut writer = block_map.write(wrap_snapshot.clone(), Patch::default());
buffer.read_with(cx, |buffer, cx| {
writer.fold_buffer(buffer_id_3, buffer, cx);
writer.fold_buffers([buffer_id_3], buffer, cx);
});
let blocks_snapshot = block_map.read(wrap_snapshot.clone(), Patch::default());
let blocks = blocks_snapshot
@ -3000,7 +3019,7 @@ mod tests {
let mut writer = block_map.write(wrap_snapshot.clone(), Patch::default());
buffer.read_with(cx, |buffer, cx| {
writer.fold_buffer(buffer_id, buffer, cx);
writer.fold_buffers([buffer_id], buffer, cx);
});
let blocks_snapshot = block_map.read(wrap_snapshot.clone(), Patch::default());
let blocks = blocks_snapshot
@ -3250,7 +3269,7 @@ mod tests {
);
folded_count += 1;
unfolded_count -= 1;
block_map.fold_buffer(buffer_to_fold, buffer, cx);
block_map.fold_buffers([buffer_to_fold], buffer, cx);
}
if unfold {
let buffer_to_unfold =
@ -3258,7 +3277,7 @@ mod tests {
log::info!("Unfolding {buffer_to_unfold:?}");
unfolded_count += 1;
folded_count -= 1;
block_map.unfold_buffer(buffer_to_unfold, buffer, cx);
block_map.unfold_buffers([buffer_to_unfold], buffer, cx);
}
log::info!(
"Unfolded buffers: {unfolded_count}, folded buffers: {folded_count}"