Revert actions! changes

Conrad Irwin created

Change summary

crates/vim2/src/command.rs           |  21 +-
crates/vim2/src/editor_events.rs     |   2 
crates/vim2/src/insert.rs            |   9 
crates/vim2/src/mode_indicator.rs    |   2 
crates/vim2/src/motion.rs            | 240 ++++++++++++++++-------------
crates/vim2/src/normal.rs            |  45 +++--
crates/vim2/src/normal/increment.rs  |  43 ++--
crates/vim2/src/normal/paste.rs      |  11 
crates/vim2/src/normal/repeat.rs     |  21 +-
crates/vim2/src/normal/scroll.rs     |  70 ++++----
crates/vim2/src/normal/search.rs     |  41 ++--
crates/vim2/src/normal/substitute.rs |  41 ++--
crates/vim2/src/object.rs            |  74 +++++---
crates/vim2/src/vim.rs               |  51 +++---
crates/vim2/src/visual.rs            |  60 ++++---
15 files changed, 393 insertions(+), 338 deletions(-)

Detailed changes

crates/vim2/src/command.rs 🔗

@@ -1,6 +1,6 @@
 use command_palette::CommandInterceptResult;
 use editor::{SortLinesCaseInsensitive, SortLinesCaseSensitive};
-use gpui::{Action, AppContext};
+use gpui::{impl_actions, Action, AppContext, ViewContext};
 use serde_derive::Deserialize;
 use workspace::{SaveIntent, Workspace};
 
@@ -15,19 +15,20 @@ use crate::{
     Vim,
 };
 
