Fix remaining errors and warnings

Nathan Sobo created

Change summary

zed/src/editor.rs                          | 810 ++++++++++++-----------
zed/src/editor/display_map/fold_map.rs     |  14 
zed/src/editor/display_map/line_wrapper.rs |  13 
zed/src/editor/display_map/tab_map.rs      |  35 
zed/src/editor/display_map/wrap_map.rs     |  10 
zed/src/editor/element.rs                  |  68 +
zed/src/file_finder.rs                     |   3 
7 files changed, 481 insertions(+), 472 deletions(-)

Detailed changes

zed/src/editor.rs 🔗

@@ -384,7 +384,7 @@ pub struct Editor {
     single_line: bool,
 }
 
-struct Snapshot {
+pub struct Snapshot {
     pub display_snapshot: DisplayMapSnapshot,
     pub gutter_visible: bool,
     pub scroll_position: Vector2F,
@@ -488,10 +488,14 @@ impl Editor {
         *self.scroll_position.lock()
     }
 
-    pub fn clamp_scroll_left(&self, max: f32) {
+    pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
         let mut scroll_position = self.scroll_position.lock();
-        let scroll_left = scroll_position.x();
-        scroll_position.set_x(scroll_left.min(max));
+        if max < scroll_position.x() {
+            scroll_position.set_x(max);
+            true
+        } else {
+            false
+        }
     }
 
     pub fn autoscroll_vertically(
@@ -559,7 +563,7 @@ impl Editor {
         max_glyph_width: f32,
         layouts: &[text_layout::Line],
         cx: &mut MutableAppContext,
-    ) {
+    ) -> bool {
         let display_map = self.display_map.snapshot(cx);
         let mut target_left = std::f32::INFINITY;
         let mut target_right = 0.0_f32;
@@ -577,7 +581,7 @@ impl Editor {
         target_right = target_right.min(scroll_width);
 
         if target_right - target_left > viewport_width {
-            return;
+            return false;
         }
 
         let mut scroll_position = self.scroll_position.lock();
@@ -586,8 +590,12 @@ impl Editor {
 
         if target_left < scroll_left {
             scroll_position.set_x(target_left / max_glyph_width);
+            true
         } else if target_right > scroll_right {
             scroll_position.set_x((target_right - viewport_width) / max_glyph_width);
+            true
+        } else {
+            false
         }
     }
 
@@ -2564,70 +2572,64 @@ mod tests {
     fn test_selection_with_mouse(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
         let settings = settings::channel(&cx.font_cache()).unwrap().1;
-        let (_, buffer_view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
+        let (_, editor) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx));
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(2, 2), false, cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
         );
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
         );
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
         );
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.end_selection(cx);
             view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
         );
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(3, 3), true, cx);
             view.update_selection(DisplayPoint::new(0, 0), Vector2F::zero(), cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [
                 DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1),
                 DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)
             ]
         );
 
-        buffer_view.update(cx, |view, cx| {
+        editor.update(cx, |view, cx| {
             view.end_selection(cx);
         });
 
-        let view = buffer_view.read(cx);
         assert_eq!(
-            view.selection_ranges(cx),
+            editor.update(cx, |view, cx| view.selection_ranges(cx)),
             [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)]
         );
     }
@@ -2640,28 +2642,28 @@ mod tests {
 
         view.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(2, 2), false, cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
-        );
 
         view.update(cx, |view, cx| {
             view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
-        );
 
         view.update(cx, |view, cx| {
             view.cancel(&(), cx);
             view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
-        );
     }
 
     #[gpui::test]
@@ -2678,26 +2680,30 @@ mod tests {
             view.begin_selection(DisplayPoint::new(0, 1), true, cx);
             view.update_selection(DisplayPoint::new(0, 3), Vector2F::zero(), cx);
             view.end_selection(cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [
+                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1),
+                ]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [
-                DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1),
-            ]
-        );
 
-        view.update(cx, |view, cx| view.cancel(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)]
-        );
+        view.update(cx, |view, cx| {
+            view.cancel(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)]
+            );
+        });
 
