Implement BlockSnapshot::line_len, use it in DisplayMap

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2021-11-17 14:56:05 -08:00
parent 00b5cc472e
commit 707ffe8ff3
4 changed files with 41 additions and 15 deletions

View file

@ -249,6 +249,11 @@ impl Rope {
self.summary().lines_utf16
}
}
pub fn line_len(&self, row: u32) -> u32 {
self.clip_point(Point::new(row, u32::MAX), Bias::Left)
.column
}
}
impl<'a> From<&'a str> for Rope {

View file

@ -14,8 +14,7 @@ use sum_tree::Bias;
use tab_map::TabMap;
use wrap_map::WrapMap;
pub use block_map::{BlockDisposition, BlockProperties, Chunks};
pub use wrap_map::BufferRows;
pub use block_map::{BlockDisposition, BlockProperties, BufferRows, Chunks};
pub trait ToDisplayPoint {
fn to_display_point(&self, map: &DisplayMapSnapshot) -> DisplayPoint;
@ -174,7 +173,7 @@ impl DisplayMapSnapshot {
}
pub fn buffer_rows(&self, start_row: u32) -> BufferRows {
self.wraps_snapshot.buffer_rows(start_row)
self.blocks_snapshot.buffer_rows(start_row)
}
pub fn buffer_row_count(&self) -> u32 {
@ -304,7 +303,11 @@ impl DisplayMapSnapshot {
}
pub fn soft_wrap_indent(&self, display_row: u32) -> Option<u32> {
self.wraps_snapshot.soft_wrap_indent(display_row)
let wrap_row = self
.blocks_snapshot
.to_wrap_point(BlockPoint::new(display_row, 0))
.row();
self.wraps_snapshot.soft_wrap_indent(wrap_row)
}
pub fn text(&self) -> String {
@ -339,7 +342,7 @@ impl DisplayMapSnapshot {
}
pub fn line_len(&self, row: u32) -> u32 {
self.wraps_snapshot.line_len(row)
self.blocks_snapshot.line_len(row)
}
pub fn longest_row(&self) -> u32 {

View file

@ -336,7 +336,7 @@ fn push_isomorphic(tree: &mut SumTree<Transform>, rows: u32) {
}
impl BlockPoint {
fn new(row: u32, column: u32) -> Self {
pub fn new(row: u32, column: u32) -> Self {
Self(Point::new(row, column))
}
}
@ -520,7 +520,24 @@ impl BlockSnapshot {
}
pub fn max_point(&self) -> BlockPoint {
self.to_block_point(self.wrap_snapshot.max_point())
let row = self.transforms.summary().output_rows - 1;
BlockPoint::new(row, self.line_len(row))
}
pub fn line_len(&self, row: u32) -> u32 {
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>();
cursor.seek(&BlockRow(row), Bias::Right, &());
if let Some(transform) = cursor.item() {
let (output_start, input_start) = cursor.start();
let overshoot = row - output_start.0;
if let Some(block) = &transform.block {
block.text.line_len(overshoot)
} else {
self.wrap_snapshot.line_len(input_start.0 + overshoot)
}
} else {
panic!("row out of range");
}
}
pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint {
@ -819,10 +836,6 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow {
}
impl BlockDisposition {
fn is_above(&self) -> bool {
matches!(self, BlockDisposition::Above)
}
fn is_below(&self) -> bool {
matches!(self, BlockDisposition::Below)
}
@ -1275,6 +1288,15 @@ mod tests {
);
}
for (row, line) in expected_lines.iter().enumerate() {
assert_eq!(
blocks_snapshot.line_len(row as u32),
line.len() as u32,
"invalid line len for row {}",
row
);
}
for row in 0..=blocks_snapshot.wrap_snapshot.max_point().row() {
let wrap_point = WrapPoint::new(row, 0);
let block_point = blocks_snapshot.to_block_point(wrap_point);

View file

@ -902,10 +902,6 @@ impl WrapPoint {
self.0.row
}
pub fn column(self) -> u32 {
self.0.column
}
pub fn row_mut(&mut self) -> &mut u32 {
&mut self.0.row
}