From b04f7a4c7c4ddd86b392e3b111383e214be6599a Mon Sep 17 00:00:00 2001 From: 0x2CA <2478557459@qq.com> Date: Tue, 8 Apr 2025 22:51:41 +0800 Subject: [PATCH] vim: Fix visual object expands (#28301) Closes #28198 Release Notes: - Fixed visual object expands --- crates/vim/src/visual.rs | 72 ++++++++++++++++++- .../test_data/test_visual_object_expands.json | 10 +++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 crates/vim/test_data/test_visual_object_expands.json diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 6fcbf74970..adb288395e 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -386,8 +386,20 @@ impl Vim { || movement::right(map, selection.start) == selection.end; if expand_both_ways { - selection.start = range.start; - selection.end = range.end; + if selection.start == range.start + && selection.end == range.end + && object.always_expands_both_ways() + { + if let Some(range) = + object.range(map, selection.clone(), around) + { + selection.start = range.start; + selection.end = range.end; + } + } else { + selection.start = range.start; + selection.end = range.end; + } } else if selection.reversed { selection.start = range.start; } else { @@ -1419,6 +1431,62 @@ mod test { .assert_eq("«ˇhello in a word» again."); } + #[gpui::test] + async fn test_visual_object_expands(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + + cx.set_shared_state(indoc! { + "{ + { + ˇ } + } + { + } + " + }) + .await; + cx.simulate_shared_keystrokes("v l").await; + cx.shared_state().await.assert_eq(indoc! { + "{ + { + « }ˇ» + } + { + } + " + }); + cx.simulate_shared_keystrokes("a {").await; + cx.shared_state().await.assert_eq(indoc! { + "{ + «{ + }ˇ» + } + { + } + " + }); + cx.simulate_shared_keystrokes("a {").await; + cx.shared_state().await.assert_eq(indoc! { + "«{ + { + } + }ˇ» + { + } + " + }); + // cx.simulate_shared_keystrokes("a {").await; + // cx.shared_state().await.assert_eq(indoc! { + // "{ + // «{ + // }ˇ» + // } + // { + // } + // " + // }); + } + #[gpui::test] async fn test_mode_across_command(cx: &mut gpui::TestAppContext) { let mut cx = VimTestContext::new(cx, true).await; diff --git a/crates/vim/test_data/test_visual_object_expands.json b/crates/vim/test_data/test_visual_object_expands.json new file mode 100644 index 0000000000..ea285ea5be --- /dev/null +++ b/crates/vim/test_data/test_visual_object_expands.json @@ -0,0 +1,10 @@ +{"Put":{"state":"{\n {\n ˇ }\n}\n{\n}\n"}} +{"Key":"v"} +{"Key":"l"} +{"Get":{"state":"{\n {\n « }ˇ»\n}\n{\n}\n","mode":"Visual"}} +{"Key":"a"} +{"Key":"{"} +{"Get":{"state":"{\n «{\n }ˇ»\n}\n{\n}\n","mode":"Visual"}} +{"Key":"a"} +{"Key":"{"} +{"Get":{"state":"«{\n {\n }\n}ˇ»\n{\n}\n","mode":"Visual"}}