-        view.update(cx, |view, cx| view.cancel(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)]
-        );
+        view.update(cx, |view, cx| {
+            view.cancel(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)]
+            );
+        });
     }
 
     #[gpui::test]
@@ -2708,13 +2714,14 @@ mod tests {
         let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6), cx));
 
         let settings = settings::channel(&font_cache).unwrap().1;
-        let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
+        let (_, editor) = cx.add_window(|cx| Editor::for_buffer(buffer.clone(), settings, cx));
 
-        let layouts = view
-            .read(cx)
-            .snapshot(cx)
-            .layout_line_numbers(1000.0, &font_cache, &layout_cache)
-            .unwrap();
+        let layouts = editor.update(cx, |editor, cx| {
+            editor
+                .snapshot(cx)
+                .layout_line_numbers(1000.0, &font_cache, &layout_cache)
+                .unwrap()
+        });
         assert_eq!(layouts.len(), 6);
     }
 
@@ -2983,110 +2990,130 @@ mod tests {
             .unwrap();
         });
 
-        view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_beginning_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_beginning_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_beginning_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_to_end_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_end_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
+                ]
+            );
+        });
 
         // Moving to the end of line again is a no-op.
-        view.update(cx, |view, cx| view.move_to_end_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_end_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
+                ]
+            );
+        });
 
         view.update(cx, |view, cx| {
             view.move_left(&(), cx);
             view.select_to_beginning_of_line(&true, cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
+                ]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
-            ]
-        );
 
-        view.update(cx, |view, cx| view.select_to_beginning_of_line(&true, cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.select_to_beginning_of_line(&true, cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.select_to_beginning_of_line(&true, cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.select_to_beginning_of_line(&true, cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.select_to_end_of_line(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.select_to_end_of_line(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.delete_to_end_of_line(&(), cx));
-        assert_eq!(view.read(cx).text(cx), "ab\n  de");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
-                DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.delete_to_end_of_line(&(), cx);
+            assert_eq!(view.text(cx), "ab\n  de");
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
+                    DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.delete_to_beginning_of_line(&(), cx));
-        assert_eq!(view.read(cx).text(cx), "\n");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            assert_eq!(view.text(cx), "\n");
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+                ]
+            );
+            view.delete_to_beginning_of_line(&(), cx)
+        });
     }
 
     #[gpui::test]
@@ -3106,155 +3133,173 @@ mod tests {
             .unwrap();
         });
 
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
-                DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
-                DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
-                DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(0, 23)..DisplayPoint::new(0, 23),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
-                DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
-            ]
-        );
-
-        view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
-                DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
+                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
-                DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
+                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
-                DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
+                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
+                ]
+            );
+        });
 
         view.update(cx, |view, cx| {
-            view.move_right(&(), cx);
-            view.select_to_previous_word_boundary(&(), cx);
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+                ]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
-                DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
-            ]
-        );
 
         view.update(cx, |view, cx| {
-            view.select_to_previous_word_boundary(&(), cx)
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
+                ]
+            );
         });
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 10)..DisplayPoint::new(0, 7),
-                DisplayPoint::new(2, 3)..DisplayPoint::new(2, 0),
-            ]
-        );
 
-        view.update(cx, |view, cx| view.select_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
-                DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(0, 23)..DisplayPoint::new(0, 23),
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.delete_to_next_word_boundary(&(), cx));
-        assert_eq!(
-            view.read(cx).text(cx),
-            "use std::s::{foo, bar}\n\n  {az.qux()}"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 10)..DisplayPoint::new(0, 10),
-                DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_to_next_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
+                    DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24),
+                ]
+            );
+        });
 
         view.update(cx, |view, cx| {
-            view.delete_to_previous_word_boundary(&(), cx)
+            view.move_to_next_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4),
+                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.move_to_next_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7),
+                    DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.move_to_next_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
+                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.move_right(&(), cx);
+            view.select_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
+                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.select_to_previous_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 7),
+                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 0),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.select_to_next_word_boundary(&(), cx);
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9),
+                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.delete_to_next_word_boundary(&(), cx);
+            assert_eq!(view.text(cx), "use std::s::{foo, bar}\n\n  {az.qux()}");
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 10)..DisplayPoint::new(0, 10),
+                    DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3),
+                ]
+            );
+        });
+
+        view.update(cx, |view, cx| {
+            view.delete_to_previous_word_boundary(&(), cx);
+            assert_eq!(view.text(cx), "use std::::{foo, bar}\n\n  az.qux()}");
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
+                    DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
+                ]
+            );
         });
