Mercurial > vim
changeset 10827:e366b968bf08 v8.0.0303
patch 8.0.0303: bracketed paste does not work in Visual mode
commit https://github.com/vim/vim/commit/a1891848d970452cd775d35a4bccfdd9758a690a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Feb 4 21:34:31 2017 +0100
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
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 04 Feb 2017 21:45:04 +0100 |
parents | c87e4d47304a |
children | fc9fa0b5480a |
files | src/normal.c src/ops.c src/proto/ops.pro src/testdir/test_paste.vim src/version.c |
diffstat | 5 files changed, 78 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/normal.c +++ b/src/normal.c @@ -9050,6 +9050,34 @@ nv_edit(cmdarg_T *cap) /* drop the pasted text */ bracketed_paste(PASTE_INSERT, TRUE, NULL); } + else if (cap->cmdchar == K_PS && VIsual_active) + { + pos_T old_pos = curwin->w_cursor; + pos_T old_visual = VIsual; + + /* In Visual mode the selected text is deleted. */ + if (VIsual_mode == 'V' || curwin->w_cursor.lnum != VIsual.lnum) + { + shift_delete_registers(); + cap->oap->regname = '1'; + } + else + cap->oap->regname = '-'; + cap->cmdchar = 'd'; + cap->nchar = NUL; + nv_operator(cap); + do_pending_operator(cap, 0, FALSE); + cap->cmdchar = K_PS; + + /* When the last char in the line was deleted then append. Detect this + * by checking if the cursor moved to before the Visual area. */ + if (*ml_get_cursor() != NUL && lt(curwin->w_cursor, old_pos) + && lt(curwin->w_cursor, old_visual)) + inc_cursor(); + + /* Insert to replace the deleted text with the pasted text. */ + invoke_edit(cap, FALSE, cap->cmdchar, FALSE); + } else if (!checkclearopq(cap->oap)) { switch (cap->cmdchar) @@ -9079,8 +9107,9 @@ nv_edit(cmdarg_T *cap) beginline(BL_WHITE|BL_FIX); break; - case K_PS: /* Bracketed paste works like "a"ppend, unless the - cursor is in the first column, then it inserts. */ + case K_PS: + /* Bracketed paste works like "a"ppend, unless the cursor is in + * the first column, then it inserts. */ if (curwin->w_cursor.col == 0) break; /*FALLTHROUGH*/
--- a/src/ops.c +++ b/src/ops.c @@ -1628,6 +1628,22 @@ adjust_clip_reg(int *rp) #endif /* + * Shift the delete registers: "9 is cleared, "8 becomes "9, etc. + */ + void +shift_delete_registers() +{ + int n; + + y_current = &y_regs[9]; + free_yank_all(); /* free register nine */ + for (n = 9; n > 1; --n) + y_regs[n] = y_regs[n - 1]; + y_previous = y_current = &y_regs[1]; + y_regs[1].y_array = NULL; /* set register one to empty */ +} + +/* * Handle a delete operation. * * Return FAIL if undo failed, OK otherwise. @@ -1739,12 +1755,7 @@ op_delete(oparg_T *oap) if (orig_regname != 0 || oap->motion_type == MLINE || oap->line_count > 1 || oap->use_reg_one) { - y_current = &y_regs[9]; - free_yank_all(); /* free register nine */ - for (n = 9; n > 1; --n) - y_regs[n] = y_regs[n - 1]; - y_previous = y_current = &y_regs[1]; - y_regs[1].y_array = NULL; /* set register one to empty */ + shift_delete_registers(); if (op_yank(oap, TRUE, FALSE) == OK) did_yank = TRUE; }
--- a/src/proto/ops.pro +++ b/src/proto/ops.pro @@ -23,6 +23,7 @@ int insert_reg(int regname, int literall int get_spec_reg(int regname, char_u **argp, int *allocated, int errmsg); int cmdline_paste_reg(int regname, int literally, int remcr); void adjust_clip_reg(int *rp); +void shift_delete_registers(void); int op_delete(oparg_T *oap); int op_replace(oparg_T *oap, int c); void op_tilde(oparg_T *oap);
--- a/src/testdir/test_paste.vim +++ b/src/testdir/test_paste.vim @@ -70,3 +70,30 @@ func Test_paste_cmdline() call feedkeys(":a\<Esc>[200~foo\<CR>bar\<Esc>[201~b\<Home>\"\<CR>", 'xt') call assert_equal("\"afoo\<CR>barb", getreg(':')) endfunc + +func Test_paste_visual_mode() + new + call setline(1, 'here are some words') + call feedkeys("0fsve\<Esc>[200~more\<Esc>[201~", 'xt') + call assert_equal('here are more words', getline(1)) + call assert_equal('some', getreg('-')) + + " include last char in the line + call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt') + call assert_equal('here are more noises', getline(1)) + call assert_equal('words', getreg('-')) + + " exclude last char in the line + call setline(1, 'some words!') + call feedkeys("0fwve\<Esc>[200~noises\<Esc>[201~", 'xt') + call assert_equal('some noises!', getline(1)) + call assert_equal('words', getreg('-')) + + " multi-line selection + call setline(1, ['some words', 'and more']) + call feedkeys("0fwvj0fd\<Esc>[200~letters\<Esc>[201~", 'xt') + call assert_equal('some letters more', getline(1)) + call assert_equal("words\nand", getreg('1')) + + bwipe! +endfunc