summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-03-14 20:46:41 +0000
committerBram Moolenaar <Bram@vim.org>2022-03-14 20:46:41 +0000
commit7a73252063242e88a6966e9d9ae7ea8beb897518 (patch)
tree822f0881036f602a6a3aefd79341ac638c415155
parent7d42840033aedf36389208b62e28b4e0b251c199 (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.c32
-rw-r--r--src/testdir/test_paste.vim46
-rw-r--r--src/version.c2
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,