From 2f2f236afe1547b4a73b271f0fd65aacb2eace41 Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 28 Mar 2024 14:01:00 +0800 Subject: [PATCH] vim: Make `cc` and `S` auto-indent (#9731) Fix #9612 Release notes: * Changed `cc` and `S` in Vim mode to only change the current line after its indentation. #9612 --- crates/vim/src/normal/change.rs | 54 +++++++++++++++++++++++- crates/vim/test_data/test_change_cc.json | 12 ++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 crates/vim/test_data/test_change_cc.json diff --git a/crates/vim/src/normal/change.rs b/crates/vim/src/normal/change.rs index dd7d6d2652ca4cf2fc7e678125a05e902b0446f5..7d9d6aa3a28dba6e548234e517b39e8a4d9f3eac 100644 --- a/crates/vim/src/normal/change.rs +++ b/crates/vim/src/normal/change.rs @@ -48,7 +48,25 @@ pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option, cx: &m true, ) } else { - motion.expand_selection(map, selection, times, false, &text_layout_details) + let result = motion.expand_selection( + map, + selection, + times, + false, + &text_layout_details, + ); + if let Motion::CurrentLine = motion { + let scope = map + .buffer_snapshot + .language_scope_at(selection.start.to_point(&map)); + for (ch, _) in map.chars_at(selection.start) { + if ch == '\n' || char_kind(&scope, ch) != CharKind::Whitespace { + break; + } + *selection.start.column_mut() += 1; + } + } + result }; }); }); @@ -398,6 +416,40 @@ mod test { .await; } + #[gpui::test] + async fn test_change_cc(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + cx.assert_neovim_compatible( + indoc! {" + The quick + brownˇ fox + jumps over + the lazy"}, + ["c", "c"], + ) + .await; + + cx.assert_neovim_compatible( + indoc! {" + ˇThe quick + brown fox + jumps over + the lazy"}, + ["c", "c"], + ) + .await; + + cx.assert_neovim_compatible( + indoc! {" + The quick + broˇwn fox + jumˇps over + the lazy"}, + ["c", "c"], + ) + .await; + } + #[gpui::test] async fn test_change_gg(cx: &mut gpui::TestAppContext) { let mut cx = NeovimBackedTestContext::new(cx).await; diff --git a/crates/vim/test_data/test_change_cc.json b/crates/vim/test_data/test_change_cc.json new file mode 100644 index 0000000000000000000000000000000000000000..a4429de026b0ba2861d6cae2d0f717ed28736b6b --- /dev/null +++ b/crates/vim/test_data/test_change_cc.json @@ -0,0 +1,12 @@ +{"Put":{"state":"The quick\n brownˇ fox\njumps over\nthe lazy"}} +{"Key":"c"} +{"Key":"c"} +{"Get":{"state":"The quick\n ˇ\njumps over\nthe lazy","mode":"Insert"}} +{"Put":{"state":"ˇThe quick\nbrown fox\njumps over\nthe lazy"}} +{"Key":"c"} +{"Key":"c"} +{"Get":{"state":"ˇ\nbrown fox\njumps over\nthe lazy","mode":"Insert"}} +{"Put":{"state":"The quick\n broˇwn fox\njumˇps over\nthe lazy"}} +{"Key":"c"} +{"Key":"c"} +{"Get":{"state":"The quick\n ˇ\nˇ\nthe lazy","mode":"Insert"}}