changeset 24752:1ce39e257f1b v8.2.2914

patch 8.2.2914: cannot paste a block without adding padding Commit: https://github.com/vim/vim/commit/2fa9384ca1b600b934bec81a72c5fb7ce757503a Author: Christian Brabandt <cb@256bit.org> Date: Sun May 30 22:17:25 2021 +0200 patch 8.2.2914: cannot paste a block without adding padding Problem: Cannot paste a block without adding padding. Solution: Add "zp" and "zP" which paste without adding padding. (Christian Brabandt, closes #8289)
author Bram Moolenaar <Bram@vim.org>
date Sun, 30 May 2021 22:30:03 +0200
parents e69e7133c9cf
children 1018030b38b2
files runtime/doc/change.txt runtime/doc/index.txt src/normal.c src/register.c src/testdir/test_normal.vim src/testdir/test_visual.vim src/version.c src/vim.h
diffstat 8 files changed, 56 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1126,6 +1126,11 @@ 5. Copying and moving text				*copy-move
 			Using the mouse only works when 'mouse' contains 'n'
 			or 'a'.
 
+["x]zp		    or					*zp* *zP*
+["x]zP			Like "p" and "P", except without adding trailing spaces
+			when pasting a block.  Thus the inserted text will not
+			always be a rectangle.
+
 You can use these commands to copy text from one place to another.  Do this
 by first getting the text into a register with a yank, delete or change
 command, then inserting the register contents with a put command.  You can
@@ -1165,6 +1170,9 @@ a register, a paste on a visual selected
 each of the selected lines (thus replacing the blockwise selected region by a
 block of the pasted line).
 
+Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
+spaces.
+
 							*blockwise-register*
 If you use a blockwise Visual mode command to get the text into the register,
 the block of text will be inserted before ("P") or after ("p") the cursor
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -864,6 +864,8 @@ tag		char	      note action in Normal mo
 |zm|		zm		   subtract one from 'foldlevel'
 |zn|		zn		   reset 'foldenable'
 |zo|		zo		   open fold
+|zp|		zp		   paste in block-mode without trailing spaces
+|zP|		zP		   paste in block-mode without trailing spaces
 |zr|		zr		   add one to 'foldlevel'
 |zs|		zs		   when 'wrap' off scroll horizontally to
 				   position the cursor at the start (left
--- a/src/normal.c
+++ b/src/normal.c
@@ -2973,6 +2973,10 @@ dozet:
 		}
 		break;
 
+		// "zp", "zP" in block mode put without addind trailing spaces
+    case 'P':
+    case 'p':  nv_put(cap);
+	       break;
 #ifdef FEAT_FOLDING
 		// "zF": create fold command
 		// "zf": create fold operator
@@ -7418,11 +7422,13 @@ nv_put_opt(cmdarg_T *cap, int fix_indent
 	}
 	else
 	    dir = (cap->cmdchar == 'P'
-				 || (cap->cmdchar == 'g' && cap->nchar == 'P'))
-							 ? BACKWARD : FORWARD;
+		    || ((cap->cmdchar == 'g' || cap->cmdchar == 'z')
+			&& cap->nchar == 'P')) ? BACKWARD : FORWARD;
 	prep_redo_cmd(cap);
 	if (cap->cmdchar == 'g')
 	    flags |= PUT_CURSEND;
+	else if (cap->cmdchar == 'z')
+	    flags |= PUT_BLOCK_INNER;
 
 	if (VIsual_active)
 	{
--- a/src/register.c
+++ b/src/register.c
@@ -1497,6 +1497,7 @@ copy_yank_reg(yankreg_T *reg)
  * "flags": PUT_FIXINDENT	make indent look nice
  *	    PUT_CURSEND		leave cursor after end of new text
  *	    PUT_LINE		force linewise put (":put")
+ *	    PUT_BLOCK_INNER     in block mode, do not add trailing spaces
  */
     void
 do_put(
@@ -1794,7 +1795,7 @@ do_put(
 	bd.textcol = 0;
 	for (i = 0; i < y_size; ++i)
 	{
-	    int spaces;
+	    int spaces = 0;
 	    char shortline;
 
 	    bd.startspaces = 0;
@@ -1845,12 +1846,16 @@ do_put(
 
 	    yanklen = (int)STRLEN(y_array[i]);
 
-	    // calculate number of spaces required to fill right side of block
-	    spaces = y_width + 1;
-	    for (j = 0; j < yanklen; j++)
-		spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
-	    if (spaces < 0)
-		spaces = 0;
+	    if ((flags & PUT_BLOCK_INNER) == 0)
+	    {
+		// calculate number of spaces required to fill right side of
+		// block
+		spaces = y_width + 1;
+		for (j = 0; j < yanklen; j++)
+		    spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
+		if (spaces < 0)
+		    spaces = 0;
+	    }
 
 	    // insert the new text
 	    totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -595,7 +595,7 @@ endfunc
 " Test for errors with z command
 func Test_normal_z_error()
   call assert_beeps('normal! z2p')
-  call assert_beeps('normal! zp')
+  call assert_beeps('normal! zq')
 endfunc
 
 func Test_normal15_z_scroll_vert()
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1044,4 +1044,26 @@ func Test_visual_put_in_block()
   bwipe!
 endfunc
 
+func Test_visual_put_in_block_using_zp()
+  new
+  " paste using zP
+  call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+    \ '/subdir', 
+    \ '/longsubdir',
+    \ '/longlongsubdir'])
+  exe "normal! 5G\<c-v>2j$y"
+  norm! 1Gf;zP
+  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
+  %d
+  " paste using zP
+  call setline(1, ['/path;text', '/path;text', '/path;text', '', 
+    \ '/subdir', 
+    \ '/longsubdir',
+    \ '/longlongsubdir'])
+  exe "normal! 5G\<c-v>2j$y"
+  norm! 1Gf;hzp
+  call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2914,
+/**/
     2913,
 /**/
     2912,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1068,6 +1068,7 @@ extern int (*dyn_libintl_wputenv)(const 
 #define PUT_LINE	8	// put register as lines
 #define PUT_LINE_SPLIT	16	// split line for linewise register
 #define PUT_LINE_FORWARD 32	// put linewise register below Visual sel.
+#define PUT_BLOCK_INNER 64      // in block mode, do not add trailing spaces
 
 // flags for set_indent()
 #define SIN_CHANGED	1	// call changed_bytes() when line changed