diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 4893fe9135..5d4dcacd6c 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -548,6 +548,8 @@ impl Vim { cx: &mut Context, ) { self.record_current_action(cx); + let count = Vim::take_count(cx).unwrap_or(1); + Vim::take_forced_motion(cx); self.update_editor(window, cx, |_, editor, window, cx| { editor.transact(window, cx, |editor, _, cx| { let selections = editor.selections.all::(cx); @@ -560,7 +562,7 @@ impl Vim { .into_iter() .map(|row| { let start_of_line = Point::new(row, 0); - (start_of_line..start_of_line, "\n".to_string()) + (start_of_line..start_of_line, "\n".repeat(count)) }) .collect::>(); editor.edit(edits, cx); @@ -575,10 +577,17 @@ impl Vim { cx: &mut Context, ) { self.record_current_action(cx); + let count = Vim::take_count(cx).unwrap_or(1); + Vim::take_forced_motion(cx); self.update_editor(window, cx, |_, editor, window, cx| { - editor.transact(window, cx, |editor, _, cx| { + editor.transact(window, cx, |editor, window, cx| { let selections = editor.selections.all::(cx); let snapshot = editor.buffer().read(cx).snapshot(cx); + let (_map, display_selections) = editor.selections.all_display(cx); + let original_positions = display_selections + .iter() + .map(|s| (s.id, s.head())) + .collect::>(); let selection_end_rows: BTreeSet = selections .into_iter() @@ -588,10 +597,18 @@ impl Vim { .into_iter() .map(|row| { let end_of_line = Point::new(row, snapshot.line_len(MultiBufferRow(row))); - (end_of_line..end_of_line, "\n".to_string()) + (end_of_line..end_of_line, "\n".repeat(count)) }) .collect::>(); editor.edit(edits, cx); + + editor.change_selections(None, window, cx, |s| { + s.move_with(|_, selection| { + if let Some(position) = original_positions.get(&selection.id) { + selection.collapse_to(*position, SelectionGoal::None); + } + }); + }); }); }); } @@ -1331,10 +1348,19 @@ mod test { } #[gpui::test] - async fn test_insert_empty_line_above(cx: &mut gpui::TestAppContext) { + async fn test_insert_empty_line(cx: &mut gpui::TestAppContext) { let mut cx = NeovimBackedTestContext::new(cx).await; cx.simulate("[ space", "ˇ").await.assert_matches(); cx.simulate("[ space", "The ˇquick").await.assert_matches(); + cx.simulate_at_each_offset( + "3 [ space", + indoc! {" + The qˇuick + brown ˇfox + jumps ˇover"}, + ) + .await + .assert_matches(); cx.simulate_at_each_offset( "[ space", indoc! {" @@ -1353,6 +1379,36 @@ mod test { ) .await .assert_matches(); + + cx.simulate("] space", "ˇ").await.assert_matches(); + cx.simulate("] space", "The ˇquick").await.assert_matches(); + cx.simulate_at_each_offset( + "3 ] space", + indoc! {" + The qˇuick + brown ˇfox + jumps ˇover"}, + ) + .await + .assert_matches(); + cx.simulate_at_each_offset( + "] space", + indoc! {" + The qˇuick + brown ˇfox + jumps ˇover"}, + ) + .await + .assert_matches(); + cx.simulate( + "] space", + indoc! {" + The quick + ˇ + brown fox"}, + ) + .await + .assert_matches(); } #[gpui::test] diff --git a/crates/vim/test_data/test_insert_empty_line.json b/crates/vim/test_data/test_insert_empty_line.json new file mode 100644 index 0000000000..534db2c457 --- /dev/null +++ b/crates/vim/test_data/test_insert_empty_line.json @@ -0,0 +1,78 @@ +{"Put":{"state":"ˇ"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"\nˇ","mode":"Normal"}} +{"Put":{"state":"The ˇquick"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"\nThe ˇquick","mode":"Normal"}} +{"Put":{"state":"The qˇuick\nbrown fox\njumps over"}} +{"Key":"3"} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"\n\n\nThe qˇuick\nbrown fox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown ˇfox\njumps over"}} +{"Key":"3"} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"The quick\n\n\n\nbrown ˇfox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown fox\njumps ˇover"}} +{"Key":"3"} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown fox\n\n\n\njumps ˇover","mode":"Normal"}} +{"Put":{"state":"The qˇuick\nbrown fox\njumps over"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"\nThe qˇuick\nbrown fox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown ˇfox\njumps over"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"The quick\n\nbrown ˇfox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown fox\njumps ˇover"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown fox\n\njumps ˇover","mode":"Normal"}} +{"Put":{"state":"The quick\nˇ\nbrown fox"}} +{"Key":"["} +{"Key":"space"} +{"Get":{"state":"The quick\n\nˇ\nbrown fox","mode":"Normal"}} +{"Put":{"state":"ˇ"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"ˇ\n","mode":"Normal"}} +{"Put":{"state":"The ˇquick"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The ˇquick\n","mode":"Normal"}} +{"Put":{"state":"The qˇuick\nbrown fox\njumps over"}} +{"Key":"3"} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The qˇuick\n\n\n\nbrown fox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown ˇfox\njumps over"}} +{"Key":"3"} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown ˇfox\n\n\n\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown fox\njumps ˇover"}} +{"Key":"3"} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown fox\njumps ˇover\n\n\n","mode":"Normal"}} +{"Put":{"state":"The qˇuick\nbrown fox\njumps over"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The qˇuick\n\nbrown fox\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown ˇfox\njumps over"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown ˇfox\n\njumps over","mode":"Normal"}} +{"Put":{"state":"The quick\nbrown fox\njumps ˇover"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The quick\nbrown fox\njumps ˇover\n","mode":"Normal"}} +{"Put":{"state":"The quick\nˇ\nbrown fox"}} +{"Key":"]"} +{"Key":"space"} +{"Get":{"state":"The quick\nˇ\n\nbrown fox","mode":"Normal"}} diff --git a/crates/vim/test_data/test_insert_empty_line_above.json b/crates/vim/test_data/test_insert_empty_line_above.json deleted file mode 100644 index 10e8f6dc0d..0000000000 --- a/crates/vim/test_data/test_insert_empty_line_above.json +++ /dev/null @@ -1,24 +0,0 @@ -{"Put":{"state":"ˇ"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"\nˇ","mode":"Normal"}} -{"Put":{"state":"The ˇquick"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"\nThe ˇquick","mode":"Normal"}} -{"Put":{"state":"The qˇuick\nbrown fox\njumps over"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"\nThe qˇuick\nbrown fox\njumps over","mode":"Normal"}} -{"Put":{"state":"The quick\nbrown ˇfox\njumps over"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"The quick\n\nbrown ˇfox\njumps over","mode":"Normal"}} -{"Put":{"state":"The quick\nbrown fox\njumps ˇover"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"The quick\nbrown fox\n\njumps ˇover","mode":"Normal"}} -{"Put":{"state":"The quick\nˇ\nbrown fox"}} -{"Key":"["} -{"Key":"space"} -{"Get":{"state":"The quick\n\nˇ\nbrown fox","mode":"Normal"}}