diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ee501da679..e485b6f363 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -11834,6 +11834,7 @@ impl Editor { fn select_next_match_ranges( this: &mut Editor, range: Range, + reversed: bool, replace_newest: bool, auto_scroll: Option, window: &mut Window, @@ -11844,7 +11845,11 @@ impl Editor { if replace_newest { s.delete(s.newest_anchor().id); } - s.insert_range(range.clone()); + if reversed { + s.insert_range(range.end..range.start); + } else { + s.insert_range(range); + } }); } @@ -11895,6 +11900,7 @@ impl Editor { select_next_match_ranges( self, next_selected_range, + last_selection.reversed, replace_newest, autoscroll, window, @@ -11953,6 +11959,7 @@ impl Editor { select_next_match_ranges( self, selection.start..selection.end, + selection.reversed, replace_newest, autoscroll, window, @@ -12120,7 +12127,11 @@ impl Editor { if action.replace_newest { s.delete(s.newest_anchor().id); } - s.insert_range(next_selected_range); + if last_selection.reversed { + s.insert_range(next_selected_range.end..next_selected_range.start); + } else { + s.insert_range(next_selected_range); + } }); } else { select_prev_state.done = true; diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index b2bb08b72f..6de271a85c 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -5825,6 +5825,13 @@ async fn test_select_next(cx: &mut TestAppContext) { cx.update_editor(|e, window, cx| e.select_next(&SelectNext::default(), window, cx)) .unwrap(); cx.assert_editor_state("«abcˇ»\n«abcˇ» «abcˇ»\ndefabc\n«abcˇ»"); + + // Test selection direction should be preserved + cx.set_state("abc\n«ˇabc» abc\ndefabc\nabc"); + + cx.update_editor(|e, window, cx| e.select_next(&SelectNext::default(), window, cx)) + .unwrap(); + cx.assert_editor_state("abc\n«ˇabc» «ˇabc»\ndefabc\nabc"); } #[gpui::test] @@ -6011,6 +6018,25 @@ let «fooˇ» = 2; let foo = 2; let foo = «2ˇ»;"#, ); + + // Test last selection direction should be preserved + cx.set_state( + r#"let foo = 2; +let foo = 2; +let «fooˇ» = 2; +let «ˇfoo» = 2; +let foo = 2;"#, + ); + + cx.update_editor(|e, window, cx| e.select_next(&SelectNext::default(), window, cx)) + .unwrap(); + cx.assert_editor_state( + r#"let foo = 2; +let foo = 2; +let «fooˇ» = 2; +let «ˇfoo» = 2; +let «ˇfoo» = 2;"#, + ); } #[gpui::test] @@ -6138,25 +6164,26 @@ async fn test_select_previous_with_single_selection(cx: &mut TestAppContext) { cx.update_editor(|e, window, cx| e.select_previous(&SelectPrevious::default(), window, cx)) .unwrap(); - cx.assert_editor_state("«abcˇ»\n«ˇabc» abc\ndefabc\nabc"); + // selection direction is preserved + cx.assert_editor_state("«ˇabc»\n«ˇabc» abc\ndefabc\nabc"); cx.update_editor(|e, window, cx| e.select_previous(&SelectPrevious::default(), window, cx)) .unwrap(); - cx.assert_editor_state("«abcˇ»\n«ˇabc» abc\ndefabc\n«abcˇ»"); + cx.assert_editor_state("«ˇabc»\n«ˇabc» abc\ndefabc\n«ˇabc»"); cx.update_editor(|editor, window, cx| editor.undo_selection(&UndoSelection, window, cx)); - cx.assert_editor_state("«abcˇ»\n«ˇabc» abc\ndefabc\nabc"); + cx.assert_editor_state("«ˇabc»\n«ˇabc» abc\ndefabc\nabc"); cx.update_editor(|editor, window, cx| editor.redo_selection(&RedoSelection, window, cx)); - cx.assert_editor_state("«abcˇ»\n«ˇabc» abc\ndefabc\n«abcˇ»"); + cx.assert_editor_state("«ˇabc»\n«ˇabc» abc\ndefabc\n«ˇabc»"); cx.update_editor(|e, window, cx| e.select_previous(&SelectPrevious::default(), window, cx)) .unwrap(); - cx.assert_editor_state("«abcˇ»\n«ˇabc» abc\ndef«abcˇ»\n«abcˇ»"); + cx.assert_editor_state("«ˇabc»\n«ˇabc» abc\ndef«ˇabc»\n«ˇabc»"); cx.update_editor(|e, window, cx| e.select_previous(&SelectPrevious::default(), window, cx)) .unwrap(); - cx.assert_editor_state("«abcˇ»\n«ˇabc» «abcˇ»\ndef«abcˇ»\n«abcˇ»"); + cx.assert_editor_state("«ˇabc»\n«ˇabc» «ˇabc»\ndef«ˇabc»\n«ˇabc»"); } #[gpui::test]