diff options
Diffstat (limited to 'src/nvim/testdir/test_mapping.vim')
-rw-r--r-- | src/nvim/testdir/test_mapping.vim | 569 |
1 files changed, 565 insertions, 4 deletions
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index f88e8cf843..e1d0b9a9ba 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -1,6 +1,8 @@ " Tests for mappings and abbreviations source shared.vim +source check.vim +source screendump.vim func Test_abbreviation() " abbreviation with 0x80 should work @@ -29,6 +31,7 @@ func Test_abclear() abclear call assert_equal("\n\nNo abbreviation found", execute('abbrev')) + call assert_fails('%abclear', 'E481:') endfunc func Test_abclear_buffer() @@ -60,7 +63,7 @@ func Test_map_ctrl_c_insert() inoremap <c-c> <ctrl-c> cnoremap <c-c> dummy cunmap <c-c> - call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt") + call feedkeys("GoTEST2: CTRL-C |\<*C-C>A|\<Esc>", "xt") call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$')) unmap! <c-c> set nomodified @@ -69,7 +72,7 @@ endfunc func Test_map_ctrl_c_visual() " mapping of ctrl-c in Visual mode vnoremap <c-c> :<C-u>$put ='vmap works' - call feedkeys("GV\<C-C>\<CR>", "xt") + call feedkeys("GV\<*C-C>\<CR>", "xt") call assert_equal('vmap works', getline('$')) vunmap <c-c> set nomodified @@ -219,7 +222,7 @@ endfunc func Test_map_meta_quotes() imap <M-"> foo - call feedkeys("Go-\<M-\">-\<Esc>", "xt") + call feedkeys("Go-\<*M-\">-\<Esc>", "xt") call assert_equal("-foo-", getline('$')) set nomodified iunmap <M-"> @@ -427,6 +430,85 @@ func Test_error_in_map_expr() exe buf .. 'bwipe!' endfunc +func Test_list_mappings() + " Remove default mappings + imapclear + + " reset 'isident' to check it isn't used + set isident= + inoremap <C-m> CtrlM + inoremap <A-S> AltS + inoremap <S-/> ShiftSlash + set isident& + call assert_equal([ + \ 'i <S-/> * ShiftSlash', + \ 'i <M-S> * AltS', + \ 'i <C-M> * CtrlM', + \], execute('imap')->trim()->split("\n")) + iunmap <C-M> + iunmap <A-S> + call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n")) + iunmap <S-/> + call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n")) + + " List global, buffer local and script local mappings + nmap ,f /^\k\+ (<CR> + nmap <buffer> ,f /^\k\+ (<CR> + nmap <script> ,fs /^\k\+ (<CR> + call assert_equal(['n ,f @/^\k\+ (<CR>', + \ 'n ,fs & /^\k\+ (<CR>', + \ 'n ,f /^\k\+ (<CR>'], + \ execute('nmap ,f')->trim()->split("\n")) + + " List <Nop> mapping + nmap ,n <Nop> + call assert_equal(['n ,n <Nop>'], + \ execute('nmap ,n')->trim()->split("\n")) + + " verbose map + call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$", + \ execute('verbose map ,n')->trim()->split("\n")[1]) + + " character with K_SPECIAL byte in rhs + nmap foo … + call assert_equal(['n foo …'], + \ execute('nmap foo')->trim()->split("\n")) + + " modified character with K_SPECIAL byte in rhs + nmap foo <M-…> + call assert_equal(['n foo <M-…>'], + \ execute('nmap foo')->trim()->split("\n")) + + " character with K_SPECIAL byte in lhs + nmap … foo + call assert_equal(['n … foo'], + \ execute('nmap …')->trim()->split("\n")) + + " modified character with K_SPECIAL byte in lhs + nmap <M-…> foo + call assert_equal(['n <M-…> foo'], + \ execute('nmap <M-…>')->trim()->split("\n")) + + " illegal bytes + let str = ":\x7f:\x80:\x90:\xd0:" + exe 'nmap foo ' .. str + call assert_equal(['n foo ' .. strtrans(str)], + \ execute('nmap foo')->trim()->split("\n")) + unlet str + + " map to CTRL-V + exe "nmap ,k \<C-V>" + call assert_equal(['n ,k <Nop>'], + \ execute('nmap ,k')->trim()->split("\n")) + + " map with space at the beginning + exe "nmap \<C-V> w <Nop>" + call assert_equal(['n <Space>w <Nop>'], + \ execute("nmap \<C-V> w")->trim()->split("\n")) + + nmapclear +endfunc + func Test_expr_map_gets_cursor() new call setline(1, ['one', 'some w!rd']) @@ -451,6 +533,82 @@ func Test_expr_map_gets_cursor() nunmap ! endfunc +func Test_expr_map_restore_cursor() + CheckScreendump + + let lines =<< trim END + call setline(1, ['one', 'two', 'three']) + 2 + set ls=2 + hi! link StatusLine ErrorMsg + noremap <expr> <C-B> Func() + func Func() + let g:on = !get(g:, 'on', 0) + redraws + return '' + endfunc + func Status() + return get(g:, 'on', 0) ? '[on]' : '' + endfunc + set stl=%{Status()} + END + call writefile(lines, 'XtestExprMap') + let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10}) + call term_sendkeys(buf, "\<C-B>") + call VerifyScreenDump(buf, 'Test_map_expr_1', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestExprMap') +endfunc + +func Test_map_listing() + CheckScreendump + + let lines =<< trim END + nmap a b + END + call writefile(lines, 'XtestMapList') + let buf = RunVimInTerminal('-S XtestMapList', #{rows: 6}) + call term_sendkeys(buf, ": nmap a\<CR>") + call VerifyScreenDump(buf, 'Test_map_list_1', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestMapList') +endfunc + +func Test_expr_map_error() + CheckScreendump + + let lines =<< trim END + func Func() + throw 'test' + return '' + endfunc + + nnoremap <expr> <F2> Func() + cnoremap <expr> <F2> Func() + + call test_override('ui_delay', 10) + END + call writefile(lines, 'XtestExprMap') + let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10}) + call term_sendkeys(buf, "\<F2>") + call TermWait(buf) + call term_sendkeys(buf, "\<CR>") + call VerifyScreenDump(buf, 'Test_map_expr_2', {}) + + call term_sendkeys(buf, ":abc\<F2>") + call VerifyScreenDump(buf, 'Test_map_expr_3', {}) + call term_sendkeys(buf, "\<Esc>0") + call VerifyScreenDump(buf, 'Test_map_expr_4', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestExprMap') +endfunc + " Test for mapping errors func Test_map_error() call assert_fails('unmap', 'E474:') @@ -476,6 +634,22 @@ func Test_map_error() call assert_fails('mapclear abc', 'E474:') call assert_fails('abclear abc', 'E474:') + call assert_fails('abbr $xyz abc', 'E474:') + + " space character in an abbreviation + call assert_fails('abbr ab<space> ABC', 'E474:') + + " invalid <expr> map + map <expr> ,f abc + call assert_fails('normal ,f', 'E121:') + unmap <expr> ,f + + " Recursive use of :normal in a map + set maxmapdepth=100 + map gq :normal gq<CR> + call assert_fails('normal gq', 'E192:') + unmap gq + set maxmapdepth& endfunc " Test for <special> key mapping @@ -503,11 +677,66 @@ endfunc " Test for hasmapto() func Test_hasmapto() call assert_equal(0, hasmapto('/^\k\+ (')) + map ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (')) + unmap ,f + + " Insert mode mapping + call assert_equal(0, hasmapto('/^\k\+ (', 'i')) + imap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'i')) + iunmap ,f + + " Normal mode mapping call assert_equal(0, hasmapto('/^\k\+ (', 'n')) nmap ,f /^\k\+ (<CR> call assert_equal(1, hasmapto('/^\k\+ (')) call assert_equal(1, hasmapto('/^\k\+ (', 'n')) + nunmap ,f + + " Visual and Select mode mapping call assert_equal(0, hasmapto('/^\k\+ (', 'v')) + call assert_equal(0, hasmapto('/^\k\+ (', 'x')) + call assert_equal(0, hasmapto('/^\k\+ (', 's')) + vmap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'v')) + call assert_equal(1, hasmapto('/^\k\+ (', 'x')) + call assert_equal(1, hasmapto('/^\k\+ (', 's')) + vunmap ,f + + " Visual mode mapping + call assert_equal(0, hasmapto('/^\k\+ (', 'x')) + xmap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'v')) + call assert_equal(1, hasmapto('/^\k\+ (', 'x')) + call assert_equal(0, hasmapto('/^\k\+ (', 's')) + xunmap ,f + + " Select mode mapping + call assert_equal(0, hasmapto('/^\k\+ (', 's')) + smap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'v')) + call assert_equal(0, hasmapto('/^\k\+ (', 'x')) + call assert_equal(1, hasmapto('/^\k\+ (', 's')) + sunmap ,f + + " Operator-pending mode mapping + call assert_equal(0, hasmapto('/^\k\+ (', 'o')) + omap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'o')) + ounmap ,f + + " Language mapping + call assert_equal(0, hasmapto('/^\k\+ (', 'l')) + lmap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'l')) + lunmap ,f + + " Cmdline mode mapping + call assert_equal(0, hasmapto('/^\k\+ (', 'c')) + cmap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (', 'c')) + cunmap ,f call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1)) endfunc @@ -519,8 +748,176 @@ func Test_mapcomplete() \ getcompletion('', 'mapping')) call assert_equal([], getcompletion(',d', 'mapping')) + call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"unmap <buffer>', @:) + + call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"unabbr <buffer>', @:) + call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match("abbr! \x01", @:) + call assert_equal("\"abbr! \x01", @:) + + " Multiple matches for a map + nmap ,f /H<CR> + omap ,f /H<CR> + call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"map ,f', @:) + mapclear +endfunc + +" Test for <expr> in abbreviation +func Test_expr_abbr() + new + iabbr <expr> teh "the" + call feedkeys("iteh ", "tx") + call assert_equal('the ', getline(1)) + iabclear + call setline(1, '') + + " invalid <expr> abbreviation + abbr <expr> hte GetAbbr() + call assert_fails('normal ihte ', 'E117:') + call assert_equal(' ', getline(1)) + unabbr <expr> hte + + close! +endfunc + +" Test for storing mappings in different modes in a vimrc file +func Test_mkvimrc_mapmodes() + map a1 /a1 + nmap a2 /a2 + vmap a3 /a3 + smap a4 /a4 + xmap a5 /a5 + omap a6 /a6 + map! a7 /a7 + imap a8 /a8 + lmap a9 /a9 + cmap a10 /a10 + tmap a11 /a11 + " Normal + Visual map + map a12 /a12 + sunmap a12 + ounmap a12 + " Normal + Selectmode map + map a13 /a13 + xunmap a13 + ounmap a13 + " Normal + OpPending map + map a14 /a14 + vunmap a14 + " Visual + Selectmode map + map a15 /a15 + nunmap a15 + ounmap a15 + " Visual + OpPending map + map a16 /a16 + nunmap a16 + sunmap a16 + " Selectmode + OpPending map + map a17 /a17 + nunmap a17 + xunmap a17 + " Normal + Visual + Selectmode map + map a18 /a18 + ounmap a18 + " Normal + Visual + OpPending map + map a19 /a19 + sunmap a19 + " Normal + Selectmode + OpPending map + map a20 /a20 + xunmap a20 + " Visual + Selectmode + OpPending map + map a21 /a21 + nunmap a21 + " Mapping to Nop + map a22 <Nop> + " Script local mapping + map <script> a23 /a23 + + " Newline in {lhs} and {rhs} of a map + exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>" + + " Abbreviation + abbr a25 A25 + cabbr a26 A26 + iabbr a27 A27 + + mkvimrc! Xvimrc + let l = readfile('Xvimrc') + call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "')) + call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "')) + call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "')) + call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "')) + call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "')) + call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "')) + call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "')) + call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "')) + call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "')) + call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "')) + call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "')) + call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'], + \ filter(copy(l), 'v:val =~ " a12 "')) + call assert_equal(['nmap a13 /a13', 'smap a13 /a13'], + \ filter(copy(l), 'v:val =~ " a13 "')) + call assert_equal(['nmap a14 /a14', 'omap a14 /a14'], + \ filter(copy(l), 'v:val =~ " a14 "')) + call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "')) + call assert_equal(['xmap a16 /a16', 'omap a16 /a16'], + \ filter(copy(l), 'v:val =~ " a16 "')) + call assert_equal(['smap a17 /a17', 'omap a17 /a17'], + \ filter(copy(l), 'v:val =~ " a17 "')) + call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'], + \ filter(copy(l), 'v:val =~ " a18 "')) + call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'], + \ filter(copy(l), 'v:val =~ " a19 "')) + call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'], + \ filter(copy(l), 'v:val =~ " a20 "')) + call assert_equal(['vmap a21 /a21', 'omap a21 /a21'], + \ filter(copy(l), 'v:val =~ " a21 "')) + call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "')) + call assert_equal([], filter(copy(l), 'v:val =~ " a23 "')) + call assert_equal(["map a24<NL> ia24<NL>\x16\e"], + \ filter(copy(l), 'v:val =~ " a24"')) + + call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "')) + call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "')) + call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "')) + call delete('Xvimrc') + + mapclear + nmapclear + vmapclear + xmapclear + smapclear + omapclear + imapclear + lmapclear + cmapclear + tmapclear +endfunc + +" Test for recursive mapping ('maxmapdepth') +func Test_map_recursive() + map x y + map y x + call assert_fails('normal x', 'E223:') + unmap x + unmap y +endfunc + +" Test for removing an abbreviation using {rhs} and with space after {lhs} +func Test_abbr_remove() + abbr foo bar + let d = maparg('foo', 'i', 1, 1) + call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode]) + unabbr bar + call assert_equal({}, maparg('foo', 'i', 1, 1)) + + abbr foo bar + unabbr foo<space><tab> + call assert_equal({}, maparg('foo', 'i', 1, 1)) endfunc func Test_map_cmdkey_redo() @@ -559,6 +956,16 @@ func Test_map_cmdkey_redo() ounmap i- endfunc +" Test for using <script> with a map to remap characters in rhs +func Test_script_local_remap() + new + inoremap <buffer> <SID>xyz mno + inoremap <buffer> <script> abc st<SID>xyzre + normal iabc + call assert_equal('stmnore', getline(1)) + bwipe! +endfunc + func Test_abbreviate_multi_byte() new iabbrev foo bar @@ -568,4 +975,158 @@ func Test_abbreviate_multi_byte() bwipe! endfunc +" Test for <Plug> always being mapped, even when used with "noremap". +func Test_plug_remap() + let g:foo = 0 + nnoremap <Plug>(Increase_x) <Cmd>let g:foo += 1<CR> + nmap <F2> <Plug>(Increase_x) + nnoremap <F3> <Plug>(Increase_x) + call feedkeys("\<F2>", 'xt') + call assert_equal(1, g:foo) + call feedkeys("\<F3>", 'xt') + call assert_equal(2, g:foo) + nnoremap x <Nop> + nmap <F4> x<Plug>(Increase_x)x + nnoremap <F5> x<Plug>(Increase_x)x + call setline(1, 'Some text') + normal! gg$ + call feedkeys("\<F4>", 'xt') + call assert_equal(3, g:foo) + call assert_equal('Some text', getline(1)) + call feedkeys("\<F5>", 'xt') + call assert_equal(4, g:foo) + call assert_equal('Some te', getline(1)) + nunmap <Plug>(Increase_x) + nunmap <F2> + nunmap <F3> + nunmap <F4> + nunmap <F5> + unlet g:foo + %bw! +endfunc + +func Test_mouse_drag_mapped_start_select() + CheckFunction test_setmouse + set mouse=a + set selectmode=key,mouse + func ClickExpr() + call test_setmouse(1, 1) + return "\<LeftMouse>" + endfunc + func DragExpr() + call test_setmouse(1, 2) + return "\<LeftDrag>" + endfunc + nnoremap <expr> <F2> ClickExpr() + nmap <expr> <F3> DragExpr() + + nnoremap <LeftDrag> <LeftDrag><Cmd><CR> + exe "normal \<F2>\<F3>" + call assert_equal('s', mode()) + exe "normal! \<C-\>\<C-N>" + + nunmap <LeftDrag> + nunmap <F2> + nunmap <F3> + delfunc ClickExpr + delfunc DragExpr + set selectmode& + set mouse& +endfunc + +" Test for mapping <LeftDrag> in Insert mode +func Test_mouse_drag_insert_map() + CheckFunction test_setmouse + set mouse=a + func ClickExpr() + call test_setmouse(1, 1) + return "\<LeftMouse>" + endfunc + func DragExpr() + call test_setmouse(1, 2) + return "\<LeftDrag>" + endfunc + inoremap <expr> <F2> ClickExpr() + imap <expr> <F3> DragExpr() + + inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR> + exe "normal i\<F2>\<F3>" + call assert_equal(1, g:dragged) + call assert_equal('v', mode()) + exe "normal! \<C-\>\<C-N>" + unlet g:dragged + + inoremap <LeftDrag> <LeftDrag><C-\><C-N> + exe "normal i\<F2>\<F3>" + call assert_equal('n', mode()) + + iunmap <LeftDrag> + iunmap <F2> + iunmap <F3> + delfunc ClickExpr + delfunc DragExpr + set mouse& +endfunc + +func Test_unmap_simplifiable() + map <C-I> foo + map <Tab> bar + call assert_equal('foo', maparg('<C-I>')) + call assert_equal('bar', maparg('<Tab>')) + unmap <C-I> + call assert_equal('', maparg('<C-I>')) + call assert_equal('bar', maparg('<Tab>')) + unmap <Tab> + + map <C-I> foo + unmap <Tab> + " This should not error + unmap <C-I> +endfunc + +func Test_expr_map_escape_special() + nnoremap … <Cmd>let g:got_ellipsis += 1<CR> + func Func() + return '…' + endfunc + nmap <expr> <F2> Func() + let g:got_ellipsis = 0 + call feedkeys("\<F2>", 'xt') + call assert_equal(1, g:got_ellipsis) + delfunc Func + nunmap <F2> + unlet g:got_ellipsis + nunmap … +endfunc + +" Testing for mapping after an <Nop> mapping is triggered on timeout. +" Test for what patch 8.1.0052 fixes. +func Test_map_after_timed_out_nop() + CheckRunVimInTerminal + + let lines =<< trim END + set timeout timeoutlen=400 + inoremap ab TEST + inoremap a <Nop> + END + call writefile(lines, 'Xtest_map_after_timed_out_nop') + let buf = RunVimInTerminal('-S Xtest_map_after_timed_out_nop', #{rows: 6}) + + " Enter Insert mode + call term_sendkeys(buf, 'i') + " Wait for the "a" mapping to timeout + call term_sendkeys(buf, 'a') + call term_wait(buf, 500) + " Send "a" and wait for a period shorter than 'timeoutlen' + call term_sendkeys(buf, 'a') + call term_wait(buf, 100) + " Send "b", should trigger the "ab" mapping + call term_sendkeys(buf, 'b') + call WaitForAssert({-> assert_equal("TEST", term_getline(buf, 1))}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_map_after_timed_out_nop') +endfunc + " vim: shiftwidth=2 sts=2 expandtab |