Fix yank around paragraph missing newline (#43583)
Use `MotionKind::LineWise` in both `vim::normal::change::Vim.change_object` and `vim::normal::yank::Vim.yank_object` when dealing with objects that target `Mode::VisualLine`, for example, paragraphs. This fixes an issue where yanking and changing paragraphs would not include the trailing newline character. Closes #28804 Release Notes: - Fixed linewise text object operations (`yap`, `cap`, etc.) omitting trailing blank line in vim mode --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
@@ -121,7 +121,11 @@ impl Vim {
|
||||
});
|
||||
});
|
||||
if objects_found {
|
||||
vim.copy_selections_content(editor, MotionKind::Exclusive, window, cx);
|
||||
let kind = match object.target_visual_mode(vim.mode, around) {
|
||||
Mode::VisualLine => MotionKind::Linewise,
|
||||
_ => MotionKind::Exclusive,
|
||||
};
|
||||
vim.copy_selections_content(editor, kind, window, cx);
|
||||
editor.insert("", window, cx);
|
||||
editor.refresh_edit_prediction(true, false, window, cx);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,11 @@ impl Vim {
|
||||
start_positions.insert(selection.id, start_position);
|
||||
});
|
||||
});
|
||||
vim.yank_selections_content(editor, MotionKind::Exclusive, window, cx);
|
||||
let kind = match object.target_visual_mode(vim.mode, around) {
|
||||
Mode::VisualLine => MotionKind::Linewise,
|
||||
_ => MotionKind::Exclusive,
|
||||
};
|
||||
vim.yank_selections_content(editor, kind, window, cx);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|_, selection| {
|
||||
let (head, goal) = start_positions.remove(&selection.id).unwrap();
|
||||
|
||||
@@ -2253,6 +2253,79 @@ async fn test_paragraph_multi_delete(cx: &mut gpui::TestAppContext) {
|
||||
cx.shared_state().await.assert_eq(indoc! {"ˇ"});
|
||||
}
|
||||
|
||||
#[perf]
|
||||
#[gpui::test]
|
||||
async fn test_yank_paragraph_with_paste(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
cx.set_shared_state(indoc! {
|
||||
"
|
||||
first paragraph
|
||||
ˇstill first
|
||||
|
||||
second paragraph
|
||||
still second
|
||||
|
||||
third paragraph
|
||||
"
|
||||
})
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes("y a p").await;
|
||||
cx.shared_clipboard()
|
||||
.await
|
||||
.assert_eq("first paragraph\nstill first\n\n");
|
||||
|
||||
cx.simulate_shared_keystrokes("j j p").await;
|
||||
cx.shared_state().await.assert_eq(indoc! {
|
||||
"
|
||||
first paragraph
|
||||
still first
|
||||
|
||||
ˇfirst paragraph
|
||||
still first
|
||||
|
||||
second paragraph
|
||||
still second
|
||||
|
||||
third paragraph
|
||||
"
|
||||
});
|
||||
}
|
||||
|
||||
#[perf]
|
||||
#[gpui::test]
|
||||
async fn test_change_paragraph(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
cx.set_shared_state(indoc! {
|
||||
"
|
||||
first paragraph
|
||||
ˇstill first
|
||||
|
||||
second paragraph
|
||||
still second
|
||||
|
||||
third paragraph
|
||||
"
|
||||
})
|
||||
.await;
|
||||
|
||||
cx.simulate_shared_keystrokes("c a p").await;
|
||||
cx.shared_clipboard()
|
||||
.await
|
||||
.assert_eq("first paragraph\nstill first\n\n");
|
||||
|
||||
cx.simulate_shared_keystrokes("escape").await;
|
||||
cx.shared_state().await.assert_eq(indoc! {
|
||||
"
|
||||
ˇ
|
||||
second paragraph
|
||||
still second
|
||||
|
||||
third paragraph
|
||||
"
|
||||
});
|
||||
}
|
||||
|
||||
#[perf]
|
||||
#[gpui::test]
|
||||
async fn test_multi_cursor_replay(cx: &mut gpui::TestAppContext) {
|
||||
|
||||
8
crates/vim/test_data/test_change_paragraph.json
Normal file
8
crates/vim/test_data/test_change_paragraph.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{"Put":{"state":"first paragraph\nˇstill first\n\nsecond paragraph\nstill second\n\nthird paragraph\n"}}
|
||||
{"Key":"c"}
|
||||
{"Key":"a"}
|
||||
{"Key":"p"}
|
||||
{"Get":{"state":"ˇ\nsecond paragraph\nstill second\n\nthird paragraph\n","mode":"Insert"}}
|
||||
{"ReadRegister":{"name":"\"","value":"first paragraph\nstill first\n\n"}}
|
||||
{"Key":"escape"}
|
||||
{"Get":{"state":"ˇ\nsecond paragraph\nstill second\n\nthird paragraph\n","mode":"Normal"}}
|
||||
10
crates/vim/test_data/test_yank_paragraph_with_paste.json
Normal file
10
crates/vim/test_data/test_yank_paragraph_with_paste.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{"Put":{"state":"first paragraph\nˇstill first\n\nsecond paragraph\nstill second\n\nthird paragraph\n"}}
|
||||
{"Key":"y"}
|
||||
{"Key":"a"}
|
||||
{"Key":"p"}
|
||||
{"Get":{"state":"ˇfirst paragraph\nstill first\n\nsecond paragraph\nstill second\n\nthird paragraph\n","mode":"Normal"}}
|
||||
{"ReadRegister":{"name":"\"","value":"first paragraph\nstill first\n\n"}}
|
||||
{"Key":"j"}
|
||||
{"Key":"j"}
|
||||
{"Key":"p"}
|
||||
{"Get":{"state":"first paragraph\nstill first\n\nˇfirst paragraph\nstill first\n\nsecond paragraph\nstill second\n\nthird paragraph\n","mode":"Normal"}}
|
||||
Reference in New Issue
Block a user