Fix infinite loop in select all (#3154)

Conrad Irwin created

[[PR Description]]

Release Notes:

- Fixed an infinite loop in select all matches
([#2170](https://github.com/zed-industries/community/issues/2170)).

Change summary

crates/editor/src/editor.rs   |  2 +-
crates/editor/src/movement.rs |  6 ++++--
crates/language/src/buffer.rs |  2 +-
crates/vim/src/test.rs        | 23 +++++++++++++++++++++++
4 files changed, 29 insertions(+), 4 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -6542,7 +6542,7 @@ impl Editor {
                     {
                         if selections
                             .iter()
-                            .find(|selection| selection.equals(&offset_range))
+                            .find(|selection| selection.range().overlaps(&offset_range))
                             .is_none()
                         {
                             next_selected_range = Some(offset_range);

crates/editor/src/movement.rs 🔗

@@ -731,7 +731,9 @@ mod tests {
             let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
             assert_eq!(
                 surrounding_word(&snapshot, display_points[1]),
-                display_points[0]..display_points[2]
+                display_points[0]..display_points[2],
+                "{}",
+                marked_text.to_string()
             );
         }
 
@@ -741,7 +743,7 @@ mod tests {
         assert("loremˇ ˇ  ˇipsum", cx);
         assert("lorem\nˇˇˇ\nipsum", cx);
         assert("lorem\nˇˇipsumˇ", cx);
-        assert("lorem,ˇˇ ˇipsum", cx);
+        assert("loremˇ,ˇˇ ipsum", cx);
         assert("ˇloremˇˇ, ipsum", cx);
     }
 

crates/language/src/buffer.rs 🔗

@@ -373,8 +373,8 @@ pub(crate) struct DiagnosticEndpoint {
 
 #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
 pub enum CharKind {
-    Punctuation,
     Whitespace,
+    Punctuation,
     Word,
 }
 

crates/vim/src/test.rs 🔗

@@ -734,3 +734,26 @@ async fn test_paragraphs_dont_wrap(cx: &mut gpui::TestAppContext) {
         two"})
         .await;
 }
+
+#[gpui::test]
+async fn test_select_all_issue_2170(cx: &mut gpui::TestAppContext) {
+    let mut cx = VimTestContext::new(cx, true).await;
+
+    cx.set_state(
+        indoc! {"
+        defmodule Test do
+            def test(a, ˇ[_, _] = b), do: IO.puts('hi')
+        end
+    "},
+        Mode::Normal,
+    );
+    cx.simulate_keystrokes(["g", "a"]);
+    cx.assert_state(
+        indoc! {"
+        defmodule Test do
+            def test(a, «[ˇ»_, _] = b), do: IO.puts('hi')
+        end
+    "},
+        Mode::Visual,
+    );
+}