Merge pull request #14685 from janlazo/vim-8.2.2911

vim-patch:8.1.2400,8.2.{2911,2914.2916}
This commit is contained in:
Jan Edmund Lazo 2021-05-31 22:01:09 -04:00 committed by GitHub
commit 27c616d688
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 378 additions and 27 deletions

View File

@ -1091,6 +1091,11 @@ inside of strings can change! Also see 'softtabstop' option. >
Using the mouse only works when 'mouse' contains 'n' Using the mouse only works when 'mouse' contains 'n'
or 'a'. 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 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 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 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 each of the selected lines (thus replacing the blockwise selected region by a
block of the pasted line). block of the pasted line).
Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
spaces.
*blockwise-register* *blockwise-register*
If you use a blockwise Visual mode command to get the text into the 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 the block of text will be inserted before ("P") or after ("p") the cursor

View File

@ -851,6 +851,8 @@ tag char note action in Normal mode ~
|zm| zm subtract one from 'foldlevel' |zm| zm subtract one from 'foldlevel'
|zn| zn reset 'foldenable' |zn| zn reset 'foldenable'
|zo| zo open fold |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' |zr| zr add one to 'foldlevel'
|zs| zs when 'wrap' off scroll horizontally to |zs| zs when 'wrap' off scroll horizontally to
position the cursor at the start (left position the cursor at the start (left

View File

@ -4384,6 +4384,12 @@ dozet:
} }
break; 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 command */
/* "zf": create fold operator */ /* "zf": create fold operator */
case 'F': case 'F':
@ -7913,12 +7919,14 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
flags |= PUT_FIXINDENT; flags |= PUT_FIXINDENT;
} else { } else {
dir = (cap->cmdchar == 'P' dir = (cap->cmdchar == 'P'
|| (cap->cmdchar == 'g' && cap->nchar == 'P')) || ((cap->cmdchar == 'g' || cap->cmdchar == 'z')
? BACKWARD : FORWARD; && cap->nchar == 'P')) ? BACKWARD : FORWARD;
} }
prep_redo_cmd(cap); prep_redo_cmd(cap);
if (cap->cmdchar == 'g') { if (cap->cmdchar == 'g') {
flags |= PUT_CURSEND; flags |= PUT_CURSEND;
} else if (cap->cmdchar == 'z') {
flags |= PUT_BLOCK_INNER;
} }
if (VIsual_active) { if (VIsual_active) {

View File

@ -2788,13 +2788,13 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
recursive = false; recursive = false;
} }
/* // Put contents of register "regname" into the text.
* Put contents of register "regname" into the text. // Caller must check "regname" to be valid!
* Caller must check "regname" to be valid! // "flags": PUT_FIXINDENT make indent look nice
* "flags": PUT_FIXINDENT make indent look nice // PUT_CURSEND leave cursor after end of new text
* PUT_CURSEND leave cursor after end of new text // PUT_LINE force linewise put (":put")
* PUT_LINE force linewise put (":put") // PUT_BLOCK_INNER in block mode, do not add trailing spaces
dir: BACKWARD for 'P', FORWARD for 'p' */ // dir: BACKWARD for 'P', FORWARD for 'p'
void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
{ {
char_u *ptr; 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; curwin->w_cursor.coladd = 0;
bd.textcol = 0; bd.textcol = 0;
for (i = 0; i < y_size; i++) { for (i = 0; i < y_size; i++) {
int spaces; int spaces = 0;
char shortline; char shortline;
// can just be 0 or 1, needed for blockwise paste beyond the current // can just be 0 or 1, needed for blockwise paste beyond the current
// buffer end // 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]); yanklen = (int)STRLEN(y_array[i]);
// calculate number of spaces required to fill right side of block if ((flags & PUT_BLOCK_INNER) == 0) {
spaces = y_width + 1; // calculate number of spaces required to fill right side of
for (long j = 0; j < yanklen; j++) { // block
spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0); spaces = y_width + 1;
} for (int j = 0; j < yanklen; j++) {
if (spaces < 0) { spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
spaces = 0; }
if (spaces < 0) {
spaces = 0;
}
} }
// insert the new text // insert the new text

View File

@ -14,13 +14,14 @@
typedef int (*Indenter)(void); typedef int (*Indenter)(void);
/* flags for do_put() */ // flags for do_put()
#define PUT_FIXINDENT 1 /* make indent look nice */ #define PUT_FIXINDENT 1 // make indent look nice
#define PUT_CURSEND 2 /* leave cursor after end of new text */ #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_CURSLINE 4 // leave cursor on last line of new text
#define PUT_LINE 8 /* put register as lines */ #define PUT_LINE 8 // put register as lines
#define PUT_LINE_SPLIT 16 /* split line for linewise register */ #define PUT_LINE_SPLIT 16 // split line for linewise register
#define PUT_LINE_FORWARD 32 /* put linewise register below Visual sel. */ #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: * Registers:

View File

@ -3755,6 +3755,7 @@ static bool reg_match_visual(void)
int mode; int mode;
colnr_T start, end; colnr_T start, end;
colnr_T start2, end2; colnr_T start2, end2;
colnr_T curswant;
// Check if the buffer is the current buffer. // Check if the buffer is the current buffer.
if (rex.reg_buf != curbuf || VIsual.lnum == 0) { if (rex.reg_buf != curbuf || VIsual.lnum == 0) {
@ -3770,6 +3771,7 @@ static bool reg_match_visual(void)
bot = VIsual; bot = VIsual;
} }
mode = VIsual_mode; mode = VIsual_mode;
curswant = wp->w_curswant;
} else { } else {
if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end)) { if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end)) {
top = curbuf->b_visual.vi_start; top = curbuf->b_visual.vi_start;
@ -3779,6 +3781,7 @@ static bool reg_match_visual(void)
bot = curbuf->b_visual.vi_start; bot = curbuf->b_visual.vi_start;
} }
mode = curbuf->b_visual.vi_mode; mode = curbuf->b_visual.vi_mode;
curswant = curbuf->b_visual.vi_curswant;
} }
lnum = rex.lnum + rex.reg_firstlnum; lnum = rex.lnum + rex.reg_firstlnum;
if (lnum < top.lnum || lnum > bot.lnum) { if (lnum < top.lnum || lnum > bot.lnum) {
@ -3798,8 +3801,9 @@ static bool reg_match_visual(void)
start = start2; start = start2;
if (end2 > end) if (end2 > end)
end = end2; end = end2;
if (top.col == MAXCOL || bot.col == MAXCOL) if (top.col == MAXCOL || bot.col == MAXCOL || curswant == MAXCOL) {
end = MAXCOL; end = MAXCOL;
}
unsigned int cols_u = win_linetabsize(wp, rex.line, unsigned int cols_u = win_linetabsize(wp, rex.line,
(colnr_T)(rex.input - rex.line)); (colnr_T)(rex.input - rex.line));
assert(cols_u <= MAXCOL); assert(cols_u <= MAXCOL);

View File

@ -1,6 +1,5 @@
" Test for block inserting " Test for block inserting
" "
" TODO: rewrite test39.in into this new style test
func Test_blockinsert_indent() func Test_blockinsert_indent()
new new

View File

@ -512,6 +512,12 @@ func Test_normal14_page_eol()
bw! bw!
endfunc 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() func Test_normal15_z_scroll_vert()
" basic test for z commands that scroll the window " basic test for z commands that scroll the window
call Setup_NewWindow() call Setup_NewWindow()
@ -2877,3 +2883,35 @@ func Test_normal_gk()
bw! bw!
set cpoptions& number& numberwidth& set cpoptions& number& numberwidth&
endfunc endfunc
" Some commands like yy, cc, dd, >>, << and !! accept a count after
" typing the first letter of the command.
func Test_normal_count_after_operator()
new
setlocal shiftwidth=4 tabstop=8 autoindent
call setline(1, ['one', 'two', 'three', 'four', 'five'])
let @a = ''
normal! j"ay4y
call assert_equal("two\nthree\nfour\nfive\n", @a)
normal! 3G>2>
call assert_equal(['one', 'two', ' three', ' four', 'five'],
\ getline(1, '$'))
exe "normal! 3G0c2cred\nblue"
call assert_equal(['one', 'two', ' red', ' blue', 'five'],
\ getline(1, '$'))
exe "normal! gg<8<"
call assert_equal(['one', 'two', 'red', 'blue', 'five'],
\ getline(1, '$'))
exe "normal! ggd3d"
call assert_equal(['blue', 'five'], getline(1, '$'))
call setline(1, range(1, 4))
call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
call assert_equal('".,.+2!', @:)
call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
call assert_equal('".!', @:)
call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
call assert_equal('".,$!', @:)
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -824,6 +824,26 @@ func Test_incsearch_search_dump()
call delete('Xis_search_script') call delete('Xis_search_script')
endfunc endfunc
func Test_hlsearch_block_visual_match()
CheckScreendump
let lines =<< trim END
set hlsearch
call setline(1, ['aa', 'bbbb', 'cccccc'])
END
call writefile(lines, 'Xhlsearch_block')
let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60})
call term_sendkeys(buf, "G\<C-V>$kk\<Esc>")
sleep 100m
call term_sendkeys(buf, "/\\%V\<CR>")
sleep 100m
call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {})
call StopVimInTerminal(buf)
call delete('Xhlsearch_block')
endfunc
func Test_incsearch_substitute() func Test_incsearch_substitute()
CheckFunction test_override CheckFunction test_override
CheckOption incsearch CheckOption incsearch

