Skip to content

Commit a83b36e

Browse files
committed
fix: ensure multi-selection with single-line copies do not have extra newlines between copied lines.
This change attempts to fix an edge-case with the multi-selection and full-line copy mechanics. Before this change, when someone used multi-selection (two cursors), and copied two lines (each with empty selections), then two full lines of content would be copied to the clipboard. However, there would an issue with too many newlines (two newlines) in-between the lines of content. After this change, now when someone does the same operation, the lines of content will only have a single newline between them.
1 parent b7cc597 commit a83b36e

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

crates/editor/src/editor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12479,7 +12479,7 @@ impl Editor {
1247912479
for trimmed_range in trimmed_selections {
1248012480
if is_first {
1248112481
is_first = false;
12482-
} else {
12482+
} else if !is_entire_line {
1248312483
text += "\n";
1248412484
}
1248512485
let mut len = 0;

crates/editor/src/editor_tests.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26922,6 +26922,43 @@ async fn test_copy_line_without_trailing_newline(cx: &mut TestAppContext) {
2692226922
cx.assert_editor_state("line1\nline2\nˇ");
2692326923
}
2692426924

26925+
#[gpui::test]
26926+
async fn test_multi_selection_copy_with_newline_between_copied_lines(cx: &mut TestAppContext) {
26927+
init_test(cx, |_| {});
26928+
26929+
let mut cx = EditorTestContext::new(cx).await;
26930+
26931+
cx.set_state("line1\nline2\nline3\nˇ");
26932+
26933+
cx.update_editor(|e, window, cx| {
26934+
e.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
26935+
s.select_display_ranges([
26936+
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
26937+
DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
26938+
DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0),
26939+
]);
26940+
});
26941+
});
26942+
26943+
cx.update_editor(|e, window, cx| e.copy(&Copy, window, cx));
26944+
26945+
let clipboard_text = cx
26946+
.read_from_clipboard()
26947+
.and_then(|item| item.text().as_deref().map(str::to_string));
26948+
26949+
assert_eq!(
26950+
clipboard_text,
26951+
Some("line1\nline2\nline3\n".to_string()),
26952+
"Copying multiple lines should include a single newline between lines"
26953+
);
26954+
26955+
cx.set_state("lineA\nˇ");
26956+
26957+
cx.update_editor(|e, window, cx| e.paste(&Paste, window, cx));
26958+
26959+
cx.assert_editor_state("lineA\nline1\nline2\nline3\nˇ");
26960+
}
26961+
2692526962
#[gpui::test]
2692626963
async fn test_end_of_editor_context(cx: &mut TestAppContext) {
2692726964
init_test(cx, |_| {});

0 commit comments

Comments
 (0)