diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 339b0354c3fc0859cfe791fd69336535645c14c8..6476002396c35bd25d419013833e37b96a6c0395 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -3028,6 +3028,10 @@ impl Editor { range.clone() } + pub fn clip_at_line_ends(&mut self, cx: &mut Context) -> bool { + self.display_map.read(cx).clip_at_line_ends + } + pub fn set_clip_at_line_ends(&mut self, clip: bool, cx: &mut Context) { if self.display_map.read(cx).clip_at_line_ends != clip { self.display_map diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index fae810d64c587f96c587057615b138b4baabd227..e53e2306d6f14b1c230ea383103bdf67fe8196c0 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -386,8 +386,6 @@ impl Vim { window: &mut Window, cx: &mut Context, ) { - let temp_mode_motion = motion.clone(); - match operator { None => self.move_cursor(motion, times, window, cx), Some(Operator::Change) => self.change_motion(motion, times, forced_motion, window, cx), @@ -477,7 +475,7 @@ impl Vim { } } // Exit temporary normal mode (if active). - self.exit_temporary_normal(Some(&temp_mode_motion), window, cx); + self.exit_temporary_normal(window, cx); } pub fn normal_object( @@ -580,8 +578,21 @@ impl Vim { window: &mut Window, cx: &mut Context, ) { - self.update_editor(cx, |_, editor, cx| { + self.update_editor(cx, |vim, editor, cx| { let text_layout_details = editor.text_layout_details(window); + + // If vim is in temporary mode and the motion being used is + // `EndOfLine` ($), we'll want to disable clipping at line ends so + // that the newline character can be selected so that, when moving + // back to visual mode, the cursor will be placed after the last + // character and not before it. + let clip_at_line_ends = editor.clip_at_line_ends(cx); + let should_disable_clip = matches!(motion, Motion::EndOfLine { .. }) && vim.temp_mode; + + if should_disable_clip { + editor.set_clip_at_line_ends(false, cx) + }; + editor.change_selections( SelectionEffects::default().nav_history(motion.push_to_jump_list()), window, @@ -593,7 +604,11 @@ impl Vim { .unwrap_or((cursor, goal)) }) }, - ) + ); + + if should_disable_clip { + editor.set_clip_at_line_ends(clip_at_line_ends, cx); + }; }); } @@ -1054,25 +1069,9 @@ impl Vim { }); } - /// If temporary mode is enabled, switches back to insert mode, using the - /// provided `motion` to determine whether to move the cursor before - /// re-enabling insert mode, for example, when `EndOfLine` ($) is used. - fn exit_temporary_normal( - &mut self, - motion: Option<&Motion>, - window: &mut Window, - cx: &mut Context, - ) { + fn exit_temporary_normal(&mut self, window: &mut Window, cx: &mut Context) { if self.temp_mode { self.switch_mode(Mode::Insert, true, window, cx); - - // Since we're switching from `Normal` mode to `Insert` mode, we'll - // move the cursor one position to the right, to ensure that, for - // motions like `EndOfLine` ($), the cursor is actually at the end - // of line and not on the last character. - if matches!(motion, Some(Motion::EndOfLine { .. })) { - self.move_cursor(Motion::Right, Some(1), window, cx); - } } } } diff --git a/crates/vim/src/normal/scroll.rs b/crates/vim/src/normal/scroll.rs index 9346d76323c4fb6c181fb914587a710c94be4537..ff884e3b7393b39b86114338fe2af11e384e1fa0 100644 --- a/crates/vim/src/normal/scroll.rs +++ b/crates/vim/src/normal/scroll.rs @@ -96,7 +96,7 @@ impl Vim { ) { let amount = by(Vim::take_count(cx).map(|c| c as f32)); Vim::take_forced_motion(cx); - self.exit_temporary_normal(None, window, cx); + self.exit_temporary_normal(window, cx); self.update_editor(cx, |_, editor, cx| { scroll_editor(editor, move_cursor, amount, window, cx) }); diff --git a/crates/vim/src/normal/yank.rs b/crates/vim/src/normal/yank.rs index 4f1274dd88359fe8c3eb1b08ab3910c513b2d98d..d5a45fca544d61735f62a8f46e849db2c009847f 100644 --- a/crates/vim/src/normal/yank.rs +++ b/crates/vim/src/normal/yank.rs @@ -59,7 +59,7 @@ impl Vim { }); }); }); - self.exit_temporary_normal(None, window, cx); + self.exit_temporary_normal(window, cx); } pub fn yank_object( @@ -90,7 +90,7 @@ impl Vim { }); }); }); - self.exit_temporary_normal(None, window, cx); + self.exit_temporary_normal(window, cx); } pub fn yank_selections_content(