From e7d03af94232b257ada0b5f75cd05fbe1072496d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 29 Jul 2021 14:00:51 -0600 Subject: [PATCH] Fix moving to previous word across a wrap boundary I'm just going to the end of the soft-wrapped line, mirroring the behavior with hard wraps. It's maybe not perfectly technically correct but that behavior would require us to consider word boundaries outside of the current line, which doesn't seem worth the complexity. --- zed/src/editor.rs | 2 +- zed/src/editor/display_map.rs | 7 +++---- zed/src/editor/display_map/wrap_map.rs | 13 ++++++++----- zed/src/editor/movement.rs | 11 +++++++++-- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/zed/src/editor.rs b/zed/src/editor.rs index d659ead948..52371e072a 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -3423,7 +3423,7 @@ mod tests { view.move_to_previous_word_boundary(&(), cx); assert_eq!( view.selection_ranges(cx), - &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)] + &[DisplayPoint::new(1, 15)..DisplayPoint::new(1, 15)] ); }); } diff --git a/zed/src/editor/display_map.rs b/zed/src/editor/display_map.rs index 19eb4316bb..8efb42f71e 100644 --- a/zed/src/editor/display_map.rs +++ b/zed/src/editor/display_map.rs @@ -213,9 +213,8 @@ impl DisplayMapSnapshot { self.folds_snapshot.is_line_folded(row) } - #[cfg(test)] - pub fn is_line_wrapped(&self, display_row: u32) -> bool { - self.wraps_snapshot.is_line_wrapped(display_row) + pub fn soft_wrap_indent(&self, display_row: u32) -> Option { + self.wraps_snapshot.soft_wrap_indent(display_row) } pub fn text(&self) -> String { @@ -492,7 +491,7 @@ mod tests { if point < snapshot.max_point() { assert!(moved_right > point); if point.column() == snapshot.line_len(point.row()) - || snapshot.is_line_wrapped(point.row()) + || snapshot.soft_wrap_indent(point.row()).is_some() && point.column() == snapshot.line_len(point.row()) - 1 { assert!(moved_right.row() > point.row()); diff --git a/zed/src/editor/display_map/wrap_map.rs b/zed/src/editor/display_map/wrap_map.rs index c7a430959f..11e6caa7fc 100644 --- a/zed/src/editor/display_map/wrap_map.rs +++ b/zed/src/editor/display_map/wrap_map.rs @@ -511,13 +511,16 @@ impl Snapshot { len as u32 } - #[cfg(test)] - pub fn is_line_wrapped(&self, row: u32) -> bool { + pub fn soft_wrap_indent(&self, row: u32) -> Option { let mut cursor = self.transforms.cursor::<_, ()>(); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right, &()); - cursor - .item() - .map_or(false, |transform| !transform.is_isomorphic()) + cursor.item().and_then(|transform| { + if transform.is_isomorphic() { + None + } else { + Some(transform.summary.output.lines.column) + } + }) } pub fn longest_row(&self) -> u32 { diff --git a/zed/src/editor/movement.rs b/zed/src/editor/movement.rs index d6dcce6d75..53a115a077 100644 --- a/zed/src/editor/movement.rs +++ b/zed/src/editor/movement.rs @@ -102,12 +102,19 @@ pub fn line_end(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result Result { - if point.column() == 0 { + let mut line_start = 0; + if point.row() > 0 { + if let Some(indent) = map.soft_wrap_indent(point.row() - 1) { + line_start = indent; + } + } + + if point.column() == line_start { if point.row() == 0 { Ok(DisplayPoint::new(0, 0)) } else { let row = point.row() - 1; - Ok(DisplayPoint::new(row, map.line_len(row))) + Ok(map.clip_point(DisplayPoint::new(row, map.line_len(row)), Bias::Left)) } } else { let mut boundary = DisplayPoint::new(point.row(), 0);