From dcca98b5ccafd88a6a7a919b2b7ebb0faf2921e7 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 21 Jun 2023 15:05:54 -0600 Subject: [PATCH] vim: Add basic 's' support --- assets/keymaps/vim.json | 3 ++- crates/vim/src/normal.rs | 26 ++++++++++++++++++++++++++ crates/vim/src/test.rs | 10 ++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 47c5f8c458..389efcdd0b 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -214,7 +214,8 @@ "r": [ "vim::PushOperator", "Replace" - ] + ], + "s": "vim::Substitute" } }, { diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 1f90d259d3..c72fffbc21 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -45,6 +45,7 @@ actions!( DeleteToEndOfLine, Paste, Yank, + Substitute, ] ); @@ -56,6 +57,12 @@ pub fn init(cx: &mut AppContext) { cx.add_action(insert_end_of_line); cx.add_action(insert_line_above); cx.add_action(insert_line_below); + cx.add_action(|_: &mut Workspace, _: &Substitute, cx| { + Vim::update(cx, |vim, cx| { + let times = vim.pop_number_operator(cx); + substitute(vim, times, cx); + }) + }); cx.add_action(|_: &mut Workspace, _: &DeleteLeft, cx| { Vim::update(cx, |vim, cx| { let times = vim.pop_number_operator(cx); @@ -471,6 +478,25 @@ pub(crate) fn normal_replace(text: Arc, cx: &mut WindowContext) { }); } +pub fn substitute(vim: &mut Vim, count: usize, cx: &mut WindowContext) { + vim.update_active_editor(cx, |editor, cx| { + editor.transact(cx, |editor, cx| { + let selection = editor.selections.newest::(cx); + + let end = if selection.start == selection.end { + selection.start + Point::new(0, 1) + } else { + selection.end + }; + + editor.buffer().update(cx, |buffer, cx| { + buffer.edit([(selection.start..end, "")], None, cx) + }) + }) + }); + vim.switch_mode(Mode::Insert, true, cx) +} + #[cfg(test)] mod test { use gpui::TestAppContext; diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index 0214806e11..ec8998adc9 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -98,3 +98,13 @@ async fn test_buffer_search(cx: &mut gpui::TestAppContext) { assert_eq!(bar.query_editor.read(cx).text(cx), "jumps"); }) } + + +#[gpui::test] +async fn test_substitute(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true).await; + + cx.set_state(indoc! {"ˇabc\n"}, Mode::Normal); + cx.simulate_keystrokes(["s", "x"]); + cx.assert_editor_state("xˇbc\n"); +}