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 | |
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.
-rw-r--r-- | runtime/doc/visual.txt | 1 | ||||
-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 | ||||
-rw-r--r-- | test/functional/editor/put_spec.lua | 12 |
5 files changed, 56 insertions, 9 deletions
diff --git a/runtime/doc/visual.txt b/runtime/doc/visual.txt index 5563a56216..4d5366a41a 100644 --- a/runtime/doc/visual.txt +++ b/runtime/doc/visual.txt @@ -255,6 +255,7 @@ Additionally the following commands can be used: 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/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 diff --git a/test/functional/editor/put_spec.lua b/test/functional/editor/put_spec.lua index fdda2be131..c367f8fdd0 100644 --- a/test/functional/editor/put_spec.lua +++ b/test/functional/editor/put_spec.lua @@ -507,7 +507,9 @@ describe('put command', function() return function(exception_table, after_redo) test_expect(exception_table, after_redo) if selection_string then - eq(selection_string, getreg('"')) + if not conversion_table.put_backwards then + eq(selection_string, getreg('"')) + end else eq('test_string"', getreg('"')) end @@ -714,7 +716,9 @@ describe('put command', function() expect_base, conversion_table) return function(exception_table, after_redo) test_expect(exception_table, after_redo) - eq('Line of words 1\n', getreg('"')) + if not conversion_table.put_backwards then + eq('Line of words 1\n', getreg('"')) + end end end local base_expect_string = [[ @@ -748,7 +752,9 @@ describe('put command', function() end, expect_base, conversion_table) return function(e,c) test_expect(e,c) - eq('Lin\nLin', getreg('"')) + if not conversion_table.put_backwards then + eq('Lin\nLin', getreg('"')) + end end end |