View File

@ -1,4 +1,4 @@
" Tests for various Visual mode. " Tests for various Visual modes.
func Test_block_shift_multibyte() func Test_block_shift_multibyte()
" Uses double-wide character. " Uses double-wide character.
@ -738,4 +738,272 @@ func Test_select_mode_gv()
bwipe! bwipe!
endfunc endfunc
" Tests for the visual block mode commands
func Test_visual_block_mode()
new
call append(0, '')
call setline(1, ['abcdefghijklm', 'abcdefghijklm', 'abcdefghijklm',
\ 'abcdefghijklm', 'abcdefghijklm'])
call cursor(1, 1)
" Test shift-right of a block
exe "normal jllll\<C-V>jj>wll\<C-V>jlll>"
" Test shift-left of a block
exe "normal G$hhhh\<C-V>kk<"
" Test block-insert
exe "normal Gkl\<C-V>kkkIxyz"
" Test block-replace
exe "normal Gllll\<C-V>kkklllrq"
" Test block-change
exe "normal G$khhh\<C-V>hhkkcmno"
call assert_equal(['axyzbcdefghijklm',
\ 'axyzqqqq mno ghijklm',
\ 'axyzqqqqef mno ghijklm',
\ 'axyzqqqqefgmnoklm',
\ 'abcdqqqqijklm'], getline(1, 5))
" Test from ':help v_b_I_example'
%d _
setlocal tabstop=8 shiftwidth=4
let lines =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call setline(1, lines)
exe "normal ggfo\<C-V>3jISTRING"
let expected =<< trim END
abcdefghijklmnSTRINGopqrstuvwxyz
abc STRING defghijklmnopqrstuvwxyz
abcdef ghi STRING jklmnopqrstuvwxyz
abcdefghijklmnSTRINGopqrstuvwxyz
END
call assert_equal(expected, getline(1, '$'))
" Test from ':help v_b_A_example'
%d _
let lines =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call setline(1, lines)
exe "normal ggfo\<C-V>3j$ASTRING"
let expected =<< trim END
abcdefghijklmnopqrstuvwxyzSTRING
abc defghijklmnopqrstuvwxyzSTRING
abcdef ghi jklmnopqrstuvwxyzSTRING
abcdefghijklmnopqrstuvwxyzSTRING
END
call assert_equal(expected, getline(1, '$'))
" Test from ':help v_b_<_example'
%d _
let lines =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call setline(1, lines)
exe "normal ggfo\<C-V>3j3l<.."
let expected =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call assert_equal(expected, getline(1, '$'))
" Test from ':help v_b_>_example'
%d _
let lines =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call setline(1, lines)
exe "normal ggfo\<C-V>3j>.."
let expected =<< trim END
abcdefghijklmn opqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmn opqrstuvwxyz
END
call assert_equal(expected, getline(1, '$'))
" Test from ':help v_b_r_example'
%d _
let lines =<< trim END
abcdefghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdef ghi jklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
END
call setline(1, lines)
exe "normal ggfo\<C-V>5l3jrX"
let expected =<< trim END
abcdefghijklmnXXXXXXuvwxyz
abc XXXXXXhijklmnopqrstuvwxyz
abcdef ghi XXXXXX jklmnopqrstuvwxyz
abcdefghijklmnXXXXXXuvwxyz
END
call assert_equal(expected, getline(1, '$'))
bwipe!
set tabstop& shiftwidth&
endfunc
" Test block-insert using cursor keys for movement
func Test_visual_block_insert_cursor_keys()
new
call append(0, ['aaaaaa', 'bbbbbb', 'cccccc', 'dddddd'])
call cursor(1, 1)
exe "norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>"
call assert_equal(['aaa aaa', 'bbb bbb', 'ccc ccc', 'ddd ddd'],
\ getline(1, 4))
call deletebufline('', 1, '$')
call setline(1, ['xaaa', 'bbbb', 'cccc', 'dddd'])
call cursor(1, 1)
exe "norm! \<C-V>jjjI<>\<Left>p\<Esc>"
call assert_equal(['<p>xaaa', '<p>bbbb', '<p>cccc', '<p>dddd'],
\ getline(1, 4))
bwipe!
endfunc
func Test_visual_block_create()
new
call append(0, '')
" Test for Visual block was created with the last <C-v>$
call setline(1, ['A23', '4567'])
call cursor(1, 1)
exe "norm! l\<C-V>j$Aab\<Esc>"
call assert_equal(['A23ab', '4567ab'], getline(1, 2))
" Test for Visual block was created with the middle <C-v>$ (1)
call deletebufline('', 1, '$')
call setline(1, ['B23', '4567'])
call cursor(1, 1)
exe "norm! l\<C-V>j$hAab\<Esc>"
call assert_equal(['B23 ab', '4567ab'], getline(1, 2))
" Test for Visual block was created with the middle <C-v>$ (2)
call deletebufline('', 1, '$')
call setline(1, ['C23', '4567'])
call cursor(1, 1)
exe "norm! l\<C-V>j$hhAab\<Esc>"
call assert_equal(['C23ab', '456ab7'], getline(1, 2))
bwipe!
endfunc
" Test for Visual block insert when virtualedit=all
func Test_virtualedit_visual_block()
set ve=all
new
call append(0, ["\t\tline1", "\t\tline2", "\t\tline3"])
call cursor(1, 1)
exe "norm! 07l\<C-V>jjIx\<Esc>"
call assert_equal([" x \tline1",
\ " x \tline2",
\ " x \tline3"], getline(1, 3))
" Test for Visual block append when virtualedit=all
exe "norm! 012l\<C-v>jjAx\<Esc>"
call assert_equal([' x x line1',
\ ' x x line2',
\ ' x x line3'], getline(1, 3))
set ve=
bwipe!
endfunc
" Test for changing case
func Test_visual_change_case()
new
" gUe must uppercase a whole word, also when ß changes to SS
exe "normal Gothe youtußeuu end\<Esc>Ypk0wgUe\r"
" gUfx must uppercase until x, inclusive.
exe "normal O- youßtußexu -\<Esc>0fogUfx\r"
" VU must uppercase a whole line
exe "normal YpkVU\r"
" same, when it's the last line in the buffer
exe "normal YPGi111\<Esc>VUddP\r"
" Uppercase two lines
exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
" Uppercase part of two lines
exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
call assert_equal(['the YOUTUSSEUU end', '- yOUSSTUSSEXu -',
\ 'THE YOUTUSSEUU END', '111THE YOUTUSSEUU END', 'BLAH DI', 'DOH DUT',
\ '222the yoUTUSSEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
bwipe!
endfunc
" Test for Visual replace using Enter or NL
func Test_visual_replace_crnl()
new
exe "normal G3o123456789\e2k05l\<C-V>2jr\r"
exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\r\n"
exe "normal G3o123456789\e2k05l\<C-V>2jr\n"
exe "normal G3o98765\e2k02l\<C-V>2jr\<C-V>\n"
call assert_equal(['12345', '789', '12345', '789', '12345', '789', "98\r65",
\ "98\r65", "98\r65", '12345', '789', '12345', '789', '12345', '789',
\ "98\n65", "98\n65", "98\n65"], getline(2, '$'))
bwipe!
endfunc
func Test_ve_block_curpos()
new
" Test cursor position. When ve=block and Visual block mode and $gj
call append(0, ['12345', '789'])
call cursor(1, 3)
set virtualedit=block
exe "norm! \<C-V>$gj\<Esc>"
call assert_equal([0, 2, 4, 0], getpos("'>"))
set virtualedit=
bwipe!
endfunc
" Test for block_insert when replacing spaces in front of the a with tabs
func Test_block_insert_replace_tabs()
new
set ts=8 sts=4 sw=4
call append(0, ["#define BO_ALL\t 0x0001",
\ "#define BO_BS\t 0x0002",
\ "#define BO_CRSR\t 0x0004"])
call cursor(1, 1)
exe "norm! f0\<C-V>2jI\<tab>\<esc>"
call assert_equal([
\ "#define BO_ALL\t\t0x0001",
\ "#define BO_BS\t \t0x0002",
\ "#define BO_CRSR\t \t0x0004", ''], getline(1, '$'))
set ts& sts& sw&
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 " vim: shiftwidth=2 sts=2 expandtab