@@ -581,37 +581,45 @@ impl BlockSnapshot {
cursor.seek(&BlockRow(point.row), Bias::Right, &());
let max_input_row = WrapRow(self.transforms.summary().input_rows);
- let search_left =
+ let mut search_left =
(bias == Bias::Left && cursor.start().1 .0 > 0) || cursor.end(&()).1 == max_input_row;
+ let mut reversed = false;
loop {
if let Some(transform) = cursor.item() {
if transform.is_isomorphic() {
let (output_start_row, input_start_row) = cursor.start();
let (output_end_row, input_end_row) = cursor.end(&());
+ let output_start = Point::new(output_start_row.0, 0);
+ let input_start = Point::new(input_start_row.0, 0);
+ let input_end = Point::new(input_end_row.0, 0);
+ let input_point = if point.row >= output_end_row.0 {
+ let line_len = self.wrap_snapshot.line_len(input_end_row.0 - 1);
+ self.wrap_snapshot
+ .clip_point(WrapPoint::new(input_end_row.0 - 1, line_len), bias)
+ } else {
+ let output_overshoot = point.0.saturating_sub(output_start);
+ self.wrap_snapshot
+ .clip_point(WrapPoint(input_start + output_overshoot), bias)
+ };
- if point.row >= output_end_row.0 {
- return BlockPoint::new(
- output_end_row.0 - 1,
- self.wrap_snapshot.line_len(input_end_row.0 - 1),
- );
+ if (input_start..input_end).contains(&input_point.0) {
+ let input_overshoot = input_point.0.saturating_sub(input_start);
+ return BlockPoint(output_start + input_overshoot);
}
+ }
- let output_start = Point::new(output_start_row.0, 0);
- let output_overshoot = point.0 - output_start;
- let input_start = Point::new(input_start_row.0, 0);
- let input_point = self
- .wrap_snapshot
- .clip_point(WrapPoint(input_start + output_overshoot), bias);
- let input_overshoot = input_point.0 - input_start;
- return BlockPoint(output_start + input_overshoot);
- } else if search_left {
+ if search_left {
cursor.prev(&());
} else {
cursor.next(&());
}
- } else {
+ } else if reversed {
return self.max_point();
+ } else {
+ reversed = true;
+ search_left = !search_left;
+ cursor.seek(&BlockRow(point.row), Bias::Right, &());
}
}
}
@@ -1368,16 +1376,30 @@ mod tests {
let mut block_point = BlockPoint::new(0, 0);
for c in expected_text.chars() {
let left_point = blocks_snapshot.clip_point(block_point, Bias::Left);
- let right_point = blocks_snapshot.clip_point(block_point, Bias::Right);
-
+ let left_buffer_point = blocks_snapshot.to_point(left_point, Bias::Left);
assert_eq!(
blocks_snapshot.to_block_point(blocks_snapshot.to_wrap_point(left_point)),
left_point
);
+ assert_eq!(
+ left_buffer_point,
+ buffer_snapshot.clip_point(left_buffer_point, Bias::Right),
+ "{:?} is not valid in buffer coordinates",
+ left_point
+ );
+
+ let right_point = blocks_snapshot.clip_point(block_point, Bias::Right);
+ let right_buffer_point = blocks_snapshot.to_point(right_point, Bias::Right);
assert_eq!(
blocks_snapshot.to_block_point(blocks_snapshot.to_wrap_point(right_point)),
right_point
);
+ assert_eq!(
+ right_buffer_point,
+ buffer_snapshot.clip_point(right_buffer_point, Bias::Left),
+ "{:?} is not valid in buffer coordinates",
+ right_point
+ );
if c == '\n' {
block_point.0 += Point::new(1, 0);
@@ -1387,4 +1409,10 @@ mod tests {
}
}
}
+
+ impl BlockSnapshot {
+ fn to_point(&self, point: BlockPoint, bias: Bias) -> Point {
+ self.wrap_snapshot.to_point(self.to_wrap_point(point), bias)
+ }
+ }
}
@@ -35,6 +35,14 @@ impl Point {
pub fn is_zero(&self) -> bool {
self.row == 0 && self.column == 0
}
+
+ pub fn saturating_sub(self, other: Self) -> Self {
+ if self < other {
+ Point::zero()
+ } else {
+ self - other
+ }
+ }
}
impl<'a> Add<&'a Self> for Point {