diff options
-rw-r--r-- | src/nvim/ops.c | 32 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test39.in | 106 | ||||
-rw-r--r-- | src/nvim/testdir/test39.ok | bin | 585 -> 0 bytes | |||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/functional/legacy/039_visual_block_mode_commands_spec.lua | 234 |
6 files changed, 258 insertions, 118 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 52c1bc0d69..19dbd0f9f6 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1991,6 +1991,7 @@ void op_insert(oparg_T *oap, long count1) char_u *firstline, *ins_text; struct block_def bd; int i; + pos_T t1; /* edit() changes this - record it for OP_APPEND */ bd.is_MAX = (curwin->w_curswant == MAXCOL); @@ -2053,7 +2054,16 @@ void op_insert(oparg_T *oap, long count1) } } - edit(NUL, FALSE, (linenr_T)count1); + t1 = oap->start; + edit(NUL, false, (linenr_T)count1); + + // When a tab was inserted, and the characters in front of the tab + // have been converted to a tab as well, the column of the cursor + // might have actually been reduced, so need to adjust here. */ + if (t1.lnum == curbuf->b_op_start_orig.lnum && + lt(curbuf->b_op_start_orig, t1)) { + oap->start = curbuf->b_op_start_orig; + } /* If user has moved off this line, we don't know what to do, so do * nothing. @@ -2069,21 +2079,23 @@ void op_insert(oparg_T *oap, long count1) if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX) { if (oap->op_type == OP_INSERT && oap->start.col + oap->start.coladd - != curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) { + != curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) { + size_t t = getviscol2(curbuf->b_op_start_orig.col, + curbuf->b_op_start_orig.coladd); oap->start.col = curbuf->b_op_start_orig.col; - pre_textlen -= getviscol2(oap->start.col, oap->start.coladd) - - oap->start_vcol; - oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd); + pre_textlen -= t - oap->start_vcol; + oap->start_vcol = t; } else if (oap->op_type == OP_APPEND && oap->end.col + oap->end.coladd - >= curbuf->b_op_start_orig.col - + curbuf->b_op_start_orig.coladd) { + >= curbuf->b_op_start_orig.col + + curbuf->b_op_start_orig.coladd) { + size_t t = getviscol2(curbuf->b_op_start_orig.col, + curbuf->b_op_start_orig.coladd); oap->start.col = curbuf->b_op_start_orig.col; /* reset pre_textlen to the value of OP_INSERT */ pre_textlen += bd.textlen; - pre_textlen -= getviscol2(oap->start.col, oap->start.coladd) - - oap->start_vcol; - oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd); + pre_textlen -= t - oap->start_vcol; + oap->start_vcol = t; oap->op_type = OP_INSERT; } } diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index bc245b21f4..aaa6f4b97e 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -14,7 +14,7 @@ SCRIPTS := test_eval.out \ test24.out \ test30.out \ test32.out test34.out \ - test36.out test37.out test39.out test40.out \ + test36.out test37.out test40.out \ test42.out test45.out \ test47.out test48.out test49.out \ test52.out test53.out test55.out \ diff --git a/src/nvim/testdir/test39.in b/src/nvim/testdir/test39.in deleted file mode 100644 index ebbcbd6d0d..0000000000 --- a/src/nvim/testdir/test39.in +++ /dev/null @@ -1,106 +0,0 @@ - -Test Visual block mode commands -And test "U" in Visual mode, also on German sharp S. - -STARTTEST -:so small.vim -:so mbyte.vim -/^abcde -:" Test shift-right of a block -jlllljj>wlljlll> -:" Test shift-left of a block -G$hhhhkk< -:" Test block-insert -GklkkkIxyz -:" Test block-replace -Gllllkkklllrq -:" Test block-change -G$khhhhhkkcmno -:$-4,$w! test.out -:" Test block-insert using cursor keys for movement -/^aaaa/ -:exe ":norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>" -:/^aa/,/^$/w >> test.out -/xaaa$/ -:exe ":norm! \<C-V>jjjI<>\<Left>p\<Esc>" -:/xaaa$/,/^$/w >> test.out -:" Test for Visual block was created with the last <C-v>$ -/^A23$/ -:exe ":norm! l\<C-V>j$Aab\<Esc>" -:.,/^$/w >> test.out -:" Test for Visual block was created with the middle <C-v>$ (1) -/^B23$/ -:exe ":norm! l\<C-V>j$hAab\<Esc>" -:.,/^$/w >> test.out -:" Test for Visual block was created with the middle <C-v>$ (2) -/^C23$/ -:exe ":norm! l\<C-V>j$hhAab\<Esc>" -:.,/^$/w >> test.out -:" Test for Visual block insert when virtualedit=all and utf-8 encoding -:set ve=all -:/\t\tline -:exe ":norm! 07l\<C-V>jjIx\<Esc>" -:.,/^$/w >> test.out -:" Test for Visual block append when virtualedit=all -:exe ":norm! 012l\<C-v>jjAx\<Esc>" -:set ve= -:.,/^$/w >> test.out -:" gUe must uppercase a whole word, also when ß changes to SS -Gothe youtußeuu endYpk0wgUe -:" gUfx must uppercase until x, inclusive. -O- youßtußexu -0fogUfx -:" VU must uppercase a whole line -YpkVU -:" same, when it's the last line in the buffer -YPGi111VUddP -:" Uppercase two lines -Oblah di -doh dutVkUj -:" Uppercase part of two lines -ddppi333k0i222fyllvjfuUk -:" visual replace using Enter or NL -G3o1234567892k05l2jr
G3o987652k02l2jr
-G3o1234567892k05l2jr -G3o987652k02l2jr -:" -:" Test cursor position. When ve=block and Visual block mode and $gj -:set ve=block -:exe ":norm! 2k\<C-V>$gj\<Esc>" -:let cpos=getpos("'>") -:$put ='col:'.cpos[2].' off:'.cpos[3] -:/^the/,$w >> test.out -:qa! -ENDTEST - - line1 - line2 - line3 - -aaaaaa -bbbbbb -cccccc -dddddd - -xaaa -bbbb -cccc -dddd - -yaaa -¿¿¿ -bbb - -A23 -4567 - -B23 -4567 - -C23 -4567 - -abcdefghijklm -abcdefghijklm -abcdefghijklm -abcdefghijklm -abcdefghijklm diff --git a/src/nvim/testdir/test39.ok b/src/nvim/testdir/test39.ok Binary files differdeleted file mode 100644 index 198e5b14dc..0000000000 --- a/src/nvim/testdir/test39.ok +++ /dev/null diff --git a/src/nvim/version.c b/src/nvim/version.c index 8c9faac0c3..142988d38f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -508,7 +508,7 @@ static int included_patches[] = { // 619 NA // 618 NA 617, - // 616, + 616, 615, 614, // 613, diff --git a/test/functional/legacy/039_visual_block_mode_commands_spec.lua b/test/functional/legacy/039_visual_block_mode_commands_spec.lua new file mode 100644 index 0000000000..55db9169fa --- /dev/null +++ b/test/functional/legacy/039_visual_block_mode_commands_spec.lua @@ -0,0 +1,234 @@ +-- Test Visual block mode commands +-- And test "U" in Visual mode, also on German sharp S. + +local helpers = require('test.functional.helpers') +local nvim, eq = helpers.meths, helpers.eq +local insert, feed = helpers.insert, helpers.feed +local clear, expect = helpers.clear, helpers.expect +local source, execute = helpers.source, helpers.execute + +describe('Visual block mode', function() + + before_each(function() + clear() + + execute('set ts&vi sw&vi sts&vi noet') -- Vim compatible + end) + + it('should shift, insert, replace and change a block', function() + insert([[ + abcdefghijklm + abcdefghijklm + abcdefghijklm + abcdefghijklm + abcdefghijklm]]) + + feed('gg') + -- Test shift-right of a block + feed('jllll<C-v>jj>wll<C-v>jlll><CR>') + -- Test shift-left of a block + feed('G$hhhh<C-v>kk<lt>') + -- Test block-insert + feed('Gkl<C-v>kkkIxyz<ESC>') + -- Test block-replace + feed('Gllll<C-v>kkklllrq') + -- Test block-change + feed('G$khhh<C-v>hhkkcmno<ESC>') + + expect([[ + axyzbcdefghijklm + axyzqqqq mno ghijklm + axyzqqqqef mno ghijklm + axyzqqqqefgmnoklm + abcdqqqqijklm]]) + end) + + it('should insert a block using cursor keys for movement', function() + insert([[ + aaaaaa + bbbbbb + cccccc + dddddd + + xaaa + bbbb + cccc + dddd]]) + + execute('/^aa') + feed('l<C-v>jjjlllI<Right><Right> <ESC>') + execute('/xaaa$') + feed('<C-v>jjjI<lt>><Left>p<ESC>') + + expect([[ + aaa aaa + bbb bbb + ccc ccc + ddd ddd + + <p>xaaa + <p>bbbb + <p>cccc + <p>dddd]]) + end) + + it('should create a block', function() + insert([[ + A23 + 4567 + + B23 + 4567 + + C23 + 4567]]) + + -- Test for Visual block was created with the last <C-v>$. + execute('/^A23$/') + feed('l<C-v>j$Aab<ESC>') + -- Test for Visual block was created with the middle <C-v>$ (1). + execute('/^B23$/') + feed('l<C-v>j$hAab<ESC>') + -- Test for Visual block was created with the middle <C-v>$ (2). + execute('/^C23$/') + feed('l<C-v>j$hhAab<ESC>') + + expect([[ + A23ab + 4567ab + + B23 ab + 4567ab + + C23ab + 456ab7]]) + end) + + it('should insert and append a block when virtualedit=all', function() + insert([[ + line1 + line2 + line3 + ]]) + + -- Test for Visual block insert when virtualedit=all and utf-8 encoding. + execute('set ve=all') + execute('/\t\tline') + feed('07l<C-v>jjIx<ESC>') + + expect([[ + x line1 + x line2 + x line3 + ]]) + + -- Test for Visual block append when virtualedit=all. + feed('012l<C-v>jjAx<ESC>') + + expect([[ + x x line1 + x x line2 + x x line3 + ]]) + end) + + it('should make a selected part uppercase', function() + -- GUe must uppercase a whole word, also when ß changes to SS. + feed('Gothe youtußeuu end<ESC>Ypk0wgUe<CR>') + -- GUfx must uppercase until x, inclusive. + feed('O- youßtußexu -<ESC>0fogUfx<CR>') + -- VU must uppercase a whole line. + feed('YpkVU<CR>') + -- Same, when it's the last line in the buffer. + feed('YPGi111<ESC>VUddP<CR>') + -- Uppercase two lines. + feed('Oblah di<CR>') + feed('doh dut<ESC>VkUj<CR>') + -- Uppercase part of two lines. + feed('ddppi333<ESC>k0i222<esc>fyllvjfuUk<CR>') + + expect([[ + + the YOUTUSSEUU end + - yOUSSTUSSEXu - + THE YOUTUSSEUU END + 111THE YOUTUSSEUU END + BLAH DI + DOH DUT + 222the yoUTUSSEUU END + 333THE YOUTUßeuu end]]) + end) + + it('should replace using Enter or NL', function() + -- Visual replace using Enter or NL. + feed('G3o123456789<ESC>2k05l<C-v>2jr<CR>') + feed('G3o98765<ESC>2k02l<C-v>2jr<C-v><CR>') + feed('G3o123456789<ESC>2k05l<C-v>2jr<CR>') + feed('G3o98765<ESC>2k02l<C-v>2jr<C-v><Nul>') + + local expected = [[ + + 12345 + 789 + 12345 + 789 + 12345 + 789 + 98<CR>65 + 98<CR>65 + 98<CR>65 + 12345 + 789 + 12345 + 789 + 12345 + 789 + 98<Nul>65 + 98<Nul>65 + 98<Nul>65]] + expected = expected:gsub('<CR>', '\r') + expected = expected:gsub('<Nul>', '\x00') + + expect(expected) + end) + + it('should treat cursor position correctly when virtualedit=block', function() + insert([[ + 12345 + 789 + 98765]]) + + -- Test cursor position. When virtualedit=block and Visual block mode and $gj. + execute('set ve=block') + feed('G2l') + feed('2k<C-v>$gj<ESC>') + execute([[let cpos=getpos("'>")]]) + local cpos = nvim.get_var('cpos') + local expected = { + col = 4, + off = 0 + } + local actual = { + col = cpos[3], + off = cpos[4] + } + + eq(expected, actual) + end) + + it('should replace spaces in front of the block with tabs', function() + insert([[ + #define BO_ALL 0x0001 + #define BO_BS 0x0002 + #define BO_CRSR 0x0004]]) + + -- Block_insert when replacing spaces in front of the block with tabs. + execute('set ts=8 sts=4 sw=4') + feed('ggf0<C-v>2jI<TAB><ESC>') + + expect([[ + #define BO_ALL 0x0001 + #define BO_BS 0x0002 + #define BO_CRSR 0x0004]]) + end) +end) |