summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-02-04 21:34:31 +0100
committerBram Moolenaar <Bram@vim.org>2017-02-04 21:34:31 +0100
commita1891848d970452cd775d35a4bccfdd9758a690a (patch)
treea4f34fe283b391afa71e8a735b10e161077e953d
parente353c402e63b9b0a0bc06acf390e352d9e7eeaeb (diff)
downloadvim-git-8.0.0303.tar.gz
patch 8.0.0303: bracketed paste does not work in Visual modev8.0.0303
Problem: Bracketed paste does not work in Visual mode. Solution: Delete the text before pasting
-rw-r--r--src/normal.c33
-rw-r--r--src/ops.c23
-rw-r--r--src/proto/ops.pro1
-rw-r--r--src/testdir/test_paste.vim27
-rw-r--r--src/version.c2
5 files changed, 78 insertions, 8 deletions
diff --git a/src/normal.c b/src/normal.c
index 3012bf3b7..ce8ca531a 100644
--- 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*/
diff --git a/src/ops.c b/src/ops.c
index 1c0276d8d..d23b3077f 100644
--- 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;
}
diff --git a/src/proto/ops.pro b/src/proto/ops.pro
index de4ae7399..ef044e7ab 100644
--- a/src/proto/ops.pro
+++ b/src/proto/ops.pro
@@ -23,6 +23,7 @@ int insert_reg(int regname, int literally);
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);
diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim
index f5deb7d6b..440dc7f1f 100644
--- 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
diff --git a/src/version.c b/src/version.c
index 34add35ec..037c2dde2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 303,
+/**/
302,
/**/
301,