diff --git a/crates/vim/src/helix.rs b/crates/vim/src/helix.rs index e173f28820..040d60cfae 100644 --- a/crates/vim/src/helix.rs +++ b/crates/vim/src/helix.rs @@ -2829,6 +2829,10 @@ mod test { ˇ»line five"}, Mode::HelixNormal, ); + + cx.set_state("oneˇ\ntwo\nthree", Mode::HelixNormal); + cx.simulate_keystrokes("d u x"); + cx.assert_state("«one\nˇ»two\nthree", Mode::HelixNormal); } #[gpui::test] diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index e2ce1fb128..027324bfab 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -146,6 +146,8 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context) { Vim::action(editor, cx, |vim, _: &HelixDelete, window, cx| { vim.record_current_action(cx); + let original_selections = + vim.update_editor(cx, |_, editor, _| editor.selections.disjoint_anchors_arc()); vim.update_editor(cx, |_, editor, cx| { editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { s.move_with(&mut |map, selection| { @@ -155,7 +157,17 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context) { }) }) }); - vim.visual_delete(false, window, cx); + let transaction_id = vim.visual_delete(false, window, cx); + if let (Some(original_selections), Some(transaction_id)) = + (original_selections, transaction_id) + { + let updated = vim.update_editor(cx, |_, editor, _| { + editor.modify_transaction_selection_history(transaction_id, |selections| { + selections.0 = original_selections; + }) + }); + debug_assert_ne!(updated, Some(false)); + } vim.switch_mode(Mode::HelixNormal, true, window, cx); }); diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 077e098bb3..e715e98a65 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -10,6 +10,7 @@ use gpui::{Context, Window, actions}; use language::{Point, Selection, SelectionGoal}; use multi_buffer::MultiBufferRow; use search::BufferSearchBar; +use text::TransactionId; use util::ResultExt; use workspace::searchable::Direction; @@ -625,9 +626,14 @@ impl Vim { }); } - pub fn visual_delete(&mut self, line_mode: bool, window: &mut Window, cx: &mut Context) { + pub fn visual_delete( + &mut self, + line_mode: bool, + window: &mut Window, + cx: &mut Context, + ) -> Option { self.store_visual_marks(window, cx); - self.update_editor(cx, |vim, editor, cx| { + let transaction_id = self.update_editor(cx, |vim, editor, cx| { let mut original_columns: HashMap<_, _> = Default::default(); let line_mode = line_mode || editor.selections.line_mode(); editor.selections.set_line_mode(false); @@ -707,7 +713,9 @@ impl Vim { }); }) }); + let transaction_id = transaction_id.flatten(); self.switch_mode(Mode::Normal, true, window, cx); + transaction_id } pub fn visual_yank(&mut self, line_mode: bool, window: &mut Window, cx: &mut Context) { @@ -928,7 +936,7 @@ impl Vim { Some(Operator::Change) => self.substitute(None, false, window, cx), Some(Operator::Delete) => { self.stop_recording(cx); - self.visual_delete(false, window, cx) + self.visual_delete(false, window, cx); } Some(Operator::Yank) => self.visual_yank(false, window, cx), _ => {} // Ignoring other operators