diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b457e7fb2d..2691bc22ac 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6826,13 +6826,14 @@ impl Editor { .map(|(i, &row)| (row, i)) .collect(); - // Compute new line start offsets after rotation (handles CRLF) - let newline_len = line_ranges[1].start.0 - line_ranges[0].end.0; - let first_line_start = line_ranges[0].start.0; - let mut new_line_starts: Vec = vec![first_line_start]; - for text in line_texts.iter().take(num_rows - 1) { - let prev_start = *new_line_starts.last().unwrap(); - new_line_starts.push(prev_start + text.len() + newline_len); + let mut old_line_end = 0; + let mut new_line_end = 0; + let mut new_line_starts = Vec::new(); + for (range, text) in line_ranges.iter().zip(&line_texts) { + let line_start = new_line_end + (range.start.0 - old_line_end); + new_line_starts.push(line_start); + old_line_end = range.end.0; + new_line_end = line_start + text.len(); } let new_selections = selections diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index bb6c2c372f..1f1d483a5c 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -8623,6 +8623,40 @@ async fn test_rotate_selections(cx: &mut TestAppContext) { "}); } +#[gpui::test] +async fn test_rotate_selections_nonconsecutive_lines(cx: &mut TestAppContext) { + init_test(cx, |_| {}); + + let mut cx = EditorTestContext::new(cx).await; + + cx.set_state(indoc! {" + ˇline1 + line2 + liˇne3 + line4ˇ + "}); + + cx.update_editor(|e, window, cx| { + e.rotate_selections_forward(&RotateSelectionsForward, window, cx) + }); + cx.assert_editor_state(indoc! {" + line4ˇ + line2 + ˇline1 + liˇne3 + "}); + + cx.update_editor(|e, window, cx| { + e.rotate_selections_backward(&RotateSelectionsBackward, window, cx) + }); + cx.assert_editor_state(indoc! {" + ˇline1 + line2 + liˇne3 + line4ˇ + "}); +} + #[gpui::test] fn test_move_line_up_down(cx: &mut TestAppContext) { init_test(cx, |_| {});