-        assert_eq!(
-            view.read(cx).text(cx),
-            "use std::::{foo, bar}\n\n  az.qux()}"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9),
-                DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2),
-            ]
-        );
     }
 
     #[gpui::test]
@@ -3341,15 +3386,15 @@ mod tests {
             )
             .unwrap();
             view.delete_line(&(), cx);
+            assert_eq!(view.text(cx), "ghi");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
+                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)
+                ]
+            );
         });
-        assert_eq!(view.read(cx).text(cx), "ghi");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
-                DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)
-            ]
-        );
 
         let settings = settings::channel(&cx.font_cache()).unwrap().1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
@@ -3358,12 +3403,12 @@ mod tests {
             view.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)], cx)
                 .unwrap();
             view.delete_line(&(), cx);
+            assert_eq!(view.text(cx), "ghi\n");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]
+            );
         });
-        assert_eq!(view.read(cx).text(cx), "ghi\n");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]
-        );
     }
 
     #[gpui::test]
@@ -3383,17 +3428,17 @@ mod tests {
             )
             .unwrap();
             view.duplicate_line(&(), cx);
+            assert_eq!(view.text(cx), "abc\nabc\ndef\ndef\nghi\n\n");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
+                    DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
+                    DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
+                    DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
+                ]
+            );
         });
-        assert_eq!(view.read(cx).text(cx), "abc\nabc\ndef\ndef\nghi\n\n");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
-                DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
-                DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
-                DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
-            ]
-        );
 
         let settings = settings::channel(&cx.font_cache()).unwrap().1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
@@ -3408,15 +3453,15 @@ mod tests {
             )
             .unwrap();
             view.duplicate_line(&(), cx);
+            assert_eq!(view.text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1),
+                    DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1),
+                ]
+            );
         });
-        assert_eq!(view.read(cx).text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1),
-                DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1),
-            ]
-        );
     }
 
     #[gpui::test]
@@ -3443,71 +3488,62 @@ mod tests {
                 cx,
             )
             .unwrap();
-        });
-        assert_eq!(
-            view.read(cx).text(cx),
-            "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj"
-        );
+            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj");
 
-        view.update(cx, |view, cx| view.move_line_up(&(), cx));
-        assert_eq!(
-            view.read(cx).text(cx),
-            "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
-                DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
-                DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
-                DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
-            ]
-        );
+            view.move_line_up(&(), cx);
+            assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
+                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
+                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
+                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_line_down(&(), cx));
-        assert_eq!(
-            view.read(cx).text(cx),
-            "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
-                DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
-                DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
-                DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_line_down(&(), cx);
+            assert_eq!(view.text(cx), "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
+                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
+                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
+                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_line_down(&(), cx));
-        assert_eq!(
-            view.read(cx).text(cx),
-            "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
-                DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
-                DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
-                DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_line_down(&(), cx);
+            assert_eq!(view.text(cx), "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
+                    DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
+                    DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
+                    DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
+                ]
+            );
+        });
 
-        view.update(cx, |view, cx| view.move_line_up(&(), cx));
-        assert_eq!(
-            view.read(cx).text(cx),
-            "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff"
-        );
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            vec![
-                DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
-                DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
-                DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
-                DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
-            ]
-        );
+        view.update(cx, |view, cx| {
+            view.move_line_up(&(), cx);
+            assert_eq!(view.text(cx), "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff");
+            assert_eq!(
+                view.selection_ranges(cx),
+                vec![
+                    DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
+                    DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
+                    DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
+                    DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
+                ]
+            );
+        });
     }
 
     #[gpui::test]
