mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Position blocks above/below buffer lines, even when the anchored line is soft-wrapped
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
2cb8b0fcd3
commit
862b988d56
4 changed files with 58 additions and 18 deletions
|
@ -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)),
|
||||
),
|
||||
|
|
|
@ -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::<Edit<u32>>::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"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Item = char>, column: usize, tab_size: usize) -> usize {
|
||||
let mut expanded_chars = 0;
|
||||
let mut expanded_bytes = 0;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue