vim: Fix d shift-g not deleting until EOD if soft-wrap is on (#20160)

This previously didn't work: `d G` would delete to the end of the "first
of the soft-wrapped lines" of the last line.

To fix it, we special case the delete behavior for `shift-g`, which is
what Neovim also seems to do.


Release Notes:

- Fixed `d G` in Vim mode not deleting until the actual end of the
document if soft-wrap is turned on.
This commit is contained in:
Thorsten Ball 2024-11-05 14:47:14 +01:00 committed by GitHub
parent 4097118070
commit 7fb9549098
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 18 deletions

View file

@ -28,25 +28,30 @@ impl Vim {
original_columns.insert(selection.id, original_head.column());
motion.expand_selection(map, selection, times, true, &text_layout_details);
// Motion::NextWordStart on an empty line should delete it.
if let Motion::NextWordStart {
ignore_punctuation: _,
} = motion
{
if selection.is_empty()
&& map
.buffer_snapshot
.line_len(MultiBufferRow(selection.start.to_point(map).row))
== 0
{
selection.end = map
.buffer_snapshot
.clip_point(
Point::new(selection.start.to_point(map).row + 1, 0),
Bias::Left,
)
.to_display_point(map)
match motion {
// Motion::NextWordStart on an empty line should delete it.
Motion::NextWordStart { .. } => {
if selection.is_empty()
&& map
.buffer_snapshot
.line_len(MultiBufferRow(selection.start.to_point(map).row))
== 0
{
selection.end = map
.buffer_snapshot
.clip_point(
Point::new(selection.start.to_point(map).row + 1, 0),
Bias::Left,
)
.to_display_point(map)
}
}
Motion::EndOfDocument {} => {
// Deleting until the end of the document includes the last line, including
// soft-wrapped lines.
selection.end = map.max_point()
}
_ => {}
}
});
});

View file

@ -730,6 +730,24 @@ async fn test_wrapped_motions(cx: &mut gpui::TestAppContext) {
});
}
#[gpui::test]
async fn test_wrapped_delete_end_document(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.set_shared_wrap(12).await;
cx.set_shared_state(indoc! {"
aaˇaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccc"
})
.await;
cx.simulate_shared_keystrokes("d shift-g i z z z").await;
cx.shared_state().await.assert_eq(indoc! {"
zzzˇ"
});
}
#[gpui::test]
async fn test_paragraphs_dont_wrap(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;

View file

@ -0,0 +1,10 @@
{"SetOption":{"value":"wrap"}}
{"SetOption":{"value":"columns=12"}}
{"Put":{"state":"aaˇaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbb\ncccccccccccccccccccc"}}
{"Key":"d"}
{"Key":"shift-g"}
{"Key":"i"}
{"Key":"z"}
{"Key":"z"}
{"Key":"z"}
{"Get":{"state":"zzzˇ","mode":"Insert"}}