# HG changeset patch # User Bram Moolenaar # Date 1643386503 -3600 # Node ID 3f8a57b8c7d85234f67aa049c4b26f33eaecac35 # Parent 9cf9ba0101f62461e1c7f2a42923728727215400 patch 8.2.4242: put in Visual mode cannot be repeated Commit: https://github.com/vim/vim/commit/fb55207ed17918c8a2a6cadf5ad9d5fcf686a7ab Author: Shougo Matsushita Date: Fri Jan 28 16:01:13 2022 +0000 patch 8.2.4242: put in Visual mode cannot be repeated Problem: Put in Visual mode cannot be repeated. Solution: Use "P" to put without yanking the deleted text into the unnamed register. (Shougo Matsushita, closes #9591) diff --git a/runtime/doc/visual.txt b/runtime/doc/visual.txt --- a/runtime/doc/visual.txt +++ b/runtime/doc/visual.txt @@ -265,6 +265,7 @@ Additionally the following commands can X delete (2) |v_X| Y yank (2) |v_Y| p put |v_p| + P put without unnamed register overwrite |v_P| J join (1) |v_J| U make uppercase |v_U| u make lowercase |v_u| diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -4661,8 +4661,8 @@ nv_bracket_block(cmdarg_T *cap, pos_T *o } // found start/end of other method: go to match else if ((pos = findmatchlimit(cap->oap, findc, - (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, - 0)) == NULL) + (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, + 0)) == NULL) n = 0; else curwin->w_cursor = *pos; @@ -7505,6 +7505,8 @@ nv_put_opt(cmdarg_T *cap, int fix_indent int was_visual = FALSE; int dir; int flags = 0; + int save_unnamed = FALSE; + yankreg_T *old_y_current, *old_y_previous; if (cap->oap->op_type != OP_NOP) { @@ -7551,6 +7553,7 @@ nv_put_opt(cmdarg_T *cap, int fix_indent // overwrites if the old contents is being put. was_visual = TRUE; regname = cap->oap->regname; + save_unnamed = cap->cmdchar == 'P'; #ifdef FEAT_CLIPBOARD adjust_clip_reg(®name); #endif @@ -7568,6 +7571,11 @@ nv_put_opt(cmdarg_T *cap, int fix_indent } // 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->nchar = NUL; cap->oap->regname = NUL; @@ -7577,6 +7585,12 @@ nv_put_opt(cmdarg_T *cap, int fix_indent empty = (curbuf->b_ml.ml_flags & ML_EMPTY); --msg_silent; + if (save_unnamed) + { + set_y_current(old_y_current); + set_y_previous(old_y_previous); + } + // delete PUT_LINE_BACKWARD; cap->oap->regname = regname; diff --git a/src/register.c b/src/register.c --- a/src/register.c +++ b/src/register.c @@ -54,37 +54,29 @@ get_y_register(int reg) } #endif -#if defined(FEAT_CLIPBOARD) || defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO) yankreg_T * get_y_current(void) { return y_current; } -#endif -#if defined(FEAT_CLIPBOARD) || defined(FEAT_VIMINFO) || defined(PROTO) yankreg_T * get_y_previous(void) { return y_previous; } -#endif -#if defined(FEAT_CLIPBOARD) || defined(PROTO) void set_y_current(yankreg_T *yreg) { y_current = yreg; } -#endif -#if defined(FEAT_CLIPBOARD) || defined(FEAT_VIMINFO) || defined(PROTO) void set_y_previous(yankreg_T *yreg) { y_previous = yreg; } -#endif void reset_y_append(void) diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim --- a/src/testdir/test_visual.vim +++ b/src/testdir/test_visual.vim @@ -1358,8 +1358,32 @@ func Test_visual_undo_deletes_last_line( exe "normal ggvjfxO" undo normal gNU + bwipe! endfunc +func Test_visual_paste() + new + + " v_p overwrites unnamed register. + call setline(1, ['xxxx']) + call setreg('"', 'foo') + call setreg('-', 'bar') + normal 1Gvp + call assert_equal(@", 'x') + call assert_equal(@-, 'x') + + if has('clipboard') + " v_P does not overwrite unnamed register. + call setline(1, ['xxxx']) + call setreg('"', 'foo') + call setreg('-', 'bar') + normal 1GvP + call assert_equal(@", 'foo') + call assert_equal(@-, 'x') + endif + + bwipe! +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 4242, +/**/ 4241, /**/ 4240,