vim: Add some forced motion support (#27991)
Closes https://github.com/zed-industries/zed/issues/20971 Added `v` input to yank and delete to override default motion. The global vim state tracking if the forced motion flag was passed handled the same way that the count is. [The main chunk of code maps the motion kind from the default to the overridden kind](https://github.com/zed-industries/zed/pull/27991/files#diff-2dca6b7d1673c912d14e4edc74e415abbe3a4e6d6b37e0e2006d30828bf4bb9cR1249-R1254). To handle the case of deleting a single character (dv0) at the start of a row I had to modify the control flow [here](https://github.com/zed-industries/zed/pull/27991/files#diff-2dca6b7d1673c912d14e4edc74e415abbe3a4e6d6b37e0e2006d30828bf4bb9cR1240-R1244). Then to handle an exclusive delete till the end of the row (dv$) I [saturated the endpoint with a left bias](https://github.com/zed-industries/zed/pull/27991/files#diff-2dca6b7d1673c912d14e4edc74e415abbe3a4e6d6b37e0e2006d30828bf4bb9cR1281-R1286). Test case: dv0 https://github.com/user-attachments/assets/613cf9fb-9732-425c-9179-025f3e107584 Test case: yvjp https://github.com/user-attachments/assets/550b7c77-1eb8-41c3-894b-117eb50b7a5d Release Notes: - Added some forced motion support for delete and yank
This commit is contained in:
parent
1df01eabfe
commit
08ce230bae
30 changed files with 485 additions and 58 deletions
|
@ -145,6 +145,7 @@ actions!(
|
|||
PushDeleteSurrounds,
|
||||
PushMark,
|
||||
ToggleMarksView,
|
||||
PushForcedMotion,
|
||||
PushIndent,
|
||||
PushOutdent,
|
||||
PushAutoIndent,
|
||||
|
@ -233,6 +234,7 @@ pub fn init(cx: &mut App) {
|
|||
|
||||
workspace.register_action(|workspace, _: &ResizePaneRight, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
Vim::take_forced_motion(cx);
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let Ok(font_id) = window.text_system().font_id(&theme.buffer_font) else {
|
||||
return;
|
||||
|
@ -248,6 +250,7 @@ pub fn init(cx: &mut App) {
|
|||
|
||||
workspace.register_action(|workspace, _: &ResizePaneLeft, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
Vim::take_forced_motion(cx);
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let Ok(font_id) = window.text_system().font_id(&theme.buffer_font) else {
|
||||
return;
|
||||
|
@ -263,6 +266,7 @@ pub fn init(cx: &mut App) {
|
|||
|
||||
workspace.register_action(|workspace, _: &ResizePaneUp, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
Vim::take_forced_motion(cx);
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
|
||||
workspace.resize_pane(Axis::Vertical, height * count, window, cx);
|
||||
|
@ -270,6 +274,7 @@ pub fn init(cx: &mut App) {
|
|||
|
||||
workspace.register_action(|workspace, _: &ResizePaneDown, window, cx| {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as f32;
|
||||
Vim::take_forced_motion(cx);
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
|
||||
workspace.resize_pane(Axis::Vertical, -height * count, window, cx);
|
||||
|
@ -472,7 +477,9 @@ impl Vim {
|
|||
vim.switch_mode(Mode::HelixNormal, false, window, cx)
|
||||
},
|
||||
);
|
||||
|
||||
Vim::action(editor, cx, |_, _: &PushForcedMotion, _, cx| {
|
||||
Vim::globals(cx).forced_motion = true;
|
||||
});
|
||||
Vim::action(editor, cx, |vim, action: &PushObject, window, cx| {
|
||||
vim.push_operator(
|
||||
Operator::Object {
|
||||
|
@ -907,6 +914,7 @@ impl Vim {
|
|||
self.current_tx.take();
|
||||
self.current_anchor.take();
|
||||
}
|
||||
Vim::take_forced_motion(cx);
|
||||
if mode != Mode::Insert && mode != Mode::Replace {
|
||||
Vim::take_count(cx);
|
||||
}
|
||||
|
@ -1011,6 +1019,13 @@ impl Vim {
|
|||
count
|
||||
}
|
||||
|
||||
pub fn take_forced_motion(cx: &mut App) -> bool {
|
||||
let global_state = cx.global_mut::<VimGlobals>();
|
||||
let forced_motion = global_state.forced_motion;
|
||||
global_state.forced_motion = false;
|
||||
forced_motion
|
||||
}
|
||||
|
||||
pub fn cursor_shape(&self, cx: &mut App) -> CursorShape {
|
||||
match self.mode {
|
||||
Mode::Normal => {
|
||||
|
@ -1372,6 +1387,7 @@ impl Vim {
|
|||
|
||||
fn clear_operator(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
Vim::take_count(cx);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.selected_register.take();
|
||||
self.operator_stack.clear();
|
||||
self.sync_vim_settings(window, cx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue