diff options
-rw-r--r-- | runtime/doc/change.txt | 8 | ||||
-rw-r--r-- | runtime/doc/index.txt | 2 | ||||
-rw-r--r-- | src/nvim/normal.c | 12 | ||||
-rw-r--r-- | src/nvim/ops.c | 33 | ||||
-rw-r--r-- | src/nvim/ops.h | 15 | ||||
-rw-r--r-- | src/nvim/testdir/test_normal.vim | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_visual.vim | 22 |
7 files changed, 74 insertions, 24 deletions
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index b2e910a834..924401be74 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1091,6 +1091,11 @@ inside of strings can change! Also see 'softtabstop' option. > 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 @@ -1130,6 +1135,9 @@ a register, a paste on a visual selected area will paste that single line on 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 diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index e7d891bc33..17258f896d 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -851,6 +851,8 @@ tag char note action in Normal mode ~ |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 diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 13706fb14a..173d8d46d1 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4384,6 +4384,12 @@ dozet: } break; + // "zp", "zP" in block mode put without addind trailing spaces + case 'P': + case 'p': + nv_put(cap); + break; + /* "zF": create fold command */ /* "zf": create fold operator */ case 'F': @@ -7913,12 +7919,14 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) flags |= PUT_FIXINDENT; } 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) { diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 0ed116c17f..2c8c7f0567 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2788,13 +2788,13 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) recursive = false; } -/* - * Put contents of register "regname" into the text. - * Caller must check "regname" to be valid! - * "flags": PUT_FIXINDENT make indent look nice - * PUT_CURSEND leave cursor after end of new text - * PUT_LINE force linewise put (":put") - dir: BACKWARD for 'P', FORWARD for 'p' */ +// Put contents of register "regname" into the text. +// Caller must check "regname" to be valid! +// "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 +// dir: BACKWARD for 'P', FORWARD for 'p' void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) { char_u *ptr; @@ -3126,7 +3126,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) curwin->w_cursor.coladd = 0; bd.textcol = 0; for (i = 0; i < y_size; i++) { - int spaces; + int spaces = 0; char shortline; // can just be 0 or 1, needed for blockwise paste beyond the current // buffer end @@ -3177,13 +3177,16 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) yanklen = (int)STRLEN(y_array[i]); - // calculate number of spaces required to fill right side of block - spaces = y_width + 1; - for (long 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 (int j = 0; j < yanklen; j++) { + spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0); + } + if (spaces < 0) { + spaces = 0; + } } // insert the new text diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 77d6b4435f..112ffbeaba 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -14,13 +14,14 @@ typedef int (*Indenter)(void); -/* flags for do_put() */ -#define PUT_FIXINDENT 1 /* make indent look nice */ -#define PUT_CURSEND 2 /* leave cursor after end of new text */ -#define PUT_CURSLINE 4 /* leave cursor on last line of new text */ -#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. */ +// flags for do_put() +#define PUT_FIXINDENT 1 // make indent look nice +#define PUT_CURSEND 2 // leave cursor after end of new text +#define PUT_CURSLINE 4 // leave cursor on last line of new text +#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 /* * Registers: diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 7a846e5ea0..e9de94c0b3 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -512,6 +512,12 @@ func Test_normal14_page_eol() bw! endfunc +" Test for errors with z command +func Test_normal_z_error() + call assert_beeps('normal! z2p') + call assert_beeps('normal! zq') +endfunc + func Test_normal15_z_scroll_vert() " basic test for z commands that scroll the window call Setup_NewWindow() diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index 73c7960579..d9d10b9681 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -738,4 +738,26 @@ func Test_select_mode_gv() 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 |