diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index ba84ba48ac..020f2b5381 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -783,11 +783,13 @@ impl<'a> BlockMapWriter<'a> { &mut self, blocks: impl IntoIterator>, ) -> Vec { - let mut ids = Vec::new(); + let blocks = blocks.into_iter(); + let mut ids = Vec::with_capacity(blocks.size_hint().1.unwrap_or(0)); let mut edits = Patch::default(); let wrap_snapshot = &*self.0.wrap_snapshot.borrow(); let buffer = wrap_snapshot.buffer_snapshot(); + let mut previous_wrap_row_range: Option> = None; for block in blocks { let id = CustomBlockId(self.0.next_block_id.fetch_add(1, SeqCst)); ids.push(id); @@ -797,11 +799,18 @@ impl<'a> BlockMapWriter<'a> { let wrap_row = wrap_snapshot .make_wrap_point(Point::new(point.row, 0), Bias::Left) .row(); - let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); - let end_row = wrap_snapshot - .next_row_boundary(WrapPoint::new(wrap_row, 0)) - .unwrap_or(wrap_snapshot.max_point().row() + 1); + let (start_row, end_row) = { + previous_wrap_row_range.take_if(|range| !range.contains(&wrap_row)); + let range = previous_wrap_row_range.get_or_insert_with(|| { + let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); + let end_row = wrap_snapshot + .next_row_boundary(WrapPoint::new(wrap_row, 0)) + .unwrap_or(wrap_snapshot.max_point().row() + 1); + start_row..end_row + }); + (range.start, range.end) + }; let block_ix = match self .0 .custom_blocks @@ -881,6 +890,7 @@ impl<'a> BlockMapWriter<'a> { let buffer = wrap_snapshot.buffer_snapshot(); let mut edits = Patch::default(); let mut last_block_buffer_row = None; + let mut previous_wrap_row_range: Option> = None; self.0.custom_blocks.retain(|block| { if block_ids.contains(&block.id) { let buffer_row = block.position.to_point(buffer).row; @@ -889,21 +899,32 @@ impl<'a> BlockMapWriter<'a> { let wrap_row = wrap_snapshot .make_wrap_point(Point::new(buffer_row, 0), Bias::Left) .row(); - let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); - let end_row = wrap_snapshot - .next_row_boundary(WrapPoint::new(wrap_row, 0)) - .unwrap_or(wrap_snapshot.max_point().row() + 1); + let (start_row, end_row) = { + previous_wrap_row_range.take_if(|range| !range.contains(&wrap_row)); + let range = previous_wrap_row_range.get_or_insert_with(|| { + let start_row = + wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); + let end_row = wrap_snapshot + .next_row_boundary(WrapPoint::new(wrap_row, 0)) + .unwrap_or(wrap_snapshot.max_point().row() + 1); + start_row..end_row + }); + (range.start, range.end) + }; + edits.push(Edit { old: start_row..end_row, new: start_row..end_row, }) } - self.0.custom_blocks_by_id.remove(&block.id); false } else { true } }); + self.0 + .custom_blocks_by_id + .retain(|id, _| !block_ids.contains(id)); self.0.sync(wrap_snapshot, edits); } }