diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index e8bf95061c..36b4261fac 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -140,7 +140,8 @@ "c": "vim::VisualChange", "d": "vim::VisualDelete", "x": "vim::VisualDelete", - "y": "vim::VisualYank" + "y": "vim::VisualYank", + "p": "vim::Paste" } }, { diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index 1d02b26e4b..026144db64 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -149,6 +149,28 @@ impl SelectionsCollection { selections } + pub fn all_adjusted_display( + &self, + cx: &mut MutableAppContext, + ) -> (DisplaySnapshot, Vec>) { + if self.line_mode { + let selections = self.all::(cx); + let map = self.display_map(cx); + let result = selections + .into_iter() + .map(|mut selection| { + let new_range = map.expand_to_line(selection.range()); + selection.start = new_range.start; + selection.end = new_range.end; + selection.map(|point| point.to_display_point(&map)) + }) + .collect(); + (map, result) + } else { + self.all_display(cx) + } + } + pub fn disjoint_in_range<'a, D>( &self, range: Range, @@ -175,7 +197,7 @@ impl SelectionsCollection { } pub fn all_display( - &mut self, + &self, cx: &mut MutableAppContext, ) -> (DisplaySnapshot, Vec>) { let display_map = self.display_map(cx); diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 4c6dfd2d60..9dd2274792 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -7,6 +7,7 @@ use std::borrow::Cow; use crate::{ motion::Motion, state::{Mode, Operator}, + utils::copy_selections_content, Vim, }; use change::init as change_init; @@ -200,11 +201,12 @@ fn paste(_: &mut Workspace, _: &Paste, cx: &mut ViewContext) { vim.update_active_editor(cx, |editor, cx| { editor.transact(cx, |editor, cx| { if let Some(item) = cx.as_mut().read_from_clipboard() { + copy_selections_content(editor, editor.selections.line_mode, cx); let mut clipboard_text = Cow::Borrowed(item.text()); if let Some(mut clipboard_selections) = item.metadata::>() { - let (display_map, selections) = editor.selections.all_display(cx); + let (display_map, selections) = editor.selections.all_adjusted_display(cx); let all_selections_were_entire_line = clipboard_selections.iter().all(|s| s.is_entire_line); if clipboard_selections.len() != selections.len() { diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 3020db5e4c..203477198f 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -6,7 +6,7 @@ use workspace::Workspace; use crate::{motion::Motion, state::Mode, utils::copy_selections_content, Vim}; -actions!(vim, [VisualDelete, VisualChange, VisualYank]); +actions!(vim, [VisualDelete, VisualChange, VisualYank, VisualPaste]); pub fn init(cx: &mut MutableAppContext) { cx.add_action(change);