diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 17886d09bd3dcf4753dd22d5139c7775836e4d4f..e5b9cfc93fd4784936a13c45daee48a121a70e79 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -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,15 +68,16 @@ use std::{ ops::{Add, Range, Sub}, sync::Arc, }; -use sum_tree::{Bias, TreeMap}; + +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 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}; - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FoldStatus { Folded, diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 7f2ab12308c8c0a92e7d60505c0e6188073b0aa8..27e61c51903b2ba8ca28623de46b742e710eba11 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -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, diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 7446b21b9cca5158c3df1c9c13fcb4f7d65b3445..1da3361f53853a5ea5a9d532b9ee2c05d6010a5d 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -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,