Skip to content

Commit f2813f6

Browse files
vim: Fix end of paragraph deletion when there's no blank lines (#29490)
This Pull Request attempts to fix an issue where using `d}` in vim mode would not delete all characters in case there's no blank lines at the end of the buffer. When calculating the end point for this motion, if there's no blank lines at the end of the buffer, Zed was calculating it to be the last character in the last line. However, if there's a newline at the end of the buffer, it calculates the end point to be the point at the right of the last character. Here's an example, for the following buffer contents: ``` Hello! Hello! ``` If the `d}` command is run at `(0, 0)`, the end point will be set to `(1, 5)`. However, fi the same command is run for this buffer instead: ``` Hello! Hello! ``` The end point will be set to `(1, 6)`, there's a 1 unit difference in the column, which leads to all characters actually being deleted. Closes #29393 Release Notes: - Fixed deleting to the end of paragraph when there's no blank lines --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
1 parent 4758173 commit f2813f6

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

crates/vim/src/motion.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,16 @@ impl Motion {
13091309
end_point.row -= 1;
13101310
end_point.column = 0;
13111311
selection.end = map.clip_point(map.next_line_boundary(end_point).1, Bias::Left);
1312+
} else if let Motion::EndOfParagraph = self {
1313+
// Special case: When using the "}" motion, it's possible
1314+
// that there's no blank lines after the paragraph the
1315+
// cursor is currently on.
1316+
// In this situation the `end_point.column` value will be
1317+
// greater than 0, so the selection doesn't actually end on
1318+
// the first character of a blank line. In that case, we'll
1319+
// want to move one column to the right, to actually include
1320+
// all characters of the last non-blank line.
1321+
selection.end = movement::saturating_right(map, selection.end)
13121322
}
13131323
}
13141324
} else if kind == MotionKind::Inclusive {

crates/vim/src/normal/delete.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,29 @@ mod test {
351351
.assert_matches();
352352
}
353353

354+
#[gpui::test]
355+
async fn test_delete_end_of_paragraph(cx: &mut gpui::TestAppContext) {
356+
let mut cx = NeovimBackedTestContext::new(cx).await;
357+
cx.simulate(
358+
"d }",
359+
indoc! {"
360+
ˇhello world.
361+
362+
hello world."},
363+
)
364+
.await
365+
.assert_matches();
366+
367+
cx.simulate(
368+
"d }",
369+
indoc! {"
370+
ˇhello world.
371+
hello world."},
372+
)
373+
.await
374+
.assert_matches();
375+
}
376+
354377
#[gpui::test]
355378
async fn test_delete_0(cx: &mut gpui::TestAppContext) {
356379
let mut cx = NeovimBackedTestContext::new(cx).await;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{"Put":{"state":"ˇhello world.\n\nhello world."}}
2+
{"Key":"d"}
3+
{"Key":"}"}
4+
{"Get":{"state":"ˇ\nhello world.","mode":"Normal"}}
5+
{"Put":{"state":"ˇhello world.\nhello world."}}
6+
{"Key":"d"}
7+
{"Key":"}"}
8+
{"Get":{"state":"ˇ","mode":"Normal"}}

0 commit comments

Comments
 (0)