diff --git a/crates/vim/src/normal/paste.rs b/crates/vim/src/normal/paste.rs index fab9b353e3e9bb5b5d00d9d415783b4a5a31ae95..f3df2ce1c07d94619933a03cf5989022daedd4de 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -25,7 +25,7 @@ pub struct Paste { #[serde(default)] before: bool, #[serde(default)] - preserve_clipboard: bool, + pub(crate) preserve_clipboard: bool, } impl Vim { @@ -835,6 +835,41 @@ mod test { ); } + #[gpui::test] + async fn test_editor_paste_visual_preserves_system_clipboard(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true).await; + + cx.set_state( + indoc! {" + The quick brown + fox ˇjumps over + the lazy dog"}, + Mode::Normal, + ); + + // Put known content on the system clipboard + cx.write_to_clipboard(ClipboardItem::new_string("from clipboard".to_string())); + + // Select "jumps" in visual mode, then editor::Paste (Cmd-V / Ctrl-V) + cx.simulate_keystrokes("v i w"); + cx.dispatch_action(editor::actions::Paste); + + // The selected text should be replaced with clipboard content + cx.assert_state( + indoc! {" + The quick brown + fox from clipboarˇd over + the lazy dog"}, + Mode::Normal, + ); + + // System clipboard must still hold the original value, not "jumps" + assert_eq!( + cx.read_from_clipboard().map(|item| item.text().unwrap()), + Some("from clipboard".into()), + ); + } + #[gpui::test] async fn test_numbered_registers(cx: &mut gpui::TestAppContext) { let mut cx = NeovimBackedTestContext::new(cx).await; diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 987def8a1ce63ffc0cf58dd63e4a1eb3cd4ddb60..d9617d34ecfaba5dd64a76c75ca379e5a08b0717 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -965,7 +965,9 @@ impl Vim { Mode::Replace => vim.paste_replace(window, cx), Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { vim.selected_register.replace('+'); - vim.paste(&VimPaste::default(), window, cx); + let mut action = VimPaste::default(); + action.preserve_clipboard = true; + vim.paste(&action, window, cx); } _ => { vim.update_editor(cx, |_, editor, cx| editor.paste(&Paste, window, cx));