Fix movement across soft wrap boundaries

Nathan Sobo and Antonio Scandurra created

Co-Authored-By: Antonio Scandurra <me@as-cii.com>

Change summary

zed/src/editor/display_map.rs          |  2 +-
zed/src/editor/display_map/wrap_map.rs | 11 ++++-------
zed/src/editor/movement.rs             | 16 ++++++++++++++--
3 files changed, 19 insertions(+), 10 deletions(-)

Detailed changes

zed/src/editor/display_map.rs 🔗

@@ -308,7 +308,7 @@ impl Point {
     pub fn to_display_point(self, map: &DisplayMapSnapshot, bias: Bias) -> DisplayPoint {
         let fold_point = self.to_fold_point(&map.folds_snapshot, bias);
         let tab_point = map.tabs_snapshot.to_tab_point(fold_point);
-        let wrap_point = map.wraps_snapshot.to_wrap_point(tab_point, bias);
+        let wrap_point = map.wraps_snapshot.to_wrap_point(tab_point);
         DisplayPoint(wrap_point)
     }
 }

zed/src/editor/display_map/wrap_map.rs 🔗

@@ -495,7 +495,7 @@ impl Snapshot {
     }
 
     pub fn max_point(&self) -> WrapPoint {
-        self.to_wrap_point(self.tab_snapshot.max_point(), Bias::Right)
+        self.to_wrap_point(self.tab_snapshot.max_point())
     }
 
     pub fn line_len(&self, row: u32) -> u32 {
@@ -548,9 +548,9 @@ impl Snapshot {
         TabPoint(tab_point)
     }
 
-    pub fn to_wrap_point(&self, point: TabPoint, bias: Bias) -> WrapPoint {
+    pub fn to_wrap_point(&self, point: TabPoint) -> WrapPoint {
         let mut cursor = self.transforms.cursor::<TabPoint, WrapPoint>();
-        cursor.seek(&point, bias, &());
+        cursor.seek(&point, Bias::Right, &());
         WrapPoint(cursor.sum_start().0 + (point.0 - cursor.seek_start().0))
     }
 
@@ -564,10 +564,7 @@ impl Snapshot {
             }
         }
 
-        self.to_wrap_point(
-            self.tab_snapshot.clip_point(self.to_tab_point(point), bias),
-            bias,
-        )
+        self.to_wrap_point(self.tab_snapshot.clip_point(self.to_tab_point(point), bias))
     }
 
     fn check_invariants(&self) {

zed/src/editor/movement.rs 🔗

@@ -40,8 +40,14 @@ pub fn up(
         point = DisplayPoint::new(0, 0);
     }
 
+    let clip_bias = if point.column() == map.line_len(point.row()) {
+        Bias::Left
+    } else {
+        Bias::Right
+    };
+
     Ok((
-        map.clip_point(point, Bias::Left),
+        map.clip_point(point, clip_bias),
         SelectionGoal::Column(goal_column),
     ))
 }
@@ -65,8 +71,14 @@ pub fn down(
         point = max_point;
     }
 
+    let clip_bias = if point.column() == map.line_len(point.row()) {
+        Bias::Left
+    } else {
+        Bias::Right
+    };
+
     Ok((
-        map.clip_point(point, Bias::Left),
+        map.clip_point(point, clip_bias),
         SelectionGoal::Column(goal_column),
     ))
 }