-- Tests for using Ctrl-A/Ctrl-X on visual selections local helpers = require('test.functional.helpers')(after_each) local source, command = helpers.source, helpers.command local call, clear = helpers.call, helpers.clear local eq, nvim = helpers.eq, helpers.meths describe('Ctrl-A/Ctrl-X on visual selections', function() before_each(function() clear() source([=[ " 1) Ctrl-A on visually selected number " Text: " foobar-10 " Expected: " 1) Ctrl-A on start of line: " foobar-9 " 2) Ctrl-A on visually selected "-10": " foobar-9 " 3) Ctrl-A on visually selected "10": " foobar-11 " 4) Ctrl-X on visually selected "-10" " foobar-11 " 5) Ctrl-X on visually selected "10" " foobar-9 func Test_visual_increment_01() call setline(1, repeat(["foobaar-10"], 5)) call cursor(1, 1) exec "norm! \" call assert_equal("foobaar-9", getline('.')) call assert_equal([0, 1, 9, 0], getpos('.')) call cursor(2, 1) exec "norm! f-v$\" call assert_equal("foobaar-9", getline('.')) call assert_equal([0, 2, 8, 0], getpos('.')) call cursor(3, 1) exec "norm! f1v$\" call assert_equal("foobaar-11", getline('.')) call assert_equal([0, 3, 9, 0], getpos('.')) call cursor(4, 1) exec "norm! f-v$\" call assert_equal("foobaar-11", getline('.')) call assert_equal([0, 4, 8, 0], getpos('.')) call cursor(5, 1) exec "norm! f1v$\" call assert_equal("foobaar-9", getline('.')) call assert_equal([0, 5, 9, 0], getpos('.')) endfunc " 2) Ctrl-A on visually selected lines " Text: " 10 " 20 " 30 " 40 " " Expected: " 1) Ctrl-A on visually selected lines: " 11 " 21 " 31 " 41 " " 2) Ctrl-X on visually selected lines: " 9 " 19 " 29 " 39 func Test_visual_increment_02() call setline(1, ["10", "20", "30", "40"]) exec "norm! GV3k$\" call assert_equal(["11", "21", "31", "41"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, ["10", "20", "30", "40"]) exec "norm! GV3k$\" call assert_equal(["9", "19", "29", "39"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 3) g Ctrl-A on visually selected lines, with non-numbers in between " Text: " 10 " " 20 " " 30 " " 40 " " Expected: " 1) 2 g Ctrl-A on visually selected lines: " 12 " " 24 " " 36 " " 48 " 2) 2 g Ctrl-X on visually selected lines " 8 " " 16 " " 24 " " 32 func Test_visual_increment_03() call setline(1, ["10", "", "20", "", "30", "", "40"]) exec "norm! GV6k2g\" call assert_equal(["12", "", "24", "", "36", "", "48"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, ["10", "", "20", "", "30", "", "40"]) exec "norm! GV6k2g\" call assert_equal(["8", "", "16", "", "24", "", "32"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 4) Ctrl-A on non-number " Text: " foobar-10 " Expected: " 1) visually select foobar: " foobar-10 func Test_visual_increment_04() call setline(1, ["foobar-10"]) exec "norm! vf-\" call assert_equal(["foobar-10"], getline(1, '$')) " NOTE: I think this is correct behavior... call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 5) g on letter " Test: " a " a " a " a " Expected: " 1) g Ctrl-A on visually selected lines " b " c " d " e func Test_visual_increment_05() set nrformats+=alpha call setline(1, repeat(["a"], 4)) exec "norm! GV3kg\" call assert_equal(["b", "c", "d", "e"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 6) g on letter " Test: " z " z " z " z " Expected: " 1) g Ctrl-X on visually selected lines " y " x " w " v func Test_visual_increment_06() set nrformats+=alpha call setline(1, repeat(["z"], 4)) exec "norm! GV3kg\" call assert_equal(["y", "x", "w", "v"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 7) on letter " Test: " 2 " 1 " 0 " -1 " -2 " " Expected: " 1) Ctrl-A on visually selected lines " 3 " 2 " 1 " 0 " -1 " " 2) Ctrl-X on visually selected lines " 1 " 0 " -1 " -2 " -3 func Test_visual_increment_07() call setline(1, ["2", "1", "0", "-1", "-2"]) exec "norm! GV4k\" call assert_equal(["3", "2", "1", "0", "-1"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, ["2", "1", "0", "-1", "-2"]) exec "norm! GV4k\" call assert_equal(["1", "0", "-1", "-2", "-3"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 8) Block increment on 0x9 " Text: " 0x9 " 0x9 " Expected: " 1) Ctrl-A on visually block selected region (cursor at beginning): " 0xa " 0xa " 2) Ctrl-A on visually block selected region (cursor at end) " 0xa " 0xa func Test_visual_increment_08() call setline(1, repeat(["0x9"], 2)) exec "norm! \j$\" call assert_equal(["0xa", "0xa"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, repeat(["0x9"], 2)) exec "norm! gg$\+\" call assert_equal(["0xa", "0xa"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 9) Increment and redo " Text: " 2 " 2 " " 3 " 3 " " Expected: " 1) 2 Ctrl-A on first 2 visually selected lines " 4 " 4 " 2) redo (.) on 3 " 5 " 5 func Test_visual_increment_09() call setline(1, ["2", "2", "", "3", "3", ""]) exec "norm! ggVj2\" call assert_equal(["4", "4", "", "3", "3", ""], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) exec "norm! 3j." call assert_equal(["4", "4", "", "5", "5", ""], getline(1, '$')) call assert_equal([0, 4, 1, 0], getpos('.')) endfunc " 10) sequentially decrement 1 " Text: " 1 " 1 " 1 " 1 " Expected: " 1) g Ctrl-X on visually selected lines " 0 " -1 " -2 " -3 func Test_visual_increment_10() call setline(1, repeat(["1"], 4)) exec "norm! GV3kg\" call assert_equal(["0", "-1", "-2", "-3"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 11) visually block selected indented lines " Text: " 1 " 1 " 1 " 1 " Expected: " 1) g Ctrl-A on block selected indented lines " 2 " 1 " 3 " 4 func Test_visual_increment_11() call setline(1, [" 1", "1", " 1", " 1"]) exec "norm! f1\3jg\" call assert_equal([" 2", "1", " 3", " 4"], getline(1, '$')) call assert_equal([0, 1, 5, 0], getpos('.')) endfunc " 12) visually selected several columns " Text: " 0 0 " 0 0 " 0 0 " Expected: " 1) 'v' select last zero and first zeroes " 0 1 " 1 0 " 1 0 func Test_visual_increment_12() call setline(1, repeat(["0 0"], 3)) exec "norm! $v++\" call assert_equal(["0 1", "1 0", "1 0"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) endfunc " 13) visually selected part of columns " Text: " max: 100px " max: 200px " max: 300px " max: 400px " Expected: " 1) 'v' on first two numbers Ctrl-A " max: 110px " max: 220px " max: 330px " max: 400px " 2) 'v' on first two numbers Ctrl-X " max: 90px " max: 190px " max: 290px " max: 400px func Test_visual_increment_13() call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"]) exec "norm! f1\l2j\" call assert_equal(["max: 110px", "max: 210px", "max: 310px", "max: 400px"], getline(1, '$')) call assert_equal([0, 1, 6, 0], getpos('.')) call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"]) exec "norm! ggf1\l2j\" call assert_equal(["max: 90px", "max: 190px", "max: 290px", "max: 400px"], getline(1, '$')) call assert_equal([0, 1, 6, 0], getpos('.')) endfunc " 14) redo in block mode " Text: " 1 1 " 1 1 " Expected: " 1) Ctrl-a on first column, redo on second column " 2 2 " 2 2 func Test_visual_increment_14() call setline(1, repeat(["1 1"], 2)) exec "norm! G\k\w." call assert_equal(["2 2", "2 2"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) endfunc " 15) block select single numbers " Text: " 101 " Expected: " 1) Ctrl-a on visually selected zero " 111 func Test_visual_increment_15() call setline(1, ["101"]) exec "norm! lv\" call assert_equal(["111"], getline(1, '$')) call assert_equal([0, 1, 2, 0], getpos('.')) endfunc " 16) increment right aligned numbers " Text: " 1 " 19 " 119 " Expected: " 1) Ctrl-a on line selected region " 2 " 20 " 120 func Test_visual_increment_16() call setline(1, [" 1", " 19", " 119"]) exec "norm! VG\" call assert_equal([" 2", " 20", " 120"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 17) block-wise increment and redo " Text: " 100 " 1 " " 100 " 1 " " Expected: " 1) Ctrl-V j $ on first block, afterwards '.' on second " 101 " 2 " " 101 " 2 func Test_visual_increment_17() call setline(1, [" 100", " 1", "", " 100", " 1"]) exec "norm! \j$\2j." call assert_equal([" 101", " 2", "", " 101", " 1"], getline(1, '$')) call assert_equal([0, 3, 1, 0], getpos('.')) endfunc " 18) repeat of g " Text: " 0 " 0 " 0 " 0 " " Expected: " 1) V 4j g, repeat twice afterwards with . " 3 " 6 " 9 " 12 func Test_visual_increment_18() call setline(1, repeat(["0"], 4)) exec "norm! GV3kg\" exec "norm! .." call assert_equal(["3", "6", "9", "12"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 19) increment on number with nrformat including alpha " Text: " 1 " 1a " " Expected: " 1) j$ " 2 " 2a func Test_visual_increment_19() set nrformats+=alpha call setline(1, ["1", "1a"]) exec "norm! \G$\" call assert_equal(["2", "2a"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 20) increment a single letter " Text: " a " " Expected: " 1) and cursor is on a " b func Test_visual_increment_20() set nrformats+=alpha call setline(1, ["a"]) exec "norm! \" call assert_equal(["b"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 21) block-wise increment on part of hexadecimal " Text: " 0x123456 " " Expected: " 1) Ctrl-V f3 " 0x124456 func Test_visual_increment_21() call setline(1, ["0x123456"]) exec "norm! \f3\" call assert_equal(["0x124456"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 22) Block increment on 0b0 " Text: " 0b1 " 0b1 " Expected: " 1) Ctrl-A on visually block selected region (cursor at beginning): " 0b10 " 0b10 " 2) Ctrl-A on visually block selected region (cursor at end) " 0b10 " 0b10 func Test_visual_increment_22() call setline(1, repeat(["0b1"], 2)) exec "norm! \j$\" call assert_equal(repeat(["0b10"], 2), getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, repeat(["0b1"], 2)) exec "norm! $\+\" call assert_equal(repeat(["0b10"], 2), getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 23) block-wise increment on part of binary " Text: " 0b1001 " " Expected: " 1) Ctrl-V 5l " 0b1011 func Test_visual_increment_23() call setline(1, ["0b1001"]) exec "norm! \4l\" call assert_equal(["0b1011"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 24) increment hexadecimal " Text: " 0x0b1001 " " Expected: " 1) " 0x0b1002 func Test_visual_increment_24() call setline(1, ["0x0b1001"]) exec "norm! \$\" call assert_equal(["0x0b1002"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 25) increment binary with nrformats including alpha " Text: " 0b1001a " " Expected: " 1) " 0b1010a func Test_visual_increment_25() set nrformats+=alpha call setline(1, ["0b1001a"]) exec "norm! \$\" call assert_equal(["0b1010a"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " 26) increment binary with 32 bits " Text: " 0b11111111111111111111111111111110 " " Expected: " 1) " 0b11111111111111111111111111111111 func Test_visual_increment_26() set nrformats+=alpha call setline(1, ["0b11111111111111111111111111111110"]) exec "norm! \$\" call assert_equal(["0b11111111111111111111111111111111"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) set nrformats-=alpha endfunc " 27) increment with 'rightreft', if supported func Test_visual_increment_27() if exists('+rightleft') set rightleft call setline(1, ["1234 56"]) exec "norm! $\" call assert_equal(["1234 57"], getline(1, '$')) call assert_equal([0, 1, 7, 0], getpos('.')) exec "norm! \" call assert_equal(["1234 58"], getline(1, '$')) call assert_equal([0, 1, 7, 0], getpos('.')) set norightleft endif endfunc " Tab code and linewise-visual inc/dec func Test_visual_increment_28() call setline(1, ["x\10", "\-1"]) exec "norm! Vj\" call assert_equal(["x\11", "\0"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, ["x\10", "\-1"]) exec "norm! ggVj\" call assert_equal(["x\9", "\-2"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " Tab code and linewise-visual inc/dec with 'nrformats'+=alpha func Test_visual_increment_29() set nrformats+=alpha call setline(1, ["x\10", "\-1"]) exec "norm! Vj\" call assert_equal(["y\10", "\0"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) call setline(1, ["x\10", "\-1"]) exec "norm! ggVj\" call assert_equal(["w\10", "\-2"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " Tab code and character-visual inc/dec func Test_visual_increment_30() call setline(1, ["x\10", "\-1"]) exec "norm! f1vjf1\" call assert_equal(["x\11", "\0"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) call setline(1, ["x\10", "\-1"]) exec "norm! ggf1vjf1\" call assert_equal(["x\9", "\-2"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) endfunc " Tab code and blockwise-visual inc/dec func Test_visual_increment_31() call setline(1, ["x\10", "\-1"]) exec "norm! f1\jl\" call assert_equal(["x\11", "\0"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) call setline(1, ["x\10", "\-1"]) exec "norm! ggf1\jl\" call assert_equal(["x\9", "\-2"], getline(1, '$')) call assert_equal([0, 1, 3, 0], getpos('.')) endfunc " Tab code and blockwise-visual decrement with 'linebreak' and 'showbreak' func Test_visual_increment_32() 28vnew dummy_31 set linebreak showbreak=+ call setline(1, ["x\\\10", "\\\\-1"]) exec "norm! ggf0\jg_\" call assert_equal(["x\\\1-1", "\\\\-2"], getline(1, '$')) call assert_equal([0, 1, 6, 0], getpos('.')) bwipe! endfunc " Tab code and blockwise-visual increment with $ func Test_visual_increment_33() call setline(1, ["\123", "456"]) exec "norm! gg0\j$\" call assert_equal(["\124", "457"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " Tab code and blockwise-visual increment and redo func Test_visual_increment_34() call setline(1, ["\123", " 456789"]) exec "norm! gg0\j\" call assert_equal(["\123", " 457789"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) exec "norm! .." call assert_equal(["\123", " 459789"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " Tab code, spaces and character-visual increment and redo func Test_visual_increment_35() call setline(1, ["\123", " 123", "\123", "\123"]) exec "norm! ggvjf3\..." call assert_equal(["\127", " 127", "\123", "\123"], getline(1, '$')) call assert_equal([0, 1, 2, 0], getpos('.')) endfunc " Tab code, spaces and blockwise-visual increment and redo func Test_visual_increment_36() call setline(1, [" 123", "\456789"]) exec "norm! G0\kl\" call assert_equal([" 123", "\556789"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) exec "norm! ..." call assert_equal([" 123", "\856789"], getline(1, '$')) call assert_equal([0, 1, 1, 0], getpos('.')) endfunc " block-wise increment and dot-repeat " Text: " 1 23 " 4 56 " " Expected: " 1) f2 Ctrl-V jl , repeat twice afterwards with . " 1 26 " 4 59 " " Try with and without indent. func Test_visual_increment_37() call setline(1, [" 1 23", " 4 56"]) exec "norm! ggf2\jl\.." call assert_equal([" 1 26", " 4 59"], getline(1, 2)) call setline(1, ["1 23", "4 56"]) exec "norm! ggf2\jl\.." call assert_equal(["1 26", "4 59"], getline(1, 2)) endfunc " Check redo after the normal mode increment func Test_visual_increment_38() exec "norm! i10\5\." call assert_equal(["20"], getline(1, '$')) call assert_equal([0, 1, 2, 0], getpos('.')) endfunc " Test what patch 7.3.414 fixed. Ctrl-A on "000" drops the leading zeros. func Test_normal_increment_01() call setline(1, "000") exec "norm! gg0\" call assert_equal("001", getline(1)) call setline(1, "000") exec "norm! gg$\" call assert_equal("001", getline(1)) call setline(1, "001") exec "norm! gg0\" call assert_equal("002", getline(1)) call setline(1, "001") exec "norm! gg$\" call assert_equal("002", getline(1)) endfunc " Test a regression of patch 7.4.1087 fixed. func Test_normal_increment_02() call setline(1, ["hello 10", "world"]) exec "norm! ggl\jx" call assert_equal(["hello 11", "worl"], getline(1, '$')) call assert_equal([0, 2, 4, 0], getpos('.')) endfunc ]=]) end) for i = 1, 38 do local id = string.format('%02d', i) it('works on Test ' .. id, function() command('set nrformats&vi') -- &vi makes Vim compatible call('Test_visual_increment_' .. id) eq({}, nvim.get_vvar('errors')) end) end it('does not drop leading zeroes', function() command('set nrformats&vi') -- &vi makes Vim compatible call('Test_normal_increment_01') eq({}, nvim.get_vvar('errors')) end) it('maintains correct column after CTRL-A', function() call('Test_normal_increment_02') eq({}, nvim.get_vvar('errors')) end) end)