-#[derive(Action, Debug, Clone, PartialEq, Deserialize)]
+#[derive(Debug, Clone, PartialEq, Deserialize)]
 pub struct GoToLine {
     pub line: u32,
 }
 
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_: &mut Workspace, action: &GoToLine, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.switch_mode(Mode::Normal, false, cx);
-    //         move_cursor(vim, Motion::StartOfDocument, Some(action.line as usize), cx);
-    //     });
-    // });
+impl_actions!(vim, [GoToLine]);
+
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, action: &GoToLine, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.switch_mode(Mode::Normal, false, cx);
+            move_cursor(vim, Motion::StartOfDocument, Some(action.line as usize), cx);
+        });
+    });
 }
 
 pub fn command_interceptor(mut query: &str, _: &AppContext) -> Option<CommandInterceptResult> {

crates/vim2/src/editor_events.rs 🔗

@@ -1,4 +1,4 @@
-use crate::{Vim, VimEvent};
+use crate::Vim;
 use editor::{Editor, EditorBlurred, EditorEvent, EditorFocused, EditorReleased};
 use gpui::{AppContext, Entity, EntityId, View, ViewContext, WindowContext};
 use workspace::item::WeakItemHandle;

crates/vim2/src/insert.rs 🔗

@@ -1,14 +1,13 @@
 use crate::{normal::repeat, state::Mode, Vim};
 use editor::{scroll::autoscroll::Autoscroll, Bias};
-use gpui::{actions, Action, AppContext, ViewContext};
+use gpui::{actions, Action, ViewContext};
 use language::SelectionGoal;
 use workspace::Workspace;
 
-actions!(NormalBefore);
+actions!(vim, [NormalBefore]);
 
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(normal_before);
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(normal_before);
 }
 
 fn normal_before(_: &mut Workspace, action: &NormalBefore, cx: &mut ViewContext<Workspace>) {

crates/vim2/src/mode_indicator.rs 🔗

@@ -2,7 +2,7 @@ use gpui::{div, AnyElement, Div, Element, Entity, IntoElement, Render, Subscript
 use settings::{Settings, SettingsStore};
 use workspace::{item::ItemHandle, ui::Label, StatusItemView};
 
-use crate::{state::Mode, Vim, VimEvent, VimModeSetting};
+use crate::{state::Mode, Vim, VimModeSetting};
 
 pub struct ModeIndicator {
     pub mode: Option<Mode>,

crates/vim2/src/motion.rs 🔗

@@ -4,7 +4,7 @@ use editor::{
     movement::{self, find_boundary, find_preceding_boundary, FindRange, TextLayoutDetails},
     Bias, CharKind, DisplayPoint, ToOffset,
 };
-use gpui::{actions, px, Action, AppContext, WindowContext};
+use gpui::{actions, impl_actions, px, AppContext, ViewContext, WindowContext};
 use language::{Point, Selection, SelectionGoal};
 use serde::Deserialize;
 use workspace::Workspace;
@@ -43,168 +43,194 @@ pub enum Motion {
     GoToColumn,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct NextWordStart {
     #[serde(default)]
     ignore_punctuation: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct NextWordEnd {
     #[serde(default)]
     ignore_punctuation: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct PreviousWordStart {
     #[serde(default)]
     ignore_punctuation: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub(crate) struct Up {
     #[serde(default)]
     pub(crate) display_lines: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct Down {
     #[serde(default)]
     display_lines: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct FirstNonWhitespace {
     #[serde(default)]
     display_lines: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct EndOfLine {
     #[serde(default)]
     display_lines: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub struct StartOfLine {
     #[serde(default)]
     pub(crate) display_lines: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 struct RepeatFind {
     #[serde(default)]
     backwards: bool,
 }
 
+impl_actions!(
+    vim,
+    [
+        RepeatFind,
+        StartOfLine,
+        EndOfLine,
+        FirstNonWhitespace,
+        Down,
+        Up,
+        PreviousWordStart,
+        NextWordEnd,
+        NextWordStart
+    ]
+);
+
 actions!(
-    Left,
-    Backspace,
-    Right,
-    CurrentLine,
-    StartOfParagraph,
-    EndOfParagraph,
-    StartOfDocument,
-    EndOfDocument,
-    Matching,
-    NextLineStart,
-    StartOfLineDownward,
-    EndOfLineDownward,
-    GoToColumn,
+    vim,
+    [
+        Left,
+        Backspace,
+        Right,
+        CurrentLine,
+        StartOfParagraph,
+        EndOfParagraph,
+        StartOfDocument,
+        EndOfDocument,
+        Matching,
+        NextLineStart,
+        StartOfLineDownward,
+        EndOfLineDownward,
+        GoToColumn,
+    ]
 );
 
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_: &mut Workspace, _: &Left, cx: _| motion(Motion::Left, cx));
-    // cx.add_action(|_: &mut Workspace, _: &Backspace, cx: _| motion(Motion::Backspace, cx));
-    // cx.add_action(|_: &mut Workspace, action: &Down, cx: _| {
-    //     motion(
-    //         Motion::Down {
-    //             display_lines: action.display_lines,
-    //         },
-    //         cx,
-    //     )
-    // });
-    // cx.add_action(|_: &mut Workspace, action: &Up, cx: _| {
-    //     motion(
-    //         Motion::Up {
-    //             display_lines: action.display_lines,
-    //         },
-    //         cx,
-    //     )
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &Right, cx: _| motion(Motion::Right, cx));
-    // cx.add_action(|_: &mut Workspace, action: &FirstNonWhitespace, cx: _| {
-    //     motion(
-    //         Motion::FirstNonWhitespace {
-    //             display_lines: action.display_lines,
-    //         },
-    //         cx,
-    //     )
-    // });
-    // cx.add_action(|_: &mut Workspace, action: &StartOfLine, cx: _| {
-    //     motion(
-    //         Motion::StartOfLine {
-    //             display_lines: action.display_lines,
-    //         },
-    //         cx,
-    //     )
-    // });
-    // cx.add_action(|_: &mut Workspace, action: &EndOfLine, cx: _| {
-    //     motion(
-    //         Motion::EndOfLine {
-    //             display_lines: action.display_lines,
-    //         },
-    //         cx,
-    //     )
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &CurrentLine, cx: _| motion(Motion::CurrentLine, cx));
-    // cx.add_action(|_: &mut Workspace, _: &StartOfParagraph, cx: _| {
-    //     motion(Motion::StartOfParagraph, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &EndOfParagraph, cx: _| {
-    //     motion(Motion::EndOfParagraph, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &StartOfDocument, cx: _| {
-    //     motion(Motion::StartOfDocument, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &EndOfDocument, cx: _| motion(Motion::EndOfDocument, cx));
-    // cx.add_action(|_: &mut Workspace, _: &Matching, cx: _| motion(Motion::Matching, cx));
-
-    // cx.add_action(
-    //     |_: &mut Workspace, &NextWordStart { ignore_punctuation }: &NextWordStart, cx: _| {
-    //         motion(Motion::NextWordStart { ignore_punctuation }, cx)
-    //     },
-    // );
-    // cx.add_action(
-    //     |_: &mut Workspace, &NextWordEnd { ignore_punctuation }: &NextWordEnd, cx: _| {
-    //         motion(Motion::NextWordEnd { ignore_punctuation }, cx)
-    //     },
-    // );
-    // cx.add_action(
-    //     |_: &mut Workspace,
-    //      &PreviousWordStart { ignore_punctuation }: &PreviousWordStart,
-    //      cx: _| { motion(Motion::PreviousWordStart { ignore_punctuation }, cx) },
-    // );
-    // cx.add_action(|_: &mut Workspace, &NextLineStart, cx: _| motion(Motion::NextLineStart, cx));
-    // cx.add_action(|_: &mut Workspace, &StartOfLineDownward, cx: _| {
-    //     motion(Motion::StartOfLineDownward, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, &EndOfLineDownward, cx: _| {
-    //     motion(Motion::EndOfLineDownward, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, &GoToColumn, cx: _| motion(Motion::GoToColumn, cx));
-    // cx.add_action(|_: &mut Workspace, action: &RepeatFind, cx: _| {
-    //     repeat_motion(action.backwards, cx)
-    // })
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, _: &Left, cx: _| motion(Motion::Left, cx));
+    workspace
+        .register_action(|_: &mut Workspace, _: &Backspace, cx: _| motion(Motion::Backspace, cx));
+    workspace.register_action(|_: &mut Workspace, action: &Down, cx: _| {
+        motion(
+            Motion::Down {
+                display_lines: action.display_lines,
+            },
+            cx,
+        )
+    });
+    workspace.register_action(|_: &mut Workspace, action: &Up, cx: _| {
+        motion(
+            Motion::Up {
+                display_lines: action.display_lines,
+            },
+            cx,
+        )
+    });
+    workspace.register_action(|_: &mut Workspace, _: &Right, cx: _| motion(Motion::Right, cx));
+    workspace.register_action(|_: &mut Workspace, action: &FirstNonWhitespace, cx: _| {
+        motion(
+            Motion::FirstNonWhitespace {
+                display_lines: action.display_lines,
+            },
+            cx,
+        )
+    });
+    workspace.register_action(|_: &mut Workspace, action: &StartOfLine, cx: _| {
+        motion(
+            Motion::StartOfLine {
+                display_lines: action.display_lines,
+            },
+            cx,
+        )
+    });
+    workspace.register_action(|_: &mut Workspace, action: &EndOfLine, cx: _| {
+        motion(
+            Motion::EndOfLine {
+                display_lines: action.display_lines,
+            },
+            cx,
+        )
+    });
+    workspace.register_action(|_: &mut Workspace, _: &CurrentLine, cx: _| {
+        motion(Motion::CurrentLine, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &StartOfParagraph, cx: _| {
+        motion(Motion::StartOfParagraph, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &EndOfParagraph, cx: _| {
+        motion(Motion::EndOfParagraph, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &StartOfDocument, cx: _| {
+        motion(Motion::StartOfDocument, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &EndOfDocument, cx: _| {
+        motion(Motion::EndOfDocument, cx)
+    });
+    workspace
+        .register_action(|_: &mut Workspace, _: &Matching, cx: _| motion(Motion::Matching, cx));
+
+    workspace.register_action(
+        |_: &mut Workspace, &NextWordStart { ignore_punctuation }: &NextWordStart, cx: _| {
+            motion(Motion::NextWordStart { ignore_punctuation }, cx)
+        },
+    );
+    workspace.register_action(
+        |_: &mut Workspace, &NextWordEnd { ignore_punctuation }: &NextWordEnd, cx: _| {
+            motion(Motion::NextWordEnd { ignore_punctuation }, cx)
+        },
+    );
+    workspace.register_action(
+        |_: &mut Workspace,
+         &PreviousWordStart { ignore_punctuation }: &PreviousWordStart,
+         cx: _| { motion(Motion::PreviousWordStart { ignore_punctuation }, cx) },
+    );
+    workspace.register_action(|_: &mut Workspace, &NextLineStart, cx: _| {
+        motion(Motion::NextLineStart, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, &StartOfLineDownward, cx: _| {
+        motion(Motion::StartOfLineDownward, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, &EndOfLineDownward, cx: _| {
+        motion(Motion::EndOfLineDownward, cx)
+    });
+    workspace
+        .register_action(|_: &mut Workspace, &GoToColumn, cx: _| motion(Motion::GoToColumn, cx));
+    workspace.register_action(|_: &mut Workspace, action: &RepeatFind, cx: _| {
+        repeat_motion(action.backwards, cx)
+    });
 }
 
 pub(crate) fn motion(motion: Motion, cx: &mut WindowContext) {

crates/vim2/src/normal.rs 🔗

@@ -20,7 +20,7 @@ use crate::{
 use collections::HashSet;
 use editor::scroll::autoscroll::Autoscroll;
 use editor::{Bias, DisplayPoint};
-use gpui::{actions, AppContext, ViewContext, WindowContext};
+use gpui::{actions, ViewContext, WindowContext};
 use language::SelectionGoal;
 use log::error;
 use workspace::Workspace;
@@ -33,20 +33,23 @@ use self::{
 };
 
 actions!(
-    InsertAfter,
-    InsertBefore,
-    InsertFirstNonWhitespace,
-    InsertEndOfLine,
-    InsertLineAbove,
-    InsertLineBelow,
-    DeleteLeft,
-    DeleteRight,
-    ChangeToEndOfLine,
-    DeleteToEndOfLine,
-    Yank,
-    YankLine,
-    ChangeCase,
-    JoinLines,
+    vim,
+    [
+        InsertAfter,
+        InsertBefore,
+        InsertFirstNonWhitespace,
+        InsertEndOfLine,
+        InsertLineAbove,
+        InsertLineBelow,
+        DeleteLeft,
+        DeleteRight,
+        ChangeToEndOfLine,
+        DeleteToEndOfLine,
+        Yank,
+        YankLine,
+        ChangeCase,
+        JoinLines,
+    ]
 );
 
 pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
@@ -123,12 +126,12 @@ pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace
         });
     });
 
-    // paste::init(cx);
-    // repeat::init(cx);
-    // scroll::init(cx);
-    // search::init(cx);
-    // substitute::init(cx);
-    // increment::init(cx);
+    paste::register(workspace, cx);
+    repeat::register(workspace, cx);
+    scroll::register(workspace, cx);
+    search::register(workspace, cx);
+    substitute::register(workspace, cx);
+    increment::register(workspace, cx);
 }
 
 pub fn normal_motion(

crates/vim2/src/normal/increment.rs 🔗

@@ -1,45 +1,46 @@
 use std::ops::Range;
 
 use editor::{scroll::autoscroll::Autoscroll, MultiBufferSnapshot, ToOffset, ToPoint};
-use gpui::{Action, AppContext, WindowContext};
+use gpui::{impl_actions, AppContext, ViewContext, WindowContext};
 use language::{Bias, Point};
 use serde::Deserialize;
 use workspace::Workspace;
 
 use crate::{state::Mode, Vim};
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct Increment {
     #[serde(default)]
     step: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct Decrement {
     #[serde(default)]
     step: bool,
 }
 
-pub fn init(cx: &mut AppContext) {
-    // todo!();
-    // cx.add_action(|_: &mut Workspace, action: &Increment, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.record_current_action(cx);
-    //         let count = vim.take_count(cx).unwrap_or(1);
-    //         let step = if action.step { 1 } else { 0 };
-    //         increment(vim, count as i32, step, cx)
-    //     })
-    // });
-    // cx.add_action(|_: &mut Workspace, action: &Decrement, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.record_current_action(cx);
-    //         let count = vim.take_count(cx).unwrap_or(1);
-    //         let step = if action.step { -1 } else { 0 };
-    //         increment(vim, count as i32 * -1, step, cx)
-    //     })
-    // });
+impl_actions!(vim, [Increment, Decrement]);
+
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, action: &Increment, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.record_current_action(cx);
+            let count = vim.take_count(cx).unwrap_or(1);
+            let step = if action.step { 1 } else { 0 };
+            increment(vim, count as i32, step, cx)
+        })
+    });
+    workspace.register_action(|_: &mut Workspace, action: &Decrement, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.record_current_action(cx);
+            let count = vim.take_count(cx).unwrap_or(1);
+            let step = if action.step { -1 } else { 0 };
+            increment(vim, count as i32 * -1, step, cx)
+        })
+    });
 }
 
 fn increment(vim: &mut Vim, mut delta: i32, step: i32, cx: &mut WindowContext) {

crates/vim2/src/normal/paste.rs 🔗

@@ -4,14 +4,14 @@ use editor::{
     display_map::ToDisplayPoint, movement, scroll::autoscroll::Autoscroll, ClipboardSelection,
     DisplayPoint,
 };
-use gpui::{Action, AppContext, ViewContext};
+use gpui::{impl_actions, ViewContext};
 use language::{Bias, SelectionGoal};
 use serde::Deserialize;
 use workspace::Workspace;
 
 use crate::{state::Mode, utils::copy_selections_content, Vim};
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct Paste {
     #[serde(default)]
@@ -20,9 +20,10 @@ struct Paste {
     preserve_clipboard: bool,
 }
 
-pub(crate) fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(paste);
+impl_actions!(vim, [Paste]);
+
+pub(crate) fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
+    workspace.register_action(paste);
 }
 
 fn paste(_: &mut Workspace, action: &Paste, cx: &mut ViewContext<Workspace>) {

crates/vim2/src/normal/repeat.rs 🔗

@@ -5,10 +5,10 @@ use crate::{
     visual::visual_motion,
     Vim,
 };
-use gpui::{actions, Action, AppContext, WindowContext};
+use gpui::{actions, Action, AppContext, ViewContext, WindowContext};
 use workspace::Workspace;
 
-actions!(Repeat, EndRepeat);
+actions!(vim, [Repeat, EndRepeat]);
 
 fn should_replay(action: &Box<dyn Action>) -> bool {
     // skip so that we don't leave the character palette open
@@ -39,16 +39,15 @@ fn repeatable_insert(action: &ReplayableAction) -> Option<Box<dyn Action>> {
     }
 }
 
-pub(crate) fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_: &mut Workspace, _: &EndRepeat, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.workspace_state.replaying = false;
-    //         vim.switch_mode(Mode::Normal, false, cx)
-    //     });
-    // });
+pub(crate) fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, _: &EndRepeat, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.workspace_state.replaying = false;
+            vim.switch_mode(Mode::Normal, false, cx)
+        });
+    });
 
-    // cx.add_action(|_: &mut Workspace, _: &Repeat, cx| repeat(cx, false));
+    workspace.register_action(|_: &mut Workspace, _: &Repeat, cx| repeat(cx, false));
 }
 
 pub(crate) fn repeat(cx: &mut WindowContext, from_insert_mode: bool) {

crates/vim2/src/normal/scroll.rs 🔗

@@ -8,40 +8,42 @@ use gpui::{actions, AppContext, ViewContext};
 use language::Bias;
 use workspace::Workspace;
 
-actions!(LineUp, LineDown, ScrollUp, ScrollDown, PageUp, PageDown,);
-
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_: &mut Workspace, _: &LineDown, cx| {
-    //     scroll(cx, false, |c| ScrollAmount::Line(c.unwrap_or(1.)))
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &LineUp, cx| {
-    //     scroll(cx, false, |c| ScrollAmount::Line(-c.unwrap_or(1.)))
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &PageDown, cx| {
-    //     scroll(cx, false, |c| ScrollAmount::Page(c.unwrap_or(1.)))
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &PageUp, cx| {
-    //     scroll(cx, false, |c| ScrollAmount::Page(-c.unwrap_or(1.)))
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &ScrollDown, cx| {
-    //     scroll(cx, true, |c| {
-    //         if let Some(c) = c {
-    //             ScrollAmount::Line(c)
-    //         } else {
-    //             ScrollAmount::Page(0.5)
-    //         }
-    //     })
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &ScrollUp, cx| {
-    //     scroll(cx, true, |c| {
-    //         if let Some(c) = c {
-    //             ScrollAmount::Line(-c)
-    //         } else {
-    //             ScrollAmount::Page(-0.5)
-    //         }
-    //     })
-    // });
+actions!(
+    vim,
+    [LineUp, LineDown, ScrollUp, ScrollDown, PageUp, PageDown]
+);
+
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, _: &LineDown, cx| {
+        scroll(cx, false, |c| ScrollAmount::Line(c.unwrap_or(1.)))
+    });
+    workspace.register_action(|_: &mut Workspace, _: &LineUp, cx| {
+        scroll(cx, false, |c| ScrollAmount::Line(-c.unwrap_or(1.)))
+    });
+    workspace.register_action(|_: &mut Workspace, _: &PageDown, cx| {
+        scroll(cx, false, |c| ScrollAmount::Page(c.unwrap_or(1.)))
+    });
+    workspace.register_action(|_: &mut Workspace, _: &PageUp, cx| {
+        scroll(cx, false, |c| ScrollAmount::Page(-c.unwrap_or(1.)))
+    });
+    workspace.register_action(|_: &mut Workspace, _: &ScrollDown, cx| {
+        scroll(cx, true, |c| {
+            if let Some(c) = c {
+                ScrollAmount::Line(c)
+            } else {
+                ScrollAmount::Page(0.5)
+            }
+        })
+    });
+    workspace.register_action(|_: &mut Workspace, _: &ScrollUp, cx| {
+        scroll(cx, true, |c| {
+            if let Some(c) = c {
+                ScrollAmount::Line(-c)
+            } else {
+                ScrollAmount::Page(-0.5)
+            }
+        })
+    });
 }
 
 fn scroll(

crates/vim2/src/normal/search.rs 🔗

@@ -1,37 +1,37 @@
-use gpui::{actions, Action, AppContext, ViewContext};
+use gpui::{actions, impl_actions, Action, AppContext, ViewContext};
 use search::{buffer_search, BufferSearchBar, SearchMode, SearchOptions};
 use serde_derive::Deserialize;
 use workspace::{searchable::Direction, Pane, Workspace};
 
 use crate::{motion::Motion, normal::move_cursor, state::SearchState, Vim};
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub(crate) struct MoveToNext {
     #[serde(default)]
     partial_word: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 pub(crate) struct MoveToPrev {
     #[serde(default)]
     partial_word: bool,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub(crate) struct Search {
     #[serde(default)]
     backwards: bool,
 }
 
-#[derive(Action, Debug, Clone, PartialEq, Deserialize)]
+#[derive(Debug, Clone, PartialEq, Deserialize)]
 pub struct FindCommand {
     pub query: String,
     pub backwards: bool,
 }
 
-#[derive(Action, Debug, Clone, PartialEq, Deserialize)]
+#[derive(Debug, Clone, PartialEq, Deserialize)]
 pub struct ReplaceCommand {
     pub query: String,
 }
@@ -44,18 +44,21 @@ struct Replacement {
     is_case_sensitive: bool,
 }
 
-actions!(SearchSubmit);
-
-pub(crate) fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(move_to_next);
-    // cx.add_action(move_to_prev);
-    // cx.add_action(search);
-    // cx.add_action(search_submit);
-    // cx.add_action(search_deploy);
-
-    // cx.add_action(find_command);
-    // cx.add_action(replace_command);
+actions!(vim, [SearchSubmit]);
+impl_actions!(
+    vim,
+    [FindCommand, ReplaceCommand, Search, MoveToPrev, MoveToNext]
+);
+
+pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(move_to_next);
+    workspace.register_action(move_to_prev);
+    workspace.register_action(search);
+    workspace.register_action(search_submit);
+    workspace.register_action(search_deploy);
+
+    workspace.register_action(find_command);
+    workspace.register_action(replace_command);
 }
 
 fn move_to_next(workspace: &mut Workspace, action: &MoveToNext, cx: &mut ViewContext<Workspace>) {
@@ -103,7 +106,7 @@ fn search(workspace: &mut Workspace, action: &Search, cx: &mut ViewContext<Works
 }
 
 // hook into the existing to clear out any vim search state on cmd+f or edit -> find.
-fn search_deploy(_: &mut Pane, _: &buffer_search::Deploy, cx: &mut ViewContext<Pane>) {
+fn search_deploy(_: &mut Workspace, _: &buffer_search::Deploy, cx: &mut ViewContext<Workspace>) {
     Vim::update(cx, |vim, _| vim.workspace_state.search = Default::default());
     cx.propagate();
 }

crates/vim2/src/normal/substitute.rs 🔗

@@ -1,32 +1,31 @@
 use editor::movement;
-use gpui::{actions, AppContext, WindowContext};
+use gpui::{actions, ViewContext, WindowContext};
 use language::Point;
 use workspace::Workspace;
 
 use crate::{motion::Motion, utils::copy_selections_content, Mode, Vim};
 
-actions!(Substitute, SubstituteLine);
+actions!(vim, [Substitute, SubstituteLine]);
 
-pub(crate) fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_: &mut Workspace, _: &Substitute, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.start_recording(cx);
-    //         let count = vim.take_count(cx);
-    //         substitute(vim, count, vim.state().mode == Mode::VisualLine, cx);
-    //     })
-    // });
+pub(crate) fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_: &mut Workspace, _: &Substitute, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.start_recording(cx);
+            let count = vim.take_count(cx);
+            substitute(vim, count, vim.state().mode == Mode::VisualLine, cx);
+        })
+    });
 
-    // cx.add_action(|_: &mut Workspace, _: &SubstituteLine, cx| {
-    //     Vim::update(cx, |vim, cx| {
-    //         vim.start_recording(cx);
-    //         if matches!(vim.state().mode, Mode::VisualBlock | Mode::Visual) {
-    //             vim.switch_mode(Mode::VisualLine, false, cx)
-    //         }
-    //         let count = vim.take_count(cx);
-    //         substitute(vim, count, true, cx)
-    //     })
-    // });
+    workspace.register_action(|_: &mut Workspace, _: &SubstituteLine, cx| {
+        Vim::update(cx, |vim, cx| {
+            vim.start_recording(cx);
+            if matches!(vim.state().mode, Mode::VisualBlock | Mode::Visual) {
+                vim.switch_mode(Mode::VisualLine, false, cx)
+            }
+            let count = vim.take_count(cx);
+            substitute(vim, count, true, cx)
+        })
+    });
 }
 
 pub fn substitute(vim: &mut Vim, count: Option<usize>, line_mode: bool, cx: &mut WindowContext) {

crates/vim2/src/object.rs 🔗

@@ -6,7 +6,7 @@ use editor::{
     movement::{self, FindRange},
     Bias, CharKind, DisplayPoint,
 };
-use gpui::{actions, Action, AppContext, WindowContext};
+use gpui::{actions, impl_actions, Action, AppContext, ViewContext, WindowContext};
 use language::Selection;
 use serde::Deserialize;
 use workspace::Workspace;
@@ -27,43 +27,59 @@ pub enum Object {
     AngleBrackets,
 }
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 #[serde(rename_all = "camelCase")]
 struct Word {
     #[serde(default)]
     ignore_punctuation: bool,
 }
 
+impl_actions!(vim, [Word]);
+
 actions!(
-    Sentence,
-    Quotes,
-    BackQuotes,
-    DoubleQuotes,
-    VerticalBars,
-    Parentheses,
-    SquareBrackets,
-    CurlyBrackets,
-    AngleBrackets
+    vim,
+    [
+        Sentence,
+        Quotes,
+        BackQuotes,
+        DoubleQuotes,
+        VerticalBars,
+        Parentheses,
+        SquareBrackets,
+        CurlyBrackets,
+        AngleBrackets
+    ]
 );
 
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(
-    //     |_: &mut Workspace, &Word { ignore_punctuation }: &Word, cx: _| {
-    //         object(Object::Word { ignore_punctuation }, cx)
-    //     },
-    // );
-    // cx.add_action(|_: &mut Workspace, _: &Sentence, cx: _| object(Object::Sentence, cx));
-    // cx.add_action(|_: &mut Workspace, _: &Quotes, cx: _| object(Object::Quotes, cx));
-    // cx.add_action(|_: &mut Workspace, _: &BackQuotes, cx: _| object(Object::BackQuotes, cx));
-    // cx.add_action(|_: &mut Workspace, _: &DoubleQuotes, cx: _| object(Object::DoubleQuotes, cx));
-    // cx.add_action(|_: &mut Workspace, _: &Parentheses, cx: _| object(Object::Parentheses, cx));
-    // cx.add_action(|_: &mut Workspace, _: &SquareBrackets, cx: _| {
-    //     object(Object::SquareBrackets, cx)
-    // });
-    // cx.add_action(|_: &mut Workspace, _: &CurlyBrackets, cx: _| object(Object::CurlyBrackets, cx));
-    // cx.add_action(|_: &mut Workspace, _: &AngleBrackets, cx: _| object(Object::AngleBrackets, cx));
-    // cx.add_action(|_: &mut Workspace, _: &VerticalBars, cx: _| object(Object::VerticalBars, cx));
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(
+        |_: &mut Workspace, &Word { ignore_punctuation }: &Word, cx: _| {
+            object(Object::Word { ignore_punctuation }, cx)
+        },
+    );
+    workspace
+        .register_action(|_: &mut Workspace, _: &Sentence, cx: _| object(Object::Sentence, cx));
+    workspace.register_action(|_: &mut Workspace, _: &Quotes, cx: _| object(Object::Quotes, cx));
+    workspace
+        .register_action(|_: &mut Workspace, _: &BackQuotes, cx: _| object(Object::BackQuotes, cx));
+    workspace.register_action(|_: &mut Workspace, _: &DoubleQuotes, cx: _| {
+        object(Object::DoubleQuotes, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &Parentheses, cx: _| {
+        object(Object::Parentheses, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &SquareBrackets, cx: _| {
+        object(Object::SquareBrackets, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &CurlyBrackets, cx: _| {
+        object(Object::CurlyBrackets, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &AngleBrackets, cx: _| {
+        object(Object::AngleBrackets, cx)
+    });
+    workspace.register_action(|_: &mut Workspace, _: &VerticalBars, cx: _| {
+        object(Object::VerticalBars, cx)
+    });
 }
 
 fn object(object: Object, cx: &mut WindowContext) {

crates/vim2/src/vim.rs 🔗

@@ -17,8 +17,8 @@ use collections::{CommandPaletteFilter, HashMap};
 use command_palette::CommandPaletteInterceptor;
 use editor::{movement, Editor, EditorEvent, EditorMode};
 use gpui::{
-    actions, Action, AppContext, EntityId, KeyContext, Subscription, View, ViewContext, WeakModel,
-    WeakView, WindowContext,
+    actions, impl_actions, Action, AppContext, EntityId, KeyContext, Subscription, View,
+    ViewContext, WeakModel, WeakView, WindowContext,
 };
 use language::{CursorShape, Point, Selection, SelectionGoal};
 pub use mode_indicator::ModeIndicator;
@@ -35,21 +35,23 @@ use crate::state::ReplayableAction;
 
 pub struct VimModeSetting(pub bool);
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct SwitchMode(pub Mode);
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct PushOperator(pub Operator);
 
-#[derive(Action, Clone, Deserialize, PartialEq)]
+#[derive(Clone, Deserialize, PartialEq)]
 struct Number(usize);
 
-actions!(Tab, Enter, Object, InnerObject, FindForward, FindBackward,);
+actions!(
+    vim,
+    [Tab, Enter, Object, InnerObject, FindForward, FindBackward]
+);
+// in the workspace namespace so it's not filtered out when vim is disabled.
+actions!(workspace, [ToggleVimMode]);
 
-#[derive(Copy, Clone, Debug)]
-enum VimEvent {
-    ModeChanged { mode: Mode },
-}
+impl_actions!(vim, [SwitchMode, PushOperator, Number]);
 
 pub fn init(cx: &mut AppContext) {
     cx.set_global(Vim::default());
@@ -60,12 +62,6 @@ pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(|workspace: &mut Workspace, cx| register(workspace, cx))
         .detach();
 
-    visual::init(cx);
-    insert::init(cx);
-    object::init(cx);
-    motion::init(cx);
-    command::init(cx);
-
     // Any time settings change, update vim mode to match. The Vim struct
     // will be initialized as disabled by default, so we filter its commands
     // out when starting up.
@@ -104,17 +100,20 @@ fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
         Vim::active_editor_input_ignored("\n".into(), cx)
     });
 
-    workspace.register_action(
-        |workspace: &mut Workspace, _: &workspace::ToggleVimMode, cx| {
-            let fs = workspace.app_state().fs.clone();
-            let currently_enabled = VimModeSetting::get_global(cx).0;
-            update_settings_file::<VimModeSetting>(fs, cx, move |setting| {
-                *setting = Some(!currently_enabled)
-            })
-        },
-    );
+    workspace.register_action(|workspace: &mut Workspace, _: &ToggleVimMode, cx| {
+        let fs = workspace.app_state().fs.clone();
+        let currently_enabled = VimModeSetting::get_global(cx).0;
+        update_settings_file::<VimModeSetting>(fs, cx, move |setting| {
+            *setting = Some(!currently_enabled)
+        })
+    });
 
-    normal::register(workspace, cx)
+    normal::register(workspace, cx);
+    insert::register(workspace, cx);
+    motion::register(workspace, cx);
+    command::register(workspace, cx);
+    object::register(workspace, cx);
+    visual::register(workspace, cx);
 }
 
 pub fn observe_keystrokes(cx: &mut WindowContext) {

crates/vim2/src/visual.rs 🔗

@@ -21,35 +21,41 @@ use crate::{
 };
 
 actions!(
-    ToggleVisual,
-    ToggleVisualLine,
-    ToggleVisualBlock,
-    VisualDelete,
-    VisualYank,
-    OtherEnd,
-    SelectNext,
-    SelectPrevious,
+    vim,
+    [
+        ToggleVisual,
+        ToggleVisualLine,
+        ToggleVisualBlock,
+        VisualDelete,
+        VisualYank,
+        OtherEnd,
+        SelectNext,
+        SelectPrevious,
+    ]
 );
 
-pub fn init(cx: &mut AppContext) {
-    // todo!()
-    // cx.add_action(|_, _: &ToggleVisual, cx: &mut ViewContext<Workspace>| {
-    //     toggle_mode(Mode::Visual, cx)
-    // });
-    // cx.add_action(|_, _: &ToggleVisualLine, cx: &mut ViewContext<Workspace>| {
-    //     toggle_mode(Mode::VisualLine, cx)
-    // });
-    // cx.add_action(
-    //     |_, _: &ToggleVisualBlock, cx: &mut ViewContext<Workspace>| {
-    //         toggle_mode(Mode::VisualBlock, cx)
-    //     },
-    // );
-    // cx.add_action(other_end);
-    // cx.add_action(delete);
-    // cx.add_action(yank);
-
-    // cx.add_action(select_next);
-    // cx.add_action(select_previous);
+pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
+    workspace.register_action(|_, _: &ToggleVisual, cx: &mut ViewContext<Workspace>| {
+        toggle_mode(Mode::Visual, cx)
+    });
+    workspace.register_action(|_, _: &ToggleVisualLine, cx: &mut ViewContext<Workspace>| {
+        toggle_mode(Mode::VisualLine, cx)
+    });
+    workspace.register_action(
+        |_, _: &ToggleVisualBlock, cx: &mut ViewContext<Workspace>| {
+            toggle_mode(Mode::VisualBlock, cx)
+        },
+    );
+    workspace.register_action(other_end);
+    workspace.register_action(delete);
+    workspace.register_action(yank);
+
+    workspace.register_action(|workspace, action, cx| {
+        select_next(workspace, action, cx).ok();
+    });
+    workspace.register_action(|workspace, action, cx| {
+        select_previous(workspace, action, cx).ok();
+    });
 }
 
 pub fn visual_motion(motion: Motion, times: Option<usize>, cx: &mut WindowContext) {