Skip to content

Commit a189184

Browse files
committed
patch 8.0.0303: bracketed paste does not work in Visual mode
Problem: Bracketed paste does not work in Visual mode. Solution: Delete the text before pasting
1 parent e353c40 commit a189184

5 files changed

Lines changed: 78 additions & 8 deletions

File tree

src/normal.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9050,6 +9050,34 @@ nv_edit(cmdarg_T *cap)
90509050
/* drop the pasted text */
90519051
bracketed_paste(PASTE_INSERT, TRUE, NULL);
90529052
}
9053+
else if (cap->cmdchar == K_PS && VIsual_active)
9054+
{
9055+
pos_T old_pos = curwin->w_cursor;
9056+
pos_T old_visual = VIsual;
9057+
9058+
/* In Visual mode the selected text is deleted. */
9059+
if (VIsual_mode == 'V' || curwin->w_cursor.lnum != VIsual.lnum)
9060+
{
9061+
shift_delete_registers();
9062+
cap->oap->regname = '1';
9063+
}
9064+
else
9065+
cap->oap->regname = '-';
9066+
cap->cmdchar = 'd';
9067+
cap->nchar = NUL;
9068+
nv_operator(cap);
9069+
do_pending_operator(cap, 0, FALSE);
9070+
cap->cmdchar = K_PS;
9071+
9072+
/* When the last char in the line was deleted then append. Detect this
9073+
* by checking if the cursor moved to before the Visual area. */
9074+
if (*ml_get_cursor() != NUL && lt(curwin->w_cursor, old_pos)
9075+
&& lt(curwin->w_cursor, old_visual))
9076+
inc_cursor();
9077+
9078+
/* Insert to replace the deleted text with the pasted text. */
9079+
invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
9080+
}
90539081
else if (!checkclearopq(cap->oap))
90549082
{
90559083
switch (cap->cmdchar)
@@ -9079,8 +9107,9 @@ nv_edit(cmdarg_T *cap)
90799107
beginline(BL_WHITE|BL_FIX);
90809108
break;
90819109

9082-
case K_PS: /* Bracketed paste works like "a"ppend, unless the
9083-
cursor is in the first column, then it inserts. */
9110+
case K_PS:
9111+
/* Bracketed paste works like "a"ppend, unless the cursor is in
9112+
* the first column, then it inserts. */
90849113
if (curwin->w_cursor.col == 0)
90859114
break;
90869115
/*FALLTHROUGH*/

src/ops.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,22 @@ adjust_clip_reg(int *rp)
16271627
}
16281628
#endif
16291629

1630+
/*
1631+
* Shift the delete registers: "9 is cleared, "8 becomes "9, etc.
1632+
*/
1633+
void
1634+
shift_delete_registers()
1635+
{
1636+
int n;
1637+
1638+
y_current = &y_regs[9];
1639+
free_yank_all(); /* free register nine */
1640+
for (n = 9; n > 1; --n)
1641+
y_regs[n] = y_regs[n - 1];
1642+
y_previous = y_current = &y_regs[1];
1643+
y_regs[1].y_array = NULL; /* set register one to empty */
1644+
}
1645+
16301646
/*
16311647
* Handle a delete operation.
16321648
*
@@ -1739,12 +1755,7 @@ op_delete(oparg_T *oap)
17391755
if (orig_regname != 0 || oap->motion_type == MLINE
17401756
|| oap->line_count > 1 || oap->use_reg_one)
17411757
{
1742-
y_current = &y_regs[9];
1743-
free_yank_all(); /* free register nine */
1744-
for (n = 9; n > 1; --n)
1745-
y_regs[n] = y_regs[n - 1];
1746-
y_previous = y_current = &y_regs[1];
1747-
y_regs[1].y_array = NULL; /* set register one to empty */
1758+
shift_delete_registers();
17481759
if (op_yank(oap, TRUE, FALSE) == OK)
17491760
did_yank = TRUE;
17501761
}

src/proto/ops.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ int insert_reg(int regname, int literally);
2323
int get_spec_reg(int regname, char_u **argp, int *allocated, int errmsg);
2424
int cmdline_paste_reg(int regname, int literally, int remcr);
2525
void adjust_clip_reg(int *rp);
26+
void shift_delete_registers(void);
2627
int op_delete(oparg_T *oap);
2728
int op_replace(oparg_T *oap, int c);
2829
void op_tilde(oparg_T *oap);

src/testdir/test_paste.vim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,30 @@ func Test_paste_cmdline()
7070
call feedkeys(":a\<Esc>[200~foo\<CR>bar\<Esc>[201~b\<Home>\"\<CR>", 'xt')
7171
call assert_equal("\"afoo\<CR>barb", getreg(':'))
7272
endfunc
73+
74+
func Test_paste_visual_mode()
75+
new
76+
call setline(1, 'here are some words')
77+
call feedkeys("0fsve\<Esc>[200~more\<Esc>[201~", 'xt')
78+
call assert_equal('here are more words', getline(1))
79+
call assert_equal('some', getreg('-'))
80+
81+
" include last char in the line
82+
call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt')
83+
call assert_equal('here are more noises', getline(1))
84+
call assert_equal('words', getreg('-'))
85+
86+
" exclude last char in the line
87+
call setline(1, 'some words!')
88+
call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt')
89+
call assert_equal('some noises!', getline(1))
90+
call assert_equal('words', getreg('-'))
91+
92+
" multi-line selection
93+
call setline(1, ['some words', 'and more'])
94+
call feedkeys("0fwvj0fd\<Esc>[200~letters\<Esc>[201~", 'xt')
95+
call assert_equal('some letters more', getline(1))
96+
call assert_equal("words\nand", getreg('1'))
97+
98+
bwipe!
99+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
303,
767769
/**/
768770
302,
769771
/**/

0 commit comments

Comments
 (0)