editor: Correctly handle blocks spanning more than 128 rows (#42172)
Release Notes: - Fixed block rendering for blocks spanning more than 128 rows
This commit is contained in:
@@ -25,29 +25,25 @@ mod crease_map;
|
||||
mod custom_highlights;
|
||||
mod fold_map;
|
||||
mod inlay_map;
|
||||
pub(crate) mod invisibles;
|
||||
mod invisibles;
|
||||
mod tab_map;
|
||||
mod wrap_map;
|
||||
|
||||
use crate::{
|
||||
EditorStyle, RowExt, hover_links::InlayHighlight, inlays::Inlay, movement::TextLayoutDetails,
|
||||
};
|
||||
pub use crate::display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap};
|
||||
pub use block_map::{
|
||||
Block, BlockChunks as DisplayChunks, BlockContext, BlockId, BlockMap, BlockPlacement,
|
||||
BlockPoint, BlockProperties, BlockRows, BlockStyle, CustomBlockId, EditorMargins, RenderBlock,
|
||||
StickyHeaderExcerpt,
|
||||
};
|
||||
use block_map::{BlockRow, BlockSnapshot};
|
||||
use collections::{HashMap, HashSet};
|
||||
pub use crease_map::*;
|
||||
use fold_map::FoldSnapshot;
|
||||
pub use fold_map::{
|
||||
ChunkRenderer, ChunkRendererContext, ChunkRendererId, Fold, FoldId, FoldPlaceholder, FoldPoint,
|
||||
};
|
||||
use gpui::{App, Context, Entity, Font, HighlightStyle, LineLayout, Pixels, UnderlineStyle};
|
||||
use inlay_map::InlaySnapshot;
|
||||
pub use inlay_map::{InlayOffset, InlayPoint};
|
||||
pub use invisibles::{is_invisible, replacement};
|
||||
|
||||
use collections::{HashMap, HashSet};
|
||||
use gpui::{App, Context, Entity, Font, HighlightStyle, LineLayout, Pixels, UnderlineStyle};
|
||||
use language::{
|
||||
OffsetUtf16, Point, Subscription as BufferSubscription, language_settings::language_settings,
|
||||
};
|
||||
@@ -58,6 +54,10 @@ use multi_buffer::{
|
||||
use project::InlayId;
|
||||
use project::project_settings::DiagnosticSeverity;
|
||||
use serde::Deserialize;
|
||||
use sum_tree::{Bias, TreeMap};
|
||||
use text::{BufferId, LineIndent};
|
||||
use ui::{SharedString, px};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use std::{
|
||||
any::TypeId,
|
||||
@@ -68,14 +68,15 @@ use std::{
|
||||
ops::{Add, Range, Sub},
|
||||
sync::Arc,
|
||||
};
|
||||
use sum_tree::{Bias, TreeMap};
|
||||
use tab_map::TabSnapshot;
|
||||
use text::{BufferId, LineIndent};
|
||||
use ui::{SharedString, px};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use wrap_map::{WrapMap, WrapSnapshot};
|
||||
|
||||
pub use crate::display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap};
|
||||
use crate::{
|
||||
EditorStyle, RowExt, hover_links::InlayHighlight, inlays::Inlay, movement::TextLayoutDetails,
|
||||
};
|
||||
use block_map::{BlockRow, BlockSnapshot};
|
||||
use fold_map::FoldSnapshot;
|
||||
use inlay_map::InlaySnapshot;
|
||||
use tab_map::TabSnapshot;
|
||||
use wrap_map::{WrapMap, WrapSnapshot};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum FoldStatus {
|
||||
|
||||
@@ -453,6 +453,7 @@ pub struct BlockChunks<'a> {
|
||||
input_chunk: Chunk<'a>,
|
||||
output_row: BlockRow,
|
||||
max_output_row: BlockRow,
|
||||
line_count_overflow: RowDelta,
|
||||
masked: bool,
|
||||
}
|
||||
|
||||
@@ -1352,6 +1353,7 @@ impl BlockSnapshot {
|
||||
input_chunk: Default::default(),
|
||||
transforms: cursor,
|
||||
output_row: rows.start,
|
||||
line_count_overflow: RowDelta(0),
|
||||
max_output_row,
|
||||
masked,
|
||||
}
|
||||
@@ -1743,6 +1745,17 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
return None;
|
||||
}
|
||||
|
||||
if self.line_count_overflow > RowDelta(0) {
|
||||
let lines = self.line_count_overflow.0.min(u128::BITS);
|
||||
self.line_count_overflow.0 -= lines;
|
||||
self.output_row += RowDelta(lines);
|
||||
return Some(Chunk {
|
||||
text: unsafe { std::str::from_utf8_unchecked(&NEWLINES[..lines as usize]) },
|
||||
chars: 1u128.unbounded_shl(lines).wrapping_sub(1),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
let transform = self.transforms.item()?;
|
||||
if transform.block.is_some() {
|
||||
let block_start = self.transforms.start().0;
|
||||
@@ -1754,13 +1767,14 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
|
||||
let start_in_block = self.output_row - block_start;
|
||||
let end_in_block = cmp::min(self.max_output_row, block_end) - block_start;
|
||||
// todo: We need to split the chunk here instead of taking min
|
||||
let line_count = cmp::min(end_in_block - start_in_block, RowDelta(u128::BITS));
|
||||
self.output_row += line_count;
|
||||
let line_count = end_in_block - start_in_block;
|
||||
let lines = RowDelta(line_count.0.min(u128::BITS));
|
||||
self.line_count_overflow = line_count - lines;
|
||||
self.output_row += lines;
|
||||
|
||||
return Some(Chunk {
|
||||
text: unsafe { std::str::from_utf8_unchecked(&NEWLINES[..line_count.0 as usize]) },
|
||||
chars: 1u128.unbounded_shl(line_count.0) - 1,
|
||||
text: unsafe { std::str::from_utf8_unchecked(&NEWLINES[..lines.0 as usize]) },
|
||||
chars: 1u128.unbounded_shl(lines.0).wrapping_sub(1),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
@@ -3042,7 +3056,7 @@ mod tests {
|
||||
_ => BlockPlacement::Below(buffer.anchor_after(offset)),
|
||||
};
|
||||
|
||||
let height = rng.random_range(min_height..5);
|
||||
let height = rng.random_range(min_height..512);
|
||||
BlockProperties {
|
||||
style: BlockStyle::Fixed,
|
||||
placement,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
ActiveDiagnostic, Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings,
|
||||
EditorSnapshot, GlobalDiagnosticRenderer, Hover,
|
||||
display_map::{InlayOffset, ToDisplayPoint, invisibles::is_invisible},
|
||||
display_map::{InlayOffset, ToDisplayPoint, is_invisible},
|
||||
hover_links::{InlayHighlight, RangeInEditor},
|
||||
movement::TextLayoutDetails,
|
||||
scroll::ScrollAmount,
|
||||
|
||||
Reference in New Issue
Block a user