diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index d2e50f9820..5d9eaed693 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -210,7 +210,7 @@ impl DisplayMapSnapshot { fn point_to_display_point(&self, point: Point, bias: Bias) -> DisplayPoint { DisplayPoint( self.blocks_snapshot.to_block_point( - self.wraps_snapshot.to_wrap_point( + self.wraps_snapshot.from_tab_point( self.tabs_snapshot .to_tab_point(point.to_fold_point(&self.folds_snapshot, bias)), ), diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index ec407ce521..9ab0e9dc0a 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -179,9 +179,8 @@ impl BlockMap { } // Find the blocks within this edited region. - // - // TODO - convert these wrap map edits into buffer positions. - let start_anchor = buffer.anchor_before(Point::new(new_start.row(), 0)); + let new_start = wrap_snapshot.to_point(new_start, Bias::Left); + let start_anchor = buffer.anchor_before(new_start); let start_block_ix = match self.blocks[last_block_ix..].binary_search_by(|probe| { probe .position @@ -194,7 +193,8 @@ impl BlockMap { let end_block_ix = if new_end.row() > wrap_snapshot.max_point().row() { self.blocks.len() } else { - let end_anchor = buffer.anchor_before(Point::new(new_end.row(), 0)); + let new_end = wrap_snapshot.to_point(new_end, Bias::Left); + let end_anchor = buffer.anchor_before(new_end); match self.blocks[start_block_ix..].binary_search_by(|probe| { probe .position @@ -210,7 +210,17 @@ impl BlockMap { blocks_in_edit.extend( self.blocks[start_block_ix..end_block_ix] .iter() - .map(|block| (block.position.to_point(buffer).row, block)), + .map(|block| { + let mut position = block.position.to_point(buffer); + match block.disposition { + BlockDisposition::Above => position.column = 0, + BlockDisposition::Below => { + position.column = buffer.line_len(position.row) + } + } + let position = wrap_snapshot.from_point(position, Bias::Left); + (position.row(), block) + }), ); blocks_in_edit.sort_unstable_by_key(|(row, block)| (*row, block.disposition, block.id)); @@ -312,13 +322,24 @@ impl<'a> BlockMapWriter<'a> { let buffer = self.0.buffer.read(cx); let mut ids = Vec::new(); let mut edits = Vec::>::new(); + let wrap_snapshot = &*self.0.wrap_snapshot.lock(); for block in blocks { let id = BlockId(self.0.next_block_id.fetch_add(1, SeqCst)); ids.push(id); let position = buffer.anchor_before(block.position); - let row = position.to_point(buffer).row; + let point = position.to_point(buffer); + let start_row = wrap_snapshot + .from_point(Point::new(point.row, 0), Bias::Left) + .row(); + let end_row = if point.row == buffer.max_point().row { + wrap_snapshot.max_point().row() + 1 + } else { + wrap_snapshot + .from_point(Point::new(point.row + 1, 0), Bias::Left) + .row() + }; let block_ix = match self .0 @@ -345,18 +366,18 @@ impl<'a> BlockMapWriter<'a> { }), ); - if let Err(edit_ix) = edits.binary_search_by_key(&row, |edit| edit.old.start) { + if let Err(edit_ix) = edits.binary_search_by_key(&start_row, |edit| edit.old.start) { edits.insert( edit_ix, Edit { - old: row..(row + 1), - new: row..(row + 1), + old: start_row..end_row, + new: start_row..end_row, }, ); } } - self.0.sync(&*self.0.wrap_snapshot.lock(), edits, cx); + self.0.sync(wrap_snapshot, edits, cx); ids } @@ -752,7 +773,7 @@ mod tests { .select_font(family_id, &Default::default()) .unwrap(); - let text = "\none two three\nfour five six\nseven eight"; + let text = "one two three\nfour five six\nseven eight"; let buffer = cx.add_model(|cx| Buffer::new(0, text, cx)); let (fold_map, folds_snapshot) = FoldMap::new(buffer.clone(), cx); @@ -764,13 +785,13 @@ mod tests { writer.insert( vec![ BlockProperties { - position: Point::new(1, 8), + position: Point::new(1, 12), text: "BLOCK 1", disposition: BlockDisposition::Above, runs: vec![], }, BlockProperties { - position: Point::new(2, 0), + position: Point::new(1, 1), text: "BLOCK 2", disposition: BlockDisposition::Below, runs: vec![], @@ -784,7 +805,7 @@ mod tests { let mut snapshot = block_map.read(wraps_snapshot, vec![], cx); assert_eq!( snapshot.text(), - "\nBLOCK 1\none two \nthree\nfour five \nsix\nBLOCK 2\nseven \neight" + "one two \nthree\nBLOCK 1\nfour five \nsix\nBLOCK 2\nseven \neight" ); } diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 93fae6d6b2..4d6ab6ac71 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -1,4 +1,5 @@ -use super::fold_map::{self, FoldEdit, FoldPoint, Snapshot as FoldSnapshot}; +use super::fold_map::{self, FoldEdit, FoldPoint, Snapshot as FoldSnapshot, ToFoldPoint}; +use buffer::Point; use language::{rope, HighlightedChunk}; use parking_lot::Mutex; use std::{mem, ops::Range}; @@ -207,6 +208,10 @@ impl Snapshot { TabPoint::new(input.row(), expanded as u32) } + pub fn from_point(&self, point: Point, bias: Bias) -> TabPoint { + self.to_tab_point(point.to_fold_point(&self.fold_snapshot, bias)) + } + pub fn to_fold_point(&self, output: TabPoint, bias: Bias) -> (FoldPoint, usize, usize) { let chars = self.fold_snapshot.chars_at(FoldPoint::new(output.row(), 0)); let expanded = output.column() as usize; @@ -219,6 +224,12 @@ impl Snapshot { ) } + pub fn to_point(&self, point: TabPoint, bias: Bias) -> Point { + self.to_fold_point(point, bias) + .0 + .to_buffer_point(&self.fold_snapshot) + } + fn expand_tabs(chars: impl Iterator, column: usize, tab_size: usize) -> usize { let mut expanded_chars = 0; let mut expanded_bytes = 0; diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index ffc2781520..51908c0877 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -657,7 +657,15 @@ impl Snapshot { TabPoint(tab_point) } - pub fn to_wrap_point(&self, point: TabPoint) -> WrapPoint { + pub fn to_point(&self, point: WrapPoint, bias: Bias) -> Point { + self.tab_snapshot.to_point(self.to_tab_point(point), bias) + } + + pub fn from_point(&self, point: Point, bias: Bias) -> WrapPoint { + self.from_tab_point(self.tab_snapshot.from_point(point, bias)) + } + + pub fn from_tab_point(&self, point: TabPoint) -> WrapPoint { let mut cursor = self.transforms.cursor::<(TabPoint, WrapPoint)>(); cursor.seek(&point, Bias::Right, &()); WrapPoint(cursor.start().1 .0 + (point.0 - cursor.start().0 .0)) @@ -673,7 +681,7 @@ impl Snapshot { } } - self.to_wrap_point(self.tab_snapshot.clip_point(self.to_tab_point(point), bias)) + self.from_tab_point(self.tab_snapshot.clip_point(self.to_tab_point(point), bias)) } fn check_invariants(&self) {