diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-02-09 14:21:04 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-02-09 14:21:04 +0800 |
commit | d9cb3fba9228aed5109a8e6069c50e4f265be9f3 (patch) | |
tree | 15a6eac7071397796be87916e907b0997b4b700b /src | |
parent | 07c97fa02d2f5be0e643f78428d56413895096cd (diff) | |
download | rneovim-d9cb3fba9228aed5109a8e6069c50e4f265be9f3.tar.gz rneovim-d9cb3fba9228aed5109a8e6069c50e4f265be9f3.tar.bz2 rneovim-d9cb3fba9228aed5109a8e6069c50e4f265be9f3.zip |
vim-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 vim/vim#9591)
https://github.com/vim/vim/commit/fb55207ed17918c8a2a6cadf5ad9d5fcf686a7ab
Cherry-pick get_y_previous() and set_y_previous() from patch 8.1.1736.
Nvim has removed y_current, so code related to it is N/A.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/normal.c | 12 | ||||
-rw-r--r-- | src/nvim/ops.c | 16 | ||||
-rw-r--r-- | src/nvim/testdir/test_visual.vim | 24 |
3 files changed, 46 insertions, 6 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 225c66aae1..21c465434a 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -7509,9 +7509,9 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) // overwrites if the old contents is being put. was_visual = true; regname = cap->oap->regname; + bool save_unnamed = cap->cmdchar == 'P'; // '+' and '*' could be the same selection - bool clipoverwrite = (regname == '+' || regname == '*') - && (cb_flags & CB_UNNAMEDMASK); + bool clipoverwrite = (regname == '+' || regname == '*') && (cb_flags & CB_UNNAMEDMASK); if (regname == 0 || regname == '"' || clipoverwrite || ascii_isdigit(regname) || regname == '-') { // The delete might overwrite the register we want to put, save it first @@ -7524,6 +7524,10 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) // do_put(), which requires the visual selection to still be active. if (!VIsual_active || VIsual_mode == 'V' || regname != '.') { // Now delete the selected text. Avoid messages here. + yankreg_T *old_y_previous; + if (save_unnamed) { + old_y_previous = get_y_previous(); + } cap->cmdchar = 'd'; cap->nchar = NUL; cap->oap->regname = NUL; @@ -7533,6 +7537,10 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) empty = (curbuf->b_ml.ml_flags & ML_EMPTY); msg_silent--; + if (save_unnamed) { + set_y_previous(old_y_previous); + } + // delete PUT_LINE_BACKWARD; cap->oap->regname = regname; } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index b8b639265c..f8ab6b2556 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -135,10 +135,18 @@ static char opchars[][3] = { Ctrl_X, NUL, OPF_CHANGE }, // OP_NR_SUB }; -/* - * Translate a command name into an operator type. - * Must only be called with a valid operator name! - */ +yankreg_T *get_y_previous(void) +{ + return y_previous; +} + +void set_y_previous(yankreg_T *yreg) +{ + y_previous = yreg; +} + +/// Translate a command name into an operator type. +/// Must only be called with a valid operator name! int get_op_type(int char1, int char2) { int i; diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index 76274fb038..e931e06175 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -1184,8 +1184,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 |