diff --git a/crates/vim2/src/command.rs b/crates/vim2/src/command.rs index d9a273179d..dcfc2a9737 100644 --- a/crates/vim2/src/command.rs +++ b/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.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 { diff --git a/crates/vim2/src/editor_events.rs b/crates/vim2/src/editor_events.rs index 6211bbe1e7..c16b3f16cf 100644 --- a/crates/vim2/src/editor_events.rs +++ b/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; diff --git a/crates/vim2/src/insert.rs b/crates/vim2/src/insert.rs index a9ca8087da..2e5cdd1f3b 100644 --- a/crates/vim2/src/insert.rs +++ b/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.register_action(normal_before); } fn normal_before(_: &mut Workspace, action: &NormalBefore, cx: &mut ViewContext) { diff --git a/crates/vim2/src/mode_indicator.rs b/crates/vim2/src/mode_indicator.rs index 9da542ec7e..ad644a383e 100644 --- a/crates/vim2/src/mode_indicator.rs +++ b/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, diff --git a/crates/vim2/src/motion.rs b/crates/vim2/src/motion.rs index 95c55e5d66..c7df0c3f2e 100644 --- a/crates/vim2/src/motion.rs +++ b/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, } -actions!( - Left, - Backspace, - Right, - CurrentLine, - StartOfParagraph, - EndOfParagraph, - StartOfDocument, - EndOfDocument, - Matching, - NextLineStart, - StartOfLineDownward, - EndOfLineDownward, - GoToColumn, +impl_actions!( + vim, + [ + RepeatFind, + StartOfLine, + EndOfLine, + FirstNonWhitespace, + Down, + Up, + PreviousWordStart, + NextWordEnd, + NextWordStart + ] ); -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)); +actions!( + vim, + [ + Left, + Backspace, + Right, + CurrentLine, + StartOfParagraph, + EndOfParagraph, + StartOfDocument, + EndOfDocument, + Matching, + NextLineStart, + StartOfLineDownward, + EndOfLineDownward, + GoToColumn, + ] +); - // 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.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) { diff --git a/crates/vim2/src/normal.rs b/crates/vim2/src/normal.rs index 64eecd00e5..13204bb6a0 100644 --- a/crates/vim2/src/normal.rs +++ b/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) { @@ -123,12 +126,12 @@ pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext) { + 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) { diff --git a/crates/vim2/src/normal/paste.rs b/crates/vim2/src/normal/paste.rs index 67bbfad2c1..6674338252 100644 --- a/crates/vim2/src/normal/paste.rs +++ b/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.register_action(paste); } fn paste(_: &mut Workspace, action: &Paste, cx: &mut ViewContext) { diff --git a/crates/vim2/src/normal/repeat.rs b/crates/vim2/src/normal/repeat.rs index 1187927eac..ec1913e0ae 100644 --- a/crates/vim2/src/normal/repeat.rs +++ b/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) -> bool { // skip so that we don't leave the character palette open @@ -39,16 +39,15 @@ fn repeatable_insert(action: &ReplayableAction) -> Option> { } } -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.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) { diff --git a/crates/vim2/src/normal/scroll.rs b/crates/vim2/src/normal/scroll.rs index 3bef78bc11..79204d7595 100644 --- a/crates/vim2/src/normal/scroll.rs +++ b/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,); +actions!( + vim, + [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) - // } - // }) - // }); +pub fn register(workspace: &mut Workspace, cx: &mut ViewContext) { + 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( diff --git a/crates/vim2/src/normal/search.rs b/crates/vim2/src/normal/search.rs index 79df67821c..2a7f82bf99 100644 --- a/crates/vim2/src/normal/search.rs +++ b/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); +actions!(vim, [SearchSubmit]); +impl_actions!( + vim, + [FindCommand, ReplaceCommand, Search, MoveToPrev, MoveToNext] +); -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); +pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext) { + 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); - // cx.add_action(find_command); - // cx.add_action(replace_command); + workspace.register_action(find_command); + workspace.register_action(replace_command); } fn move_to_next(workspace: &mut Workspace, action: &MoveToNext, cx: &mut ViewContext) { @@ -103,7 +106,7 @@ fn search(workspace: &mut Workspace, action: &Search, cx: &mut ViewContext find. -fn search_deploy(_: &mut Pane, _: &buffer_search::Deploy, cx: &mut ViewContext) { +fn search_deploy(_: &mut Workspace, _: &buffer_search::Deploy, cx: &mut ViewContext) { Vim::update(cx, |vim, _| vim.workspace_state.search = Default::default()); cx.propagate(); } diff --git a/crates/vim2/src/normal/substitute.rs b/crates/vim2/src/normal/substitute.rs index 22cecb176a..f623b499e0 100644 --- a/crates/vim2/src/normal/substitute.rs +++ b/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.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, line_mode: bool, cx: &mut WindowContext) { diff --git a/crates/vim2/src/object.rs b/crates/vim2/src/object.rs index 18fcaf0177..a43210ebb6 100644 --- a/crates/vim2/src/object.rs +++ b/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.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) { diff --git a/crates/vim2/src/vim.rs b/crates/vim2/src/vim.rs index e3b3a3c2be..008eeaf20f 100644 --- a/crates/vim2/src/vim.rs +++ b/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) { 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::(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::(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) { diff --git a/crates/vim2/src/visual.rs b/crates/vim2/src/visual.rs index 0daa7ed4c4..c0b1e03677 100644 --- a/crates/vim2/src/visual.rs +++ b/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| { - // toggle_mode(Mode::Visual, cx) - // }); - // cx.add_action(|_, _: &ToggleVisualLine, cx: &mut ViewContext| { - // toggle_mode(Mode::VisualLine, cx) - // }); - // cx.add_action( - // |_, _: &ToggleVisualBlock, cx: &mut ViewContext| { - // toggle_mode(Mode::VisualBlock, cx) - // }, - // ); - // cx.add_action(other_end); - // cx.add_action(delete); - // cx.add_action(yank); +pub fn register(workspace: &mut Workspace, cx: &mut ViewContext) { + workspace.register_action(|_, _: &ToggleVisual, cx: &mut ViewContext| { + toggle_mode(Mode::Visual, cx) + }); + workspace.register_action(|_, _: &ToggleVisualLine, cx: &mut ViewContext| { + toggle_mode(Mode::VisualLine, cx) + }); + workspace.register_action( + |_, _: &ToggleVisualBlock, cx: &mut ViewContext| { + toggle_mode(Mode::VisualBlock, cx) + }, + ); + workspace.register_action(other_end); + workspace.register_action(delete); + workspace.register_action(yank); - // cx.add_action(select_next); - // cx.add_action(select_previous); + 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, cx: &mut WindowContext) {