Don't render line numbers for soft-wrapped line segments

Nathan Sobo created

Change summary

zed/src/editor.rs                      | 22 +++++++++++++---------
zed/src/editor/display_map.rs          |  1 +
zed/src/editor/display_map/wrap_map.rs | 17 ++++++++++++++---
zed/src/editor/element.rs              | 22 ++++++++++++----------
4 files changed, 40 insertions(+), 22 deletions(-)

Detailed changes

zed/src/editor.rs 🔗

@@ -2345,7 +2345,7 @@ impl Snapshot {
         viewport_height: f32,
         font_cache: &FontCache,
         layout_cache: &TextLayoutCache,
-    ) -> Result<Vec<text_layout::Line>> {
+    ) -> Result<Vec<Option<text_layout::Line>>> {
         let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?;
 
         let start_row = self.scroll_position().y() as usize;
@@ -2357,18 +2357,22 @@ impl Snapshot {
 
         let mut layouts = Vec::with_capacity(line_count);
         let mut line_number = String::new();
-        for buffer_row in self
+        for (buffer_row, soft_wrapped) in self
             .display_snapshot
             .buffer_rows(start_row as u32)
             .take(line_count)
         {
-            line_number.clear();
-            write!(&mut line_number, "{}", buffer_row + 1).unwrap();
-            layouts.push(layout_cache.layout_str(
-                &line_number,
-                self.font_size,
-                &[(line_number.len(), font_id, ColorU::black())],
-            ));
+            if soft_wrapped {
+                layouts.push(None);
+            } else {
+                line_number.clear();
+                write!(&mut line_number, "{}", buffer_row + 1).unwrap();
+                layouts.push(Some(layout_cache.layout_str(
+                    &line_number,
+                    self.font_size,
+                    &[(line_number.len(), font_id, ColorU::black())],
+                )));
+            }
         }
 
         Ok(layouts)

zed/src/editor/display_map.rs 🔗

@@ -349,6 +349,7 @@ mod tests {
                     assert_eq!(
                         snapshot
                             .buffer_rows(start_display_row as u32)
+                            .map(|(row, _)| row)
                             .collect::<Vec<_>>(),
                         &expected_buffer_rows[start_display_row..],
                         "invalid buffer_rows({}..)",

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

@@ -69,6 +69,7 @@ pub struct BufferRows<'a> {
     input_buffer_rows: fold_map::BufferRows<'a>,
     input_buffer_row: u32,
     output_row: u32,
+    soft_wrapped: bool,
     max_output_row: u32,
     transforms: Cursor<'a, Transform, WrapPoint, TabPoint>,
 }
@@ -516,10 +517,14 @@ impl Snapshot {
 
     pub fn buffer_rows(&self, start_row: u32) -> BufferRows {
         let mut transforms = self.transforms.cursor::<WrapPoint, TabPoint>();
-        transforms.seek(&WrapPoint::new(start_row, 0), Bias::Right, &());
+        transforms.seek(&WrapPoint::new(start_row, 0), Bias::Left, &());
         let mut input_row = transforms.sum_start().row();
+        let soft_wrapped;
         if transforms.item().map_or(false, |t| t.is_isomorphic()) {
             input_row += start_row - transforms.seek_start().row();
+            soft_wrapped = false;
+        } else {
+            soft_wrapped = true;
         }
         let mut input_buffer_rows = self.tab_snapshot.buffer_rows(input_row);
         let input_buffer_row = input_buffer_rows.next().unwrap();
@@ -528,6 +533,7 @@ impl Snapshot {
             input_buffer_row,
             input_buffer_rows,
             output_row: start_row,
+            soft_wrapped,
             max_output_row: self.max_point().row(),
         }
     }
@@ -686,7 +692,7 @@ impl<'a> Iterator for HighlightedChunks<'a> {
 }
 
 impl<'a> Iterator for BufferRows<'a> {
-    type Item = u32;
+    type Item = (u32, bool);
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.output_row > self.max_output_row {
@@ -694,14 +700,19 @@ impl<'a> Iterator for BufferRows<'a> {
         }
 
         let buffer_row = self.input_buffer_row;
+        let soft_wrapped = self.soft_wrapped;
+
         self.output_row += 1;
         self.transforms
             .seek_forward(&WrapPoint::new(self.output_row, 0), Bias::Left, &());
         if self.transforms.item().map_or(false, |t| t.is_isomorphic()) {
             self.input_buffer_row = self.input_buffer_rows.next().unwrap();
+            self.soft_wrapped = false;
+        } else {
+            self.soft_wrapped = true;
         }
 
-        Some(buffer_row)
+        Some((buffer_row, soft_wrapped))
     }
 }
 

zed/src/editor/element.rs 🔗

@@ -195,16 +195,18 @@ impl EditorElement {
         });
 
         for (ix, line) in layout.line_number_layouts.iter().enumerate() {
-            let line_origin = rect.origin()
-                + vec2f(
-                    rect.width() - line.width() - layout.gutter_padding,
-                    ix as f32 * layout.line_height - (scroll_top % layout.line_height),
+            if let Some(line) = line {
+                let line_origin = rect.origin()
+                    + vec2f(
+                        rect.width() - line.width() - layout.gutter_padding,
+                        ix as f32 * layout.line_height - (scroll_top % layout.line_height),
+                    );
+                line.paint(
+                    line_origin,
+                    RectF::new(vec2f(0., 0.), vec2f(line.width(), layout.line_height)),
+                    cx,
                 );
-            line.paint(
-                line_origin,
-                RectF::new(vec2f(0., 0.), vec2f(line.width(), layout.line_height)),
-                cx,
-            );
+            }
         }
 
         cx.scene.pop_layer();
@@ -560,7 +562,7 @@ pub struct LayoutState {
     text_size: Vector2F,
     snapshot: Snapshot,
     line_layouts: Vec<text_layout::Line>,
-    line_number_layouts: Vec<text_layout::Line>,
+    line_number_layouts: Vec<Option<text_layout::Line>>,
     line_height: f32,
     em_width: f32,
     selections: HashMap<ReplicaId, Vec<Range<DisplayPoint>>>,