Fix vim full line operations failing when no trailing newline (#24409)
Closes #24270 Release Notes: - Fixed an issue where doing line-wise operations in vim mode on the last line of a file with no trailing newline would not work properly
This commit is contained in:
parent
73c487c222
commit
337b9e62d2
11 changed files with 79 additions and 17 deletions
|
@ -1545,4 +1545,40 @@ mod test {
|
||||||
cx.simulate_shared_keystrokes("x escape shift-o").await;
|
cx.simulate_shared_keystrokes("x escape shift-o").await;
|
||||||
cx.shared_state().await.assert_eq("// hello\n// ˇ\n// x\n");
|
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
|
// 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
|
// contains a newline (so that delete works as expected). We undo that change
|
||||||
// here.
|
// here.
|
||||||
let is_last_line = linewise
|
let max_point = buffer.max_point();
|
||||||
&& end.row == buffer.max_row().0
|
let should_adjust_start = linewise
|
||||||
&& buffer.max_point().column > 0
|
&& end.row == max_point.row
|
||||||
&& start.row < buffer.max_row().0
|
&& max_point.column > 0
|
||||||
|
&& start.row < max_point.row
|
||||||
&& start == Point::new(start.row, buffer.line_len(MultiBufferRow(start.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);
|
start = Point::new(start.row + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +182,7 @@ impl Vim {
|
||||||
for chunk in buffer.text_for_range(start..end) {
|
for chunk in buffer.text_for_range(start..end) {
|
||||||
text.push_str(chunk);
|
text.push_str(chunk);
|
||||||
}
|
}
|
||||||
if is_last_line {
|
if should_add_newline {
|
||||||
text.push('\n');
|
text.push('\n');
|
||||||
}
|
}
|
||||||
clipboard_selections.push(ClipboardSelection {
|
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"}}
|
|
@ -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"}}
|
Loading…
Add table
Add a link
Reference in a new issue