editor: Don't overwrite primary selection with only empty cursors

With several cursors and nothing selected, the per-selection text joined
into a string of newlines, which passed the `!text.is_empty()` check and
replaced the primary selection on every keystroke and cursor move.

Only write to the primary selection when at least one selection is
non-empty.

Closes #64446
This commit is contained in:
dualfroz committed 2026-10-02 16:38:57 +02:00
1 parent 16ea2153b4
commit d4a2eeba66
2 files changed
+34 -1

No files matched your search

+31
View File
@@ -10996,6 +10996,37 @@ async fn test_copy_and_paste_non_empty_selection_followed_by_empty_selection(
"});
}
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
#[gpui::test]
async fn test_empty_cursors_do_not_overwrite_primary_selection(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
cx.update(|_, cx| cx.write_to_primary(ClipboardItem::new_string("primary".into())));
cx.set_state(indoc! {"
oneˇ
twoˇ
threeˇ
"});
assert_eq!(
cx.update(|_, cx| cx.read_from_primary())
.and_then(|item| item.text()),
Some("primary".to_string())
);
cx.set_state(indoc! {"
«oneˇ»
twoˇ
three
"});
assert_eq!(
cx.update(|_, cx| cx.read_from_primary())
.and_then(|item| item.text()),
Some("one\n".to_string())
);
}
#[gpui::test]
async fn test_copy_trim(cx: &mut TestAppContext) {
init_test(cx, |_| {});
+3 -1
View File
@@ -1562,7 +1562,9 @@ impl Editor {
}
}
if !text.is_empty() {
// Several empty cursors still join into a string of newlines, so
// check the selections themselves rather than the joined text.
if selections.iter().any(|selection| !selection.is_empty()) {
cx.write_to_primary(ClipboardItem::new_string(text));
}
}