@@ -3522,23 +3558,23 @@ mod tests {
         view.update(cx, |view, cx| {
             view.select_ranges(vec![0..4, 8..14, 19..24], false, cx);
             view.cut(&(), cx);
+            assert_eq!(view.text(cx), "two four six ");
         });
-        assert_eq!(view.read(cx).text(cx), "two four six ");
 
         // Paste with three cursors. Each cursor pastes one slice of the clipboard text.
         view.update(cx, |view, cx| {
             view.select_ranges(vec![4..4, 9..9, 13..13], false, cx);
             view.paste(&(), cx);
+            assert_eq!(view.text(cx), "two one four three six five ");
+            assert_eq!(
+                view.selection_ranges(cx),
+                &[
+                    DisplayPoint::new(0, 8)..DisplayPoint::new(0, 8),
+                    DisplayPoint::new(0, 19)..DisplayPoint::new(0, 19),
+                    DisplayPoint::new(0, 28)..DisplayPoint::new(0, 28)
+                ]
+            );
         });
-        assert_eq!(view.read(cx).text(cx), "two one four three six five ");
-        assert_eq!(
-            view.update(cx, |view, cx| view.selection_ranges(cx)),
-            &[
-                DisplayPoint::new(0, 8)..DisplayPoint::new(0, 8),
-                DisplayPoint::new(0, 19)..DisplayPoint::new(0, 19),
-                DisplayPoint::new(0, 28)..DisplayPoint::new(0, 28)
-            ]
-        );
 
         // Paste again but with only two cursors. Since the number of cursors doesn't
         // match the number of slices in the clipboard, the entire clipboard text

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

@@ -26,10 +26,6 @@ impl OutputPoint {
         Self(super::Point::new(row, column))
     }
 
-    pub fn zero() -> Self {
-        Self::new(0, 0)
-    }
-
     pub fn row(self) -> u32 {
         self.0.row
     }
@@ -42,6 +38,7 @@ impl OutputPoint {
         &mut self.0.row
     }
 
+    #[cfg(test)]
     pub fn column_mut(&mut self) -> &mut u32 {
         &mut self.0.column
     }
@@ -450,10 +447,6 @@ impl Snapshot {
         self.chunks_at(OutputOffset(0)).collect()
     }
 
-    pub fn text_summary(&self) -> TextSummary {
-        self.transforms.summary().output
-    }
-
     pub fn text_summary_for_range(&self, range: Range<OutputPoint>) -> TextSummary {
         let mut summary = TextSummary::default();
 
@@ -499,6 +492,7 @@ impl Snapshot {
         OutputOffset(self.transforms.summary().output.bytes)
     }
 
+    #[cfg(test)]
     pub fn line_len(&self, row: u32) -> u32 {
         let line_start = self.to_output_offset(OutputPoint::new(row, 0)).0;
         let line_end = if row >= self.max_point().row() {
@@ -527,6 +521,7 @@ impl Snapshot {
         OutputPoint(self.transforms.summary().output.lines)
     }
 
+    #[cfg(test)]
     pub fn longest_row(&self) -> u32 {
         self.transforms.summary().output.longest_row
     }
@@ -584,7 +579,7 @@ impl Snapshot {
         }
     }
 
-    pub fn highlighted_chunks(&self, range: Range<OutputOffset>) -> HighlightedChunks {
+    pub fn highlighted_chunks(&mut self, range: Range<OutputOffset>) -> HighlightedChunks {
         let mut transform_cursor = self.transforms.cursor::<OutputOffset, usize>();
 
         transform_cursor.seek(&range.end, Bias::Right, &());
@@ -1093,6 +1088,7 @@ pub struct Edit {
     pub new_bytes: Range<OutputOffset>,
 }
 
+#[cfg(test)]
 impl Edit {
     pub fn delta(&self) -> isize {
         self.inserted_bytes() as isize - self.deleted_bytes() as isize

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

@@ -5,7 +5,6 @@ use std::{collections::HashMap, sync::Arc};
 
 pub struct LineWrapper {
     font_system: Arc<dyn FontSystem>,
-    font_cache: Arc<FontCache>,
     font_id: FontId,
     font_size: f32,
     cached_ascii_char_widths: Mutex<[f32; 128]>,
@@ -15,7 +14,7 @@ pub struct LineWrapper {
 impl LineWrapper {
     pub fn new(
         font_system: Arc<dyn FontSystem>,
-        font_cache: Arc<FontCache>,
+        font_cache: &FontCache,
         settings: Settings,
     ) -> Self {
         let font_id = font_cache
@@ -23,7 +22,6 @@ impl LineWrapper {
             .unwrap();
         let font_size = settings.buffer_font_size;
         Self {
-            font_cache,
             font_system,
             font_id,
             font_size,
@@ -32,12 +30,13 @@ impl LineWrapper {
         }
     }
 
+    #[cfg(test)]
     pub fn wrap_line_with_shaping(&self, line: &str, wrap_width: f32) -> Vec<usize> {
         self.font_system
             .wrap_line(line, self.font_id, self.font_size, wrap_width)
     }
 
-    pub fn wrap_line_without_shaping(&self, line: &str, wrap_width: f32) -> Vec<usize> {
+    pub fn wrap_line(&self, line: &str, wrap_width: f32) -> Vec<usize> {
         let mut width = 0.0;
         let mut boundaries = Vec::new();
         let mut last_boundary_ix = 0;
@@ -126,14 +125,14 @@ mod tests {
             ..Settings::new(&font_cache).unwrap()
         };
 
-        let wrapper = LineWrapper::new(font_system, font_cache, settings);
+        let wrapper = LineWrapper::new(font_system, &font_cache, settings);
 
         assert_eq!(
             wrapper.wrap_line_with_shaping("aa bbb cccc ddddd eeee", 72.0),
             &[7, 12, 18],
         );
         assert_eq!(
-            wrapper.wrap_line_without_shaping("aa bbb cccc ddddd eeee", 72.0),
+            wrapper.wrap_line("aa bbb cccc ddddd eeee", 72.0),
             &[7, 12, 18],
         );
 
@@ -142,7 +141,7 @@ mod tests {
             &[4, 11, 18],
         );
         assert_eq!(
-            wrapper.wrap_line_without_shaping("aaa aaaaaaaaaaaaaaaaaa", 72.0),
+            wrapper.wrap_line("aaa aaaaaaaaaaaaaaaaaa", 72.0),
             &[4, 11, 18],
         );
     }

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

@@ -2,7 +2,7 @@ use parking_lot::Mutex;
 
 use super::fold_map::{
     self, Chunks as InputChunks, Edit as InputEdit, HighlightedChunks as InputHighlightedChunks,
-    OutputOffset as InputOffset, OutputPoint as InputPoint, Snapshot as InputSnapshot,
+    OutputPoint as InputPoint, Snapshot as InputSnapshot,
 };
 use crate::{editor::rope, settings::StyleId, util::Bias};
 use std::{cmp, mem, ops::Range};
@@ -144,7 +144,7 @@ impl Snapshot {
         }
     }
 
-    pub fn highlighted_chunks(&self, range: Range<OutputPoint>) -> HighlightedChunks {
+    pub fn highlighted_chunks(&mut self, range: Range<OutputPoint>) -> HighlightedChunks {
         let (input_start, expanded_char_column, to_next_stop) =
             self.to_input_point(range.start, Bias::Left);
         let input_start = self.input.to_output_offset(input_start);
@@ -170,20 +170,6 @@ impl Snapshot {
         self.chunks_at(Default::default()).collect()
     }
 
-    pub fn len(&self) -> OutputOffset {
-        self.to_output_offset(self.input.len())
-    }
-
-    pub fn line_len(&self, row: u32) -> u32 {
-        self.to_output_point(InputPoint::new(row, self.input.line_len(row)))
-            .column()
-    }
-
-    pub fn longest_row(&self) -> u32 {
-        // TODO: Account for tab expansion.
-        self.input.longest_row()
-    }
-
     pub fn max_point(&self) -> OutputPoint {
         self.to_output_point(self.input.max_point())
     }
@@ -195,15 +181,6 @@ impl Snapshot {
         )
     }
 
-    pub fn to_output_offset(&self, input_offset: InputOffset) -> OutputOffset {
-        let input_point = input_offset.to_point(&self.input);
-        let input_row_start_offset = self
-            .input
-            .to_output_offset(InputPoint::new(input_point.row(), 0));
-        let output_point = self.to_output_point(input_point);
-        OutputOffset(input_row_start_offset.0 + output_point.column() as usize)
-    }
-
     pub fn to_output_point(&self, input: InputPoint) -> OutputPoint {
         let chars = self.input.chars_at(InputPoint::new(input.row(), 0));
         let expanded = Self::expand_tabs(chars, input.column() as usize, self.tab_size);
@@ -306,14 +283,6 @@ impl OutputPoint {
     pub fn column(self) -> u32 {
         self.0.column
     }
-
-    pub fn row_mut(&mut self) -> &mut u32 {
-        &mut self.0.row
-    }
-
-    pub fn column_mut(&mut self) -> &mut u32 {
-        &mut self.0.column
-    }
 }
 
 impl From<super::Point> for OutputPoint {

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

@@ -90,7 +90,7 @@ impl WrapMap {
             snapshot: Snapshot::new(tab_snapshot),
             line_wrapper: Arc::new(LineWrapper::new(
                 cx.platform().fonts(),
-                cx.font_cache().clone(),
+                cx.font_cache(),
                 settings,
             )),
         })));
@@ -98,6 +98,7 @@ impl WrapMap {
         this
     }
 
+    #[cfg(test)]
     pub fn is_rewrapping(&self) -> bool {
         self.0.lock().background_task.is_some()
     }
@@ -392,7 +393,7 @@ impl Snapshot {
                     }
 
                     let mut prev_boundary_ix = 0;
-                    for boundary_ix in line_wrapper.wrap_line_without_shaping(&line, wrap_width) {
+                    for boundary_ix in line_wrapper.wrap_line(&line, wrap_width) {
                         let wrapped = &line[prev_boundary_ix..boundary_ix];
                         new_transforms
                             .push_or_extend(Transform::isomorphic(TextSummary::from(wrapped)));
@@ -717,6 +718,7 @@ impl WrapPoint {
         Self(super::Point::new(row, column))
     }
 
+    #[cfg(test)]
     pub fn zero() -> Self {
         Self::new(0, 0)
     }
@@ -826,7 +828,7 @@ mod tests {
             });
             let mut notifications = wrap_map.notifications();
 
-            let mut line_wrapper = LineWrapper::new(font_system, font_cache, settings);
+            let mut line_wrapper = LineWrapper::new(font_system, &font_cache, settings);
             let unwrapped_text = tabs_snapshot.text();
             let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
 
@@ -888,7 +890,7 @@ mod tests {
             }
 
             let mut prev_ix = 0;
-            for ix in line_wrapper.wrap_line_without_shaping(line, wrap_width) {
+            for ix in line_wrapper.wrap_line(line, wrap_width) {
                 wrapped_text.push_str(&line[prev_ix..ix]);
                 wrapped_text.push('\n');
                 prev_ix = ix;

zed/src/editor/element.rs 🔗

@@ -51,8 +51,7 @@ impl EditorElement {
     ) -> bool {
         if paint.text_bounds.contains_point(position) {
             let position = self.update_view(cx.app, |view, cx| {
-                let font_cache = cx.font_cache().clone();
-                paint.point_for_position(view, layout, position, &font_cache, cx)
+                paint.point_for_position(view, layout, position, cx)
             });
             cx.dispatch_action("buffer:select", SelectAction::Begin { position, add: cmd });
             true
@@ -110,7 +109,7 @@ impl EditorElement {
             let font_cache = cx.font_cache.clone();
             let text_layout_cache = cx.text_layout_cache.clone();
             let action = self.update_view(cx.app, |view, cx| SelectAction::Update {
-                position: paint.point_for_position(view, layout, position, &font_cache, cx),
+                position: paint.point_for_position(view, layout, position, cx),
                 scroll_position: (view.scroll_position() + scroll_delta).clamp(
                     Vector2F::zero(),
                     layout.scroll_max(&font_cache, &text_layout_cache),
@@ -376,7 +375,7 @@ impl Element for EditorElement {
             size.set_y((snapshot.max_point().row() + 1) as f32 * line_height);
         }
 
-        let (autoscroll_horizontally, snapshot) = self.update_view(cx.app, |view, cx| {
+        let (autoscroll_horizontally, mut snapshot) = self.update_view(cx.app, |view, cx| {
             let autoscroll_horizontally = view.autoscroll_vertically(size.y(), line_height, cx);
             let snapshot = view.snapshot(cx);
             (autoscroll_horizontally, snapshot)
@@ -416,21 +415,22 @@ impl Element for EditorElement {
             }
         };
 
-        let view = self.view(cx.app);
         let mut selections = HashMap::new();
-        for selection_set_id in view.active_selection_sets(cx.app) {
-            selections.insert(
-                selection_set_id.replica_id,
-                view.selections_in_range(
-                    selection_set_id,
-                    DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
-                    cx.app,
-                )
-                .collect(),
-            );
-        }
+        self.update_view(cx.app, |view, cx| {
+            for selection_set_id in view.active_selection_sets(cx).collect::<Vec<_>>() {
+                selections.insert(
+                    selection_set_id.replica_id,
+                    view.selections_in_range(
+                        selection_set_id,
+                        DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0),
+                        cx,
+                    )
+                    .collect(),
+                );
+            }
+        });
 
-        let layout = LayoutState {
+        let mut layout = LayoutState {
             size,
             gutter_size,
             gutter_padding,
@@ -446,19 +446,26 @@ impl Element for EditorElement {
             max_visible_line_width,
         };
 
-        // TODO: If any of the below changes the editor's scroll state, update the layout's snapshot to reflect it.
-        let view = self.view(cx.app);
-        view.clamp_scroll_left(layout.scroll_max(cx.font_cache, cx.text_layout_cache).x());
-        if autoscroll_horizontally {
-            view.autoscroll_horizontally(
-                view.scroll_position().y() as u32,
-                layout.text_size.x(),
-                layout.scroll_width(cx.font_cache, cx.text_layout_cache),
-                snapshot.em_width(cx.font_cache),
-                &layout.line_layouts,
-                cx.app,
-            );
-        }
+        self.update_view(cx.app, |view, cx| {
+            let clamped = view.clamp_scroll_left(layout.scroll_max(font_cache, layout_cache).x());
+            let autoscrolled;
+            if autoscroll_horizontally {
+                autoscrolled = view.autoscroll_horizontally(
+                    view.scroll_position().y() as u32,
+                    layout.text_size.x(),
+                    layout.scroll_width(font_cache, layout_cache),
+                    layout.snapshot.em_width(font_cache),
+                    &layout.line_layouts,
+                    cx,
+                );
+            } else {
+                autoscrolled = false;
+            }
+
+            if clamped || autoscrolled {
+                layout.snapshot = view.snapshot(cx);
+            }
+        });
 
         (size, Some(layout))
     }
@@ -588,7 +595,6 @@ impl PaintState {
         view: &Editor,
         layout: &LayoutState,
         position: Vector2F,
-        font_cache: &FontCache,
         cx: &mut MutableAppContext,
     ) -> DisplayPoint {
         let scroll_position = view.scroll_position();

zed/src/file_finder.rs 🔗

@@ -311,7 +311,8 @@ impl FileFinder {
     }
 
     fn workspace_updated(&mut self, _: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) {
-        if let Some(task) = self.spawn_search(self.query_buffer.read(cx).text(cx), cx) {
+        let query = self.query_buffer.update(cx, |buffer, cx| buffer.text(cx));
+        if let Some(task) = self.spawn_search(query, cx) {
             task.detach();
         }
     }