]> granicus.if.org Git - vim/commitdiff
patch 8.0.0303: bracketed paste does not work in Visual mode v8.0.0303
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Feb 2017 20:34:31 +0000 (21:34 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Feb 2017 20:34:31 +0000 (21:34 +0100)
Problem:    Bracketed paste does not work in Visual mode.
Solution:   Delete the text before pasting

src/normal.c
src/ops.c
src/proto/ops.pro
src/testdir/test_paste.vim
src/version.c

index 3012bf3b72f4614bcf44425beaada833f7b9c5a9..ce8ca531a0918a87417f58a8e9f01b6fa91e099e 100644 (file)
@@ -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*/
index 1c0276d8d79de81363f0ddc211bd5fec893ad598..d23b3077f53127ee7bd3b48ea1fb5b397d406ef8 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -1627,6 +1627,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.
  *
@@ -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;
        }
index de4ae739990f3ea0a108151eb987dd01861226aa..ef044e7abad27900959ec0e8cc8ebe36169bb574 100644 (file)
@@ -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);
index f5deb7d6bcb1068349db936a285acc1e46104ea0..440dc7f1f678e5735d465f2ea6182a0b35e6d9b0 100644 (file)
@@ -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
index 34add35ecc38bdea403881ef6a0b1a5111deb1db..037c2dde252e675d51dcd76a8de609a63916f214 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    303,
 /**/
     302,
 /**/