diff --git a/crates/vim/src/helix/paste.rs b/crates/vim/src/helix/paste.rs index ecfdaa499257ad91d8518f488be9a4d4dbb51f1c..957d459dac50892e8173f4f1ac12459277b6d6ae 100644 --- a/crates/vim/src/helix/paste.rs +++ b/crates/vim/src/helix/paste.rs @@ -84,13 +84,22 @@ impl Vim { let display_point = if line_mode { if action.before { movement::line_beginning(&display_map, sel.start, false) - } else if sel.end.column() == 0 { + } else if sel.start.column() > 0 + && sel.end.column() == 0 + && sel.start != sel.end + { sel.end } else { - movement::right( - &display_map, - movement::line_end(&display_map, sel.end, false), - ) + let point = movement::line_end(&display_map, sel.end, false); + if sel.end.column() == 0 && point.column() > 0 { + // If the selection ends at the beginning of the next line, and the current line + // under the cursor is not empty, we paste at the selection's end. + sel.end + } else { + // If however the current line under the cursor is empty, we need to move + // to the beginning of the next line to avoid pasting above the end of current selection. + movement::right(&display_map, point) + } } } else if action.before { sel.start @@ -123,6 +132,12 @@ impl Vim { let offset = anchor.to_offset(&snapshot); if action.before { offset.saturating_sub(len)..offset + } else if line_mode { + // In line mode, we always move the cursor to the end of the inserted text. + // Otherwise, while it looks fine visually, inserting/appending ends up + // in the next logical line which is not desirable. + debug_assert!(len > 0); + offset..(offset + len - 1) } else { offset..(offset + len) } @@ -386,8 +401,8 @@ mod test { indoc! {" The quick brown fox jumps over - «n - ˇ»the lazy dog."}, + «nˇ» + the lazy dog."}, Mode::HelixNormal, ); @@ -405,8 +420,27 @@ mod test { indoc! {" The quick brown fox jumps over - «n - ˇ»the lazy dog."}, + «nˇ» + the lazy dog."}, + Mode::HelixNormal, + ); + + cx.set_state( + indoc! {" + + The quick brown + fox jumps overˇ + the lazy dog."}, + Mode::HelixNormal, + ); + cx.simulate_keystrokes("x y up up p"); + cx.assert_state( + indoc! {" + + «fox jumps overˇ» + The quick brown + fox jumps over + the lazy dog."}, Mode::HelixNormal, ); }