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 d659ead94852dcb83dad02e5a9d4e6df95c38cd9..52371e072ac81e6f3b557038eabbf459b47109e9 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 19eb4316bb7623ebc7aebfd42b4ce0c6988d22d2..8efb42f71eef45021f39535436fed60809bd4153 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 c7a430959fb6e6ce1d6cb53671ed38828c62a6f4..11e6caa7fc4dd87243c280815f32a604abdca791 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 d6dcce6d75fa77358d6b0c489921412f77c0f31e..53a115a0771f6f966b5bf9dd6562ea900c75c410 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);