0
0
mirror of https://github.com/vim/vim.git synced 2025-09-30 04:44:14 -04:00

patch 8.2.4881: "P" in Visual mode still changes some registers

Problem:    "P" in Visual mode still changes some registers.
Solution:   Make "P" in Visual mode not change any register. (Shougo
            Matsushita, closes #10349)
This commit is contained in:
Shougo Matsushita
2022-05-06 11:45:09 +01:00
committed by Bram Moolenaar
parent 434725cc4c
commit 509142ab7a
6 changed files with 83 additions and 52 deletions

View File

@@ -1177,14 +1177,15 @@ register. With blockwise selection it also depends on the size of the block
and whether the corners are on an existing character. (Implementation detail: and whether the corners are on an existing character. (Implementation detail:
it actually works by first putting the register after the selection and then it actually works by first putting the register after the selection and then
deleting the selection.) deleting the selection.)
With 'p' the previously selected text is put in the unnamed register. This is With |p| the previously selected text is put in the unnamed register (and
useful if you want to put that text somewhere else. But you cannot repeat the possibly the selection and/or clipboard). This is useful if you want to put
same change. that text somewhere else. But you cannot repeat the same change.
With 'P' the unnamed register is not changed, you can repeat the same change. With |P| the unnamed register is not changed (and neither the selection or
But the deleted text cannot be used. If you do need it you can use 'p' with clipboard), you can repeat the same change. But the deleted text cannot be
another register. E.g., yank the text to copy, Visually select the text to used. If you do need it you can use |p| with another register. E.g., yank
replace and use "0p . You can repeat this as many times as you like, and the the text to copy, Visually select the text to replace and use "0p . You can
unnamed register will be changed each time. repeat this as many times as you like, and the unnamed register will be
changed each time.
When you use a blockwise Visual mode command and yank only a single line into When you use a blockwise Visual mode command and yank only a single line into
a register, a paste on a visual selected area will paste that single line on a register, a paste on a visual selected area will paste that single line on

View File

@@ -939,7 +939,7 @@ tag command note action in Visual mode ~
|v_K| K run 'keywordprg' on the highlighted area |v_K| K run 'keywordprg' on the highlighted area
|v_O| O move horizontally to other corner of area |v_O| O move horizontally to other corner of area
|v_P| P replace highlighted area with register |v_P| P replace highlighted area with register
contents; unnamed register is unchanged contents; registers are unchanged
Q does not start Ex mode Q does not start Ex mode
|v_R| R 2 delete the highlighted lines and start |v_R| R 2 delete the highlighted lines and start
insert insert

View File

@@ -265,7 +265,7 @@ Additionally the following commands can be used:
X delete (2) |v_X| X delete (2) |v_X|
Y yank (2) |v_Y| Y yank (2) |v_Y|
p put |v_p| p put |v_p|
P put without unnamed register overwrite |v_P| P put without overwriting registers |v_P|
J join (1) |v_J| J join (1) |v_J|
U make uppercase |v_U| U make uppercase |v_U|
u make lowercase |v_u| u make lowercase |v_u|

View File

@@ -7236,8 +7236,7 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
int was_visual = FALSE; int was_visual = FALSE;
int dir; int dir;
int flags = 0; int flags = 0;
int save_unnamed = FALSE; int keep_registers = FALSE;
yankreg_T *old_y_current, *old_y_previous;
if (cap->oap->op_type != OP_NOP) if (cap->oap->op_type != OP_NOP)
{ {
@@ -7284,7 +7283,7 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
// overwrites if the old contents is being put. // overwrites if the old contents is being put.
was_visual = TRUE; was_visual = TRUE;
regname = cap->oap->regname; regname = cap->oap->regname;
save_unnamed = cap->cmdchar == 'P'; keep_registers = cap->cmdchar == 'P';
#ifdef FEAT_CLIPBOARD #ifdef FEAT_CLIPBOARD
adjust_clip_reg(&regname); adjust_clip_reg(&regname);
#endif #endif
@@ -7302,26 +7301,15 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
} }
// Now delete the selected text. Avoid messages here. // Now delete the selected text. Avoid messages here.
if (save_unnamed)
{
old_y_current = get_y_current();
old_y_previous = get_y_previous();
}
cap->cmdchar = 'd'; cap->cmdchar = 'd';
cap->nchar = NUL; cap->nchar = NUL;
cap->oap->regname = NUL; cap->oap->regname = keep_registers ? '_' : NUL;
++msg_silent; ++msg_silent;
nv_operator(cap); nv_operator(cap);
do_pending_operator(cap, 0, FALSE); do_pending_operator(cap, 0, FALSE);
empty = (curbuf->b_ml.ml_flags & ML_EMPTY); empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
--msg_silent; --msg_silent;
if (save_unnamed)
{
set_y_current(old_y_current);
set_y_previous(old_y_previous);
}
// delete PUT_LINE_BACKWARD; // delete PUT_LINE_BACKWARD;
cap->oap->regname = regname; cap->oap->regname = regname;

View File

@@ -1390,18 +1390,28 @@ func Test_visual_paste()
call assert_equal('x', @-) call assert_equal('x', @-)
call assert_equal('bazooxxf', getline(1)) call assert_equal('bazooxxf', getline(1))
if has('clipboard') bwipe!
endfunc
func Test_visual_paste_clipboard()
CheckFeature clipboard_working
if has('gui')
" auto select feature breaks tests
set guioptions-=a
endif
" v_P does not overwrite unnamed register. " v_P does not overwrite unnamed register.
call setline(1, ['xxxx']) call setline(1, ['xxxx'])
call setreg('"', 'foo') call setreg('"', 'foo')
call setreg('-', 'bar') call setreg('-', 'bar')
normal gg0vP normal gg0vP
call assert_equal('foo', @") call assert_equal('foo', @")
call assert_equal('x', @-) call assert_equal('bar', @-)
call assert_equal('fooxxx', getline(1)) call assert_equal('fooxxx', getline(1))
normal $vP normal $vP
call assert_equal('foo', @") call assert_equal('foo', @")
call assert_equal('x', @-) call assert_equal('bar', @-)
call assert_equal('fooxxfoo', getline(1)) call assert_equal('fooxxfoo', getline(1))
" Test with a different register as unnamed register. " Test with a different register as unnamed register.
call setline(2, ['baz']) call setline(2, ['baz'])
@@ -1409,15 +1419,45 @@ func Test_visual_paste()
call assert_equal('baz', @") call assert_equal('baz', @")
normal gg0vP normal gg0vP
call assert_equal('baz', @") call assert_equal('baz', @")
call assert_equal('f', @-) call assert_equal('bar', @-)
call assert_equal('bazooxxfoo', getline(1)) call assert_equal('bazooxxfoo', getline(1))
normal $vP normal $vP
call assert_equal('baz', @") call assert_equal('baz', @")
call assert_equal('o', @-) call assert_equal('bar', @-)
call assert_equal('bazooxxfobaz', getline(1)) call assert_equal('bazooxxfobaz', getline(1))
" Test for unnamed clipboard
set clipboard=unnamed
call setline(1, ['xxxx'])
call setreg('"', 'foo')
call setreg('-', 'bar')
call setreg('*', 'baz')
normal gg0vP
call assert_equal('foo', @")
call assert_equal('bar', @-)
call assert_equal('baz', @*)
call assert_equal('bazxxx', getline(1))
" Test for unnamedplus clipboard
if has('unnamedplus')
set clipboard=unnamedplus
call setline(1, ['xxxx'])
call setreg('"', 'foo')
call setreg('-', 'bar')
call setreg('+', 'baz')
normal gg0vP
call assert_equal('foo', @")
call assert_equal('bar', @-)
call assert_equal('baz', @+)
call assert_equal('bazxxx', getline(1))
endif endif
set clipboard&
if has('gui')
set guioptions&
endif
bwipe! bwipe!
endfunc endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4881,
/**/ /**/
4880, 4880,
/**/ /**/