Detailed changes
@@ -1545,4 +1545,40 @@ mod test {
cx.simulate_shared_keystrokes("x escape shift-o").await;
cx.shared_state().await.assert_eq("// hello\n// ˇ\n// x\n");
}
+
+ #[gpui::test]
+ async fn test_yank_line_with_trailing_newline(cx: &mut gpui::TestAppContext) {
+ let mut cx = NeovimBackedTestContext::new(cx).await;
+ cx.set_shared_state("heˇllo\n").await;
+ cx.simulate_shared_keystrokes("y y p").await;
+ cx.shared_state().await.assert_eq("hello\nˇhello\n");
+ }
+
+ #[gpui::test]
+ async fn test_yank_line_without_trailing_newline(cx: &mut gpui::TestAppContext) {
+ let mut cx = NeovimBackedTestContext::new(cx).await;
+ cx.set_shared_state("heˇllo").await;
+ cx.simulate_shared_keystrokes("y y p").await;
+ cx.shared_state().await.assert_eq("hello\nˇhello");
+ }
+
+ #[gpui::test]
+ async fn test_yank_multiline_without_trailing_newline(cx: &mut gpui::TestAppContext) {
+ let mut cx = NeovimBackedTestContext::new(cx).await;
+ cx.set_shared_state("heˇllo\nhello").await;
+ cx.simulate_shared_keystrokes("2 y y p").await;
+ cx.shared_state()
+ .await
+ .assert_eq("hello\nˇhello\nhello\nhello");
+ }
+
+ #[gpui::test]
+ async fn test_dd_then_paste_without_trailing_newline(cx: &mut gpui::TestAppContext) {
+ let mut cx = NeovimBackedTestContext::new(cx).await;
+ cx.set_shared_state("heˇllo").await;
+ cx.simulate_shared_keystrokes("d d").await;
+ cx.shared_state().await.assert_eq("ˇ");
+ cx.simulate_shared_keystrokes("p p").await;
+ cx.shared_state().await.assert_eq("\nhello\nˇhello");
+ }
}
@@ -162,13 +162,16 @@ impl Vim {
// that line, we will have expanded the start of the selection to ensure it
// contains a newline (so that delete works as expected). We undo that change
// here.
- let is_last_line = linewise
- && end.row == buffer.max_row().0
- && buffer.max_point().column > 0
- && start.row < buffer.max_row().0
+ let max_point = buffer.max_point();
+ let should_adjust_start = linewise
+ && end.row == max_point.row
+ && max_point.column > 0
+ && start.row < max_point.row
&& start == Point::new(start.row, buffer.line_len(MultiBufferRow(start.row)));
+ let should_add_newline =
+ should_adjust_start || (end == max_point && max_point.column > 0 && linewise);
- if is_last_line {
+ if should_adjust_start {
start = Point::new(start.row + 1, 0);
}
@@ -179,7 +182,7 @@ impl Vim {
for chunk in buffer.text_for_range(start..end) {
text.push_str(chunk);
}
- if is_last_line {
+ if should_add_newline {
text.push('\n');
}
clipboard_selections.push(ClipboardSelection {
@@ -0,0 +1,7 @@
+{"Put":{"state":"heˇllo"}}
+{"Key":"d"}
+{"Key":"d"}
+{"Get":{"state":"ˇ","mode":"Normal"}}
+{"Key":"p"}
+{"Key":"p"}
+{"Get":{"state":"\nhello\nˇhello","mode":"Normal"}}
@@ -1,10 +1,10 @@
{"Put":{"state":"0b111111111111111111111111111111111111111111111111111111111111111111111ˇ1\n"}}
{"Key":"ctrl-a"}
-{"Get":{"state":"0b000000111111111111111111111111111111111111111111111111111111111111111ˇ1\n", "mode":"Normal"}}
+{"Get":{"state":"0b000000111111111111111111111111111111111111111111111111111111111111111ˇ1\n","mode":"Normal"}}
{"Key":"ctrl-a"}
{"Get":{"state":"0b000000000000000000000000000000000000000000000000000000000000000000000ˇ0\n","mode":"Normal"}}
{"Key":"ctrl-a"}
{"Get":{"state":"0b000000000000000000000000000000000000000000000000000000000000000000000ˇ1\n","mode":"Normal"}}
{"Key":"2"}
{"Key":"ctrl-x"}
-{"Get":{"state":"0b000000111111111111111111111111111111111111111111111111111111111111111ˇ1\n", "mode":"Normal"}}
+{"Get":{"state":"0b000000111111111111111111111111111111111111111111111111111111111111111ˇ1\n","mode":"Normal"}}
@@ -1,10 +1,10 @@
{"Put":{"state":"0xfffffffffffffffffffˇf\n"}}
{"Key":"ctrl-a"}
-{"Get":{"state":"0x0000fffffffffffffffˇf\n", "mode":"Normal"}}
+{"Get":{"state":"0x0000fffffffffffffffˇf\n","mode":"Normal"}}
{"Key":"ctrl-a"}
{"Get":{"state":"0x0000000000000000000ˇ0\n","mode":"Normal"}}
{"Key":"ctrl-a"}
{"Get":{"state":"0x0000000000000000000ˇ1\n","mode":"Normal"}}
{"Key":"2"}
{"Key":"ctrl-x"}
-{"Get":{"state":"0x0000fffffffffffffffˇf\n", "mode":"Normal"}}
+{"Get":{"state":"0x0000fffffffffffffffˇf\n","mode":"Normal"}}
@@ -2,9 +2,9 @@
{"Key":"ctrl-a"}
{"Get":{"state":"inline0x3ˇau32\n","mode":"Normal"}}
{"Key":"ctrl-a"}
-{"Get":{"state":"inline0x3ˇbu32\n", "mode":"Normal"}}
+{"Get":{"state":"inline0x3ˇbu32\n","mode":"Normal"}}
{"Key":"l"}
{"Key":"l"}
{"Key":"l"}
{"Key":"ctrl-a"}
-{"Get":{"state":"inline0x3bu3ˇ3\n", "mode":"Normal"}}
+{"Get":{"state":"inline0x3bu3ˇ3\n","mode":"Normal"}}
@@ -3,4 +3,4 @@
{"Get":{"state":"-ˇ1\n","mode":"Normal"}}
{"Key":"2"}
{"Key":"ctrl-a"}
-{"Get":{"state":"ˇ1\n", "mode":"Normal"}}
+{"Get":{"state":"ˇ1\n","mode":"Normal"}}
@@ -2,12 +2,12 @@
{"Key":"ctrl-a"}
{"Get":{"state":"1844674407370955161ˇ5\n","mode":"Normal"}}
{"Key":"ctrl-a"}
-{"Get":{"state":"-1844674407370955161ˇ5\n", "mode":"Normal"}}
+{"Get":{"state":"-1844674407370955161ˇ5\n","mode":"Normal"}}
{"Key":"ctrl-a"}
-{"Get":{"state":"-1844674407370955161ˇ4\n", "mode":"Normal"}}
+{"Get":{"state":"-1844674407370955161ˇ4\n","mode":"Normal"}}
{"Key":"3"}
{"Key":"ctrl-x"}
-{"Get":{"state":"1844674407370955161ˇ4\n", "mode":"Normal"}}
+{"Get":{"state":"1844674407370955161ˇ4\n","mode":"Normal"}}
{"Key":"2"}
{"Key":"ctrl-a"}
-{"Get":{"state":"-1844674407370955161ˇ5\n", "mode":"Normal"}}
+{"Get":{"state":"-1844674407370955161ˇ5\n","mode":"Normal"}}
@@ -0,0 +1,5 @@
+{"Put":{"state":"heˇllo\n"}}
+{"Key":"y"}
+{"Key":"y"}
+{"Key":"p"}
+{"Get":{"state":"hello\nˇhello\n","mode":"Normal"}}
@@ -0,0 +1,5 @@
+{"Put":{"state":"heˇllo"}}
+{"Key":"y"}
+{"Key":"y"}
+{"Key":"p"}
+{"Get":{"state":"hello\nˇhello","mode":"Normal"}}
@@ -0,0 +1,6 @@
+{"Put":{"state":"heˇllo\nhello"}}
+{"Key":"2"}
+{"Key":"y"}
+{"Key":"y"}
+{"Key":"p"}
+{"Get":{"state":"hello\nˇhello\nhello\nhello","mode":"Normal"}}