diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-03-14 20:46:41 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-03-14 20:46:41 +0000 |
commit | 7a73252063242e88a6966e9d9ae7ea8beb897518 (patch) | |
tree | 822f0881036f602a6a3aefd79341ac638c415155 | |
parent | 7d42840033aedf36389208b62e28b4e0b251c199 (diff) |
patch 8.2.4567: bracketed paste doesn't work well in Visual linewise modev8.2.4567
Problem: Bracketed paste doesn't work well in Visual linewise mode.
Solution: Handle linewise Visual mode differently. (closes #9947)
-rw-r--r-- | src/normal.c | 32 | ||||
-rw-r--r-- | src/testdir/test_paste.vim | 46 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 75 insertions, 5 deletions
diff --git a/src/normal.c b/src/normal.c index 9376be5ceb..e39fb772ae 100644 --- a/src/normal.c +++ b/src/normal.c @@ -6880,6 +6880,7 @@ nv_edit(cmdarg_T *cap) { pos_T old_pos = curwin->w_cursor; pos_T old_visual = VIsual; + int old_visual_mode = VIsual_mode; // In Visual mode the selected text is deleted. if (VIsual_mode == 'V' || curwin->w_cursor.lnum != VIsual.lnum) @@ -6895,11 +6896,32 @@ nv_edit(cmdarg_T *cap) do_pending_operator(cap, 0, FALSE); cap->cmdchar = K_PS; - // When the last char in the line was deleted then append. Detect this - // by checking if the cursor moved to before the Visual area. - if (*ml_get_cursor() != NUL && LT_POS(curwin->w_cursor, old_pos) - && LT_POS(curwin->w_cursor, old_visual)) - inc_cursor(); + if (*ml_get_cursor() != NUL) + { + if (old_visual_mode == 'V') + { + // In linewise Visual mode insert before the beginning of the + // next line. + // When the last line in the buffer was deleted then create a + // new line, otherwise there is not need to move cursor. + // Detect this by checking if cursor moved above Visual area. + if (curwin->w_cursor.lnum < old_pos.lnum + && curwin->w_cursor.lnum < old_visual.lnum) + { + if (u_save_cursor() == OK) + { + ml_append(curwin->w_cursor.lnum, (char_u *)"", 0, + FALSE); + appended_lines(curwin->w_cursor.lnum++, 1L); + } + } + } + // When the last char in the line was deleted then append. + // Detect this by checking if cursor moved before Visual area. + else if (curwin->w_cursor.col < old_pos.col + && curwin->w_cursor.col < old_visual.col) + inc_cursor(); + } // Insert to replace the deleted text with the pasted text. invoke_edit(cap, FALSE, cap->cmdchar, FALSE); diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim index 5b8d8a0e3e..a59e128691 100644 --- a/src/testdir/test_paste.vim +++ b/src/testdir/test_paste.vim @@ -109,23 +109,69 @@ func Test_paste_visual_mode() call feedkeys("0fsve\<Esc>[200~more\<Esc>[201~", 'xt') call assert_equal('here are more words', getline(1)) call assert_equal('some', getreg('-')) + normal! u + call assert_equal('here are some words', getline(1)) + exe "normal! \<C-R>" + call assert_equal('here are more words', getline(1)) " include last char in the line call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt') call assert_equal('here are more noises', getline(1)) call assert_equal('words', getreg('-')) + normal! u + call assert_equal('here are more words', getline(1)) + exe "normal! \<C-R>" + call assert_equal('here are more noises', getline(1)) " exclude last char in the line call setline(1, 'some words!') call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt') call assert_equal('some noises!', getline(1)) call assert_equal('words', getreg('-')) + normal! u + call assert_equal('some words!', getline(1)) + exe "normal! \<C-R>" + call assert_equal('some noises!', getline(1)) " multi-line selection call setline(1, ['some words', 'and more']) call feedkeys("0fwvj0fd\<Esc>[200~letters\<Esc>[201~", 'xt') call assert_equal('some letters more', getline(1)) call assert_equal("words\nand", getreg('1')) + normal! u + call assert_equal(['some words', 'and more'], getline(1, 2)) + exe "normal! \<C-R>" + call assert_equal('some letters more', getline(1)) + + " linewise non-last line, cursor at start of line + call setline(1, ['some words', 'and more']) + call feedkeys("0V\<Esc>[200~letters\<Esc>[201~", 'xt') + call assert_equal('lettersand more', getline(1)) + call assert_equal("some words\n", getreg('1')) + normal! u + call assert_equal(['some words', 'and more'], getline(1, 2)) + exe "normal! \<C-R>" + call assert_equal('lettersand more', getline(1)) + + " linewise non-last line, cursor in the middle of line + call setline(1, ['some words', 'and more']) + call feedkeys("0fwV\<Esc>[200~letters\<Esc>[201~", 'xt') + call assert_equal('lettersand more', getline(1)) + call assert_equal("some words\n", getreg('1')) + normal! u + call assert_equal(['some words', 'and more'], getline(1, 2)) + exe "normal! \<C-R>" + call assert_equal('lettersand more', getline(1)) + + " linewise last line + call setline(1, ['some words', 'and more']) + call feedkeys("j0V\<Esc>[200~letters\<Esc>[201~", 'xt') + call assert_equal(['some words', 'letters'], getline(1, 2)) + call assert_equal("and more\n", getreg('1')) + normal! u + call assert_equal(['some words', 'and more'], getline(1, 2)) + exe "normal! \<C-R>" + call assert_equal(['some words', 'letters'], getline(1, 2)) bwipe! endfunc diff --git a/src/version.c b/src/version.c index 5576f20f9a..4a4aa75fea 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4567, +/**/ 4566, /**/ 4565, |