1" Tests for mappings and abbreviations 2 3source shared.vim 4source check.vim 5source screendump.vim 6source term_util.vim 7 8func Test_abbreviation() 9 " abbreviation with 0x80 should work 10 inoreab чкпр vim 11 call feedkeys("Goчкпр \<Esc>", "xt") 12 call assert_equal('vim ', getline('$')) 13 iunab чкпр 14 set nomodified 15endfunc 16 17func Test_abclear() 18 abbrev foo foobar 19 iabbrev fooi foobari 20 cabbrev fooc foobarc 21 call assert_equal("\n\n" 22 \ .. "c fooc foobarc\n" 23 \ .. "i fooi foobari\n" 24 \ .. "! foo foobar", execute('abbrev')) 25 26 iabclear 27 call assert_equal("\n\n" 28 \ .. "c fooc foobarc\n" 29 \ .. "c foo foobar", execute('abbrev')) 30 abbrev foo foobar 31 iabbrev fooi foobari 32 33 cabclear 34 call assert_equal("\n\n" 35 \ .. "i fooi foobari\n" 36 \ .. "i foo foobar", execute('abbrev')) 37 abbrev foo foobar 38 cabbrev fooc foobarc 39 40 abclear 41 call assert_equal("\n\nNo abbreviation found", execute('abbrev')) 42 call assert_fails('%abclear', 'E481:') 43endfunc 44 45func Test_abclear_buffer() 46 abbrev foo foobar 47 new X1 48 abbrev <buffer> foo1 foobar1 49 new X2 50 abbrev <buffer> foo2 foobar2 51 52 call assert_equal("\n\n" 53 \ .. "! foo2 @foobar2\n" 54 \ .. "! foo foobar", execute('abbrev')) 55 56 abclear <buffer> 57 call assert_equal("\n\n" 58 \ .. "! foo foobar", execute('abbrev')) 59 60 b X1 61 call assert_equal("\n\n" 62 \ .. "! foo1 @foobar1\n" 63 \ .. "! foo foobar", execute('abbrev')) 64 abclear <buffer> 65 call assert_equal("\n\n" 66 \ .. "! foo foobar", execute('abbrev')) 67 68 abclear 69 call assert_equal("\n\nNo abbreviation found", execute('abbrev')) 70 71 %bwipe 72endfunc 73 74func Test_map_ctrl_c_insert() 75 " mapping of ctrl-c in Insert mode 76 set cpo-=< cpo-=k 77 inoremap <c-c> <ctrl-c> 78 cnoremap <c-c> dummy 79 cunmap <c-c> 80 call feedkeys("GoTEST2: CTRL-C |\<*C-C>A|\<Esc>", "xt") 81 call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$')) 82 unmap! <c-c> 83 set nomodified 84endfunc 85 86func Test_map_ctrl_c_visual() 87 " mapping of ctrl-c in Visual mode 88 vnoremap <c-c> :<C-u>$put ='vmap works' 89 call feedkeys("GV\<*C-C>\<CR>", "xt") 90 call assert_equal('vmap works', getline('$')) 91 vunmap <c-c> 92 set nomodified 93endfunc 94 95func Test_map_langmap() 96 CheckFeature langmap 97 98 " check langmap applies in normal mode 99 set langmap=+- nolangremap 100 new 101 call setline(1, ['a', 'b', 'c']) 102 2 103 call assert_equal('b', getline('.')) 104 call feedkeys("+", "xt") 105 call assert_equal('a', getline('.')) 106 107 " check no remapping 108 map x + 109 2 110 call feedkeys("x", "xt") 111 call assert_equal('c', getline('.')) 112 113 " check with remapping 114 set langremap 115 2 116 call feedkeys("x", "xt") 117 call assert_equal('a', getline('.')) 118 119 unmap x 120 bwipe! 121 122 " 'langnoremap' follows 'langremap' and vise versa 123 set langremap 124 set langnoremap 125 call assert_equal(0, &langremap) 126 set langremap 127 call assert_equal(0, &langnoremap) 128 set nolangremap 129 call assert_equal(1, &langnoremap) 130 131 " check default values 132 set langnoremap& 133 call assert_equal(0, &langnoremap) 134 call assert_equal(1, &langremap) 135 set langremap& 136 call assert_equal(0, &langnoremap) 137 call assert_equal(1, &langremap) 138 139 " langmap should not apply in insert mode, 'langremap' doesn't matter 140 set langmap=+{ nolangremap 141 call feedkeys("Go+\<Esc>", "xt") 142 call assert_equal('+', getline('$')) 143 set langmap=+{ langremap 144 call feedkeys("Go+\<Esc>", "xt") 145 call assert_equal('+', getline('$')) 146 147 " langmap used for register name in insert mode. 148 call setreg('a', 'aaaa') 149 call setreg('b', 'bbbb') 150 call setreg('c', 'cccc') 151 set langmap=ab langremap 152 call feedkeys("Go\<C-R>a\<Esc>", "xt") 153 call assert_equal('bbbb', getline('$')) 154 call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt") 155 call assert_equal('bbbb', getline('$')) 156 " mapping does not apply 157 imap c a 158 call feedkeys("Go\<C-R>c\<Esc>", "xt") 159 call assert_equal('cccc', getline('$')) 160 imap a c 161 call feedkeys("Go\<C-R>a\<Esc>", "xt") 162 call assert_equal('bbbb', getline('$')) 163 164 " langmap should not apply in Command-line mode 165 set langmap=+{ nolangremap 166 call feedkeys(":call append(line('$'), '+')\<CR>", "xt") 167 call assert_equal('+', getline('$')) 168 169 iunmap a 170 iunmap c 171 set nomodified 172endfunc 173 174func Test_map_feedkeys() 175 " issue #212 (feedkeys insert mapping at current position) 176 nnoremap . :call feedkeys(".", "in")<cr> 177 call setline('$', ['a b c d', 'a b c d']) 178 $-1 179 call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt") 180 call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$'))) 181 nunmap . 182 set nomodified 183endfunc 184 185func Test_map_cursor() 186 " <c-g>U<cursor> works only within a single line 187 imapclear 188 imap ( ()<c-g>U<left> 189 call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt") 190 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2)) 191 call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1)) 192 193 " test undo 194 call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt") 195 call assert_equal('', getline(line('$') - 2)) 196 call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1)) 197 set nomodified 198 imapclear 199endfunc 200 201func Test_map_cursor_ctrl_gU() 202 " <c-g>U<cursor> works only within a single line 203 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left> 204 call setline(1, ['foo', 'foobar', '', 'foo']) 205 call cursor(1,2) 206 call feedkeys("c<*PREFIX\<esc>.", 'xt') 207 call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$')) 208 " break undo manually 209 set ul=1000 210 exe ":norm! uu" 211 call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$')) 212 213 " Test that it does not work if the cursor moves to the previous line 214 " 2 times <S-Left> move to the previous line 215 nnoremap c<* *Ncgn<C-r>"<C-G>U<S-Left><C-G>U<S-Left> 216 call setline(1, ['', ' foo', 'foobar', '', 'foo']) 217 call cursor(2,3) 218 call feedkeys("c<*PREFIX\<esc>.", 'xt') 219 call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$')) 220 nmapclear 221endfunc 222 223 224" This isn't actually testing a mapping, but similar use of CTRL-G U as above. 225func Test_break_undo() 226 set whichwrap=<,>,[,] 227 call feedkeys("G4o2k", "xt") 228 exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>." 229 call assert_equal('new line here', getline(line('$') - 3)) 230 call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2)) 231 call assert_equal('new line here', getline(line('$') - 1)) 232 set nomodified 233endfunc 234 235func Test_map_meta_quotes() 236 imap <M-"> foo 237 call feedkeys("Go-\<*M-\">-\<Esc>", "xt") 238 call assert_equal("-foo-", getline('$')) 239 set nomodified 240 iunmap <M-"> 241endfunc 242 243func Test_map_meta_multibyte() 244 imap <M-á> foo 245 call assert_match('i <M-á>\s*foo', execute('imap')) 246 iunmap <M-á> 247endfunc 248 249func Test_abbr_after_line_join() 250 new 251 abbr foo bar 252 set backspace=indent,eol,start 253 exe "normal o\<BS>foo " 254 call assert_equal("bar ", getline(1)) 255 bwipe! 256 unabbr foo 257 set backspace& 258endfunc 259 260func Test_map_timeout() 261 CheckFeature timers 262 nnoremap aaaa :let got_aaaa = 1<CR> 263 nnoremap bb :let got_bb = 1<CR> 264 nmap b aaa 265 new 266 func ExitInsert(timer) 267 let g:line = getline(1) 268 call feedkeys("\<Esc>", "t") 269 endfunc 270 set timeout timeoutlen=200 271 let timer = timer_start(300, 'ExitInsert') 272 " After the 'b' Vim waits for another character to see if it matches 'bb'. 273 " When it times out it is expanded to "aaa", but there is no wait for 274 " "aaaa". Can't check that reliably though. 275 call feedkeys("b", "xt!") 276 call assert_equal("aa", g:line) 277 call assert_false(exists('got_aaa')) 278 call assert_false(exists('got_bb')) 279 280 bwipe! 281 nunmap aaaa 282 nunmap bb 283 nunmap b 284 set timeoutlen& 285 delfunc ExitInsert 286 call timer_stop(timer) 287endfunc 288 289func Test_map_timeout_with_timer_interrupt() 290 CheckFeature job 291 CheckFeature timers 292 293 " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key 294 " sequence. 295 new 296 let g:val = 0 297 nnoremap \12 :let g:val = 1<CR> 298 nnoremap \123 :let g:val = 2<CR> 299 set timeout timeoutlen=200 300 301 func ExitCb(job, status) 302 let g:timer = timer_start(1, {-> feedkeys("3\<Esc>", 't')}) 303 endfunc 304 305 call job_start([&shell, &shellcmdflag, 'echo'], {'exit_cb': 'ExitCb'}) 306 call feedkeys('\12', 'xt!') 307 call assert_equal(2, g:val) 308 309 bwipe! 310 nunmap \12 311 nunmap \123 312 set timeoutlen& 313 call WaitFor({-> exists('g:timer')}) 314 call timer_stop(g:timer) 315 unlet g:timer 316 unlet g:val 317 delfunc ExitCb 318endfunc 319 320func Test_abbreviation_CR() 321 new 322 func Eatchar(pat) 323 let c = nr2char(getchar(0)) 324 return (c =~ a:pat) ? '' : c 325 endfunc 326 iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr> 327 call feedkeys("GA~~7 \<esc>", 'xt') 328 call assert_equal('~~~~~~~', getline('$')) 329 %d 330 call feedkeys("GA~~7\<cr>\<esc>", 'xt') 331 call assert_equal(['~~~~~~~', ''], getline(1,'$')) 332 delfunc Eatchar 333 bw! 334endfunc 335 336func Test_cabbr_visual_mode() 337 cabbr s su 338 call feedkeys(":s \<c-B>\"\<CR>", 'itx') 339 call assert_equal('"su ', getreg(':')) 340 call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx') 341 let expected = '"'. "'<,'>su " 342 call assert_equal(expected, getreg(':')) 343 call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx') 344 let expected = '" '. "'<,'>su " 345 call assert_equal(expected, getreg(':')) 346 call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx') 347 let expected = '"'. "'a,'bsu " 348 call assert_equal(expected, getreg(':')) 349 cunabbr s 350endfunc 351 352func Test_motionforce_omap() 353 func GetCommand() 354 let g:m=mode(1) 355 let [g:lnum1, g:col1] = searchpos('-', 'Wb') 356 if g:lnum1 == 0 357 return "\<Esc>" 358 endif 359 let [g:lnum2, g:col2] = searchpos('-', 'W') 360 if g:lnum2 == 0 361 return "\<Esc>" 362 endif 363 return ":call Select()\<CR>" 364 endfunc 365 func Select() 366 call cursor([g:lnum1, g:col1]) 367 exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2]) 368 call cursor([g:lnum2, g:col2]) 369 execute "normal! \<BS>" 370 endfunc 371 new 372 onoremap <buffer><expr> i- GetCommand() 373 " 1) default omap mapping 374 %d_ 375 call setline(1, ['aaa - bbb', 'x', 'ddd - eee']) 376 call cursor(2, 1) 377 norm di- 378 call assert_equal('no', g:m) 379 call assert_equal(['aaa -- eee'], getline(1, '$')) 380 " 2) forced characterwise operation 381 %d_ 382 call setline(1, ['aaa - bbb', 'x', 'ddd - eee']) 383 call cursor(2, 1) 384 norm dvi- 385 call assert_equal('nov', g:m) 386 call assert_equal(['aaa -- eee'], getline(1, '$')) 387 " 3) forced linewise operation 388 %d_ 389 call setline(1, ['aaa - bbb', 'x', 'ddd - eee']) 390 call cursor(2, 1) 391 norm dVi- 392 call assert_equal('noV', g:m) 393 call assert_equal([''], getline(1, '$')) 394 " 4) forced blockwise operation 395 %d_ 396 call setline(1, ['aaa - bbb', 'x', 'ddd - eee']) 397 call cursor(2, 1) 398 exe "norm d\<C-V>i-" 399 call assert_equal("no\<C-V>", g:m) 400 call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$')) 401 bwipe! 402 delfunc Select 403 delfunc GetCommand 404endfunc 405 406func Test_error_in_map_expr() 407 " Unlike CheckRunVimInTerminal this does work in a win32 console 408 CheckFeature terminal 409 if has('win32') && has('gui_running') 410 throw 'Skipped: cannot run Vim in a terminal window' 411 endif 412 413 let lines =<< trim [CODE] 414 func Func() 415 " fail to create list 416 let x = [ 417 endfunc 418 nmap <expr> ! Func() 419 set updatetime=50 420 [CODE] 421 call writefile(lines, 'Xtest.vim') 422 423 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8}) 424 let job = term_getjob(buf) 425 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))}) 426 427 " GC must not run during map-expr processing, which can make Vim crash. 428 call term_sendkeys(buf, '!') 429 call TermWait(buf, 50) 430 call term_sendkeys(buf, "\<CR>") 431 call TermWait(buf, 50) 432 call assert_equal('run', job_status(job)) 433 434 call term_sendkeys(buf, ":qall!\<CR>") 435 call WaitFor({-> job_status(job) ==# 'dead'}) 436 if has('unix') 437 call assert_equal('', job_info(job).termsig) 438 endif 439 440 call delete('Xtest.vim') 441 exe buf .. 'bwipe!' 442endfunc 443 444func Test_list_mappings() 445 " Remove default mappings 446 imapclear 447 448 inoremap <C-M> CtrlM 449 inoremap <A-S> AltS 450 inoremap <S-/> ShiftSlash 451 call assert_equal([ 452 \ 'i <S-/> * ShiftSlash', 453 \ 'i <M-S> * AltS', 454 \ 'i <C-M> * CtrlM', 455 \], execute('imap')->trim()->split("\n")) 456 iunmap <C-M> 457 iunmap <A-S> 458 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n")) 459 iunmap <S-/> 460 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n")) 461 462 " List global, buffer local and script local mappings 463 nmap ,f /^\k\+ (<CR> 464 nmap <buffer> ,f /^\k\+ (<CR> 465 nmap <script> ,fs /^\k\+ (<CR> 466 call assert_equal(['n ,f @/^\k\+ (<CR>', 467 \ 'n ,fs & /^\k\+ (<CR>', 468 \ 'n ,f /^\k\+ (<CR>'], 469 \ execute('nmap ,f')->trim()->split("\n")) 470 471 " List <Nop> mapping 472 nmap ,n <Nop> 473 call assert_equal(['n ,n <Nop>'], 474 \ execute('nmap ,n')->trim()->split("\n")) 475 476 " verbose map 477 call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$", 478 \ execute('verbose map ,n')->trim()->split("\n")[1]) 479 480 " map to CTRL-V 481 exe "nmap ,k \<C-V>" 482 call assert_equal(['n ,k <Nop>'], 483 \ execute('nmap ,k')->trim()->split("\n")) 484 485 nmapclear 486endfunc 487 488func Test_expr_map_gets_cursor() 489 new 490 call setline(1, ['one', 'some w!rd']) 491 func StoreColumn() 492 let g:exprLine = line('.') 493 let g:exprCol = col('.') 494 return 'x' 495 endfunc 496 nnoremap <expr> x StoreColumn() 497 2 498 nmap ! f!<Ignore>x 499 call feedkeys("!", 'xt') 500 call assert_equal('some wrd', getline(2)) 501 call assert_equal(2, g:exprLine) 502 call assert_equal(7, g:exprCol) 503 504 bwipe! 505 unlet g:exprLine 506 unlet g:exprCol 507 delfunc StoreColumn 508 nunmap x 509 nunmap ! 510endfunc 511 512func Test_expr_map_restore_cursor() 513 CheckScreendump 514 515 let lines =<< trim END 516 call setline(1, ['one', 'two', 'three']) 517 2 518 set ls=2 519 hi! link StatusLine ErrorMsg 520 noremap <expr> <C-B> Func() 521 func Func() 522 let g:on = !get(g:, 'on', 0) 523 redraws 524 return '' 525 endfunc 526 func Status() 527 return get(g:, 'on', 0) ? '[on]' : '' 528 endfunc 529 set stl=%{Status()} 530 END 531 call writefile(lines, 'XtestExprMap') 532 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10}) 533 call TermWait(buf) 534 call term_sendkeys(buf, "\<C-B>") 535 call VerifyScreenDump(buf, 'Test_map_expr_1', {}) 536 537 " clean up 538 call StopVimInTerminal(buf) 539 call delete('XtestExprMap') 540endfunc 541 542" Test for mapping errors 543func Test_map_error() 544 call assert_fails('unmap', 'E474:') 545 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:') 546 call assert_fails('unmap abc', 'E31:') 547 call assert_fails('unabbr abc', 'E24:') 548 call assert_equal('', maparg('')) 549 call assert_fails('echo maparg("abc", [])', 'E730:') 550 551 " unique map 552 map ,w /[#&!]<CR> 553 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:') 554 " unique buffer-local map 555 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:') 556 unmap ,w 557 558 " unique abbreviation 559 abbr SP special 560 call assert_fails("abbr <unique> SP special", 'E226:') 561 " unique buffer-local map 562 call assert_fails("abbr <buffer> <unique> SP special", 'E224:') 563 unabbr SP 564 565 call assert_fails('mapclear abc', 'E474:') 566 call assert_fails('abclear abc', 'E474:') 567 call assert_fails('abbr $xyz abc', 'E474:') 568 569 " space character in an abbreviation 570 call assert_fails('abbr ab<space> ABC', 'E474:') 571 572 " invalid <expr> map 573 map <expr> ,f abc 574 call assert_fails('normal ,f', 'E121:') 575 unmap <expr> ,f 576 577 " Recursive use of :normal in a map 578 set maxmapdepth=100 579 map gq :normal gq<CR> 580 call assert_fails('normal gq', 'E192:') 581 unmap gq 582 set maxmapdepth& 583endfunc 584 585" Test for <special> key mapping 586func Test_map_special() 587 new 588 let old_cpo = &cpo 589 set cpo+=< 590 imap <F12> Blue 591 call feedkeys("i\<F12>", "x") 592 call assert_equal("<F12>", getline(1)) 593 call feedkeys("ddi<F12>", "x") 594 call assert_equal("Blue", getline(1)) 595 iunmap <F12> 596 imap <special> <F12> Green 597 call feedkeys("ddi\<F12>", "x") 598 call assert_equal("Green", getline(1)) 599 call feedkeys("ddi<F12>", "x") 600 call assert_equal("<F12>", getline(1)) 601 iunmap <special> <F12> 602 let &cpo = old_cpo 603 %bwipe! 604endfunc 605 606" Test for hasmapto() 607func Test_hasmapto() 608 call assert_equal(0, hasmapto('/^\k\+ (')) 609 map ,f /^\k\+ (<CR> 610 call assert_equal(1, hasmapto('/^\k\+ (')) 611 unmap ,f 612 613 " Insert mode mapping 614 call assert_equal(0, hasmapto('/^\k\+ (', 'i')) 615 imap ,f /^\k\+ (<CR> 616 call assert_equal(1, hasmapto('/^\k\+ (', 'i')) 617 iunmap ,f 618 619 " Normal mode mapping 620 call assert_equal(0, hasmapto('/^\k\+ (', 'n')) 621 nmap ,f /^\k\+ (<CR> 622 call assert_equal(1, hasmapto('/^\k\+ (')) 623 call assert_equal(1, hasmapto('/^\k\+ (', 'n')) 624 nunmap ,f 625 626 " Visual and Select mode mapping 627 call assert_equal(0, hasmapto('/^\k\+ (', 'v')) 628 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 629 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 630 vmap ,f /^\k\+ (<CR> 631 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 632 call assert_equal(1, hasmapto('/^\k\+ (', 'x')) 633 call assert_equal(1, hasmapto('/^\k\+ (', 's')) 634 vunmap ,f 635 636 " Visual mode mapping 637 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 638 xmap ,f /^\k\+ (<CR> 639 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 640 call assert_equal(1, hasmapto('/^\k\+ (', 'x')) 641 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 642 xunmap ,f 643 644 " Select mode mapping 645 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 646 smap ,f /^\k\+ (<CR> 647 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 648 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 649 call assert_equal(1, hasmapto('/^\k\+ (', 's')) 650 sunmap ,f 651 652 " Operator-pending mode mapping 653 call assert_equal(0, hasmapto('/^\k\+ (', 'o')) 654 omap ,f /^\k\+ (<CR> 655 call assert_equal(1, hasmapto('/^\k\+ (', 'o')) 656 ounmap ,f 657 658 " Language mapping 659 call assert_equal(0, hasmapto('/^\k\+ (', 'l')) 660 lmap ,f /^\k\+ (<CR> 661 call assert_equal(1, hasmapto('/^\k\+ (', 'l')) 662 lunmap ,f 663 664 " Cmdline mode mapping 665 call assert_equal(0, hasmapto('/^\k\+ (', 'c')) 666 cmap ,f /^\k\+ (<CR> 667 call assert_equal(1, hasmapto('/^\k\+ (', 'c')) 668 cunmap ,f 669 670 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1)) 671endfunc 672 673" Test for command-line completion of maps 674func Test_mapcomplete() 675 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>', 676 \ '<silent>', '<special>', '<unique>'], 677 \ getcompletion('', 'mapping')) 678 call assert_equal([], getcompletion(',d', 'mapping')) 679 680 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx') 681 call assert_equal('"unmap <buffer>', @:) 682 683 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx') 684 call assert_equal('"unabbr <buffer>', @:) 685 686 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx') 687 call assert_equal("\"abbr! \x01", @:) 688 689 " Multiple matches for a map 690 nmap ,f /H<CR> 691 omap ,f /H<CR> 692 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx') 693 call assert_equal('"map ,f', @:) 694 mapclear 695endfunc 696 697" Test for <expr> in abbreviation 698func Test_expr_abbr() 699 new 700 iabbr <expr> teh "the" 701 call feedkeys("iteh ", "tx") 702 call assert_equal('the ', getline(1)) 703 iabclear 704 call setline(1, '') 705 706 " invalid <expr> abbreviation 707 abbr <expr> hte GetAbbr() 708 call assert_fails('normal ihte ', 'E117:') 709 call assert_equal('', getline(1)) 710 unabbr <expr> hte 711 712 close! 713endfunc 714 715" Test for storing mappings in different modes in a vimrc file 716func Test_mkvimrc_mapmodes() 717 map a1 /a1 718 nmap a2 /a2 719 vmap a3 /a3 720 smap a4 /a4 721 xmap a5 /a5 722 omap a6 /a6 723 map! a7 /a7 724 imap a8 /a8 725 lmap a9 /a9 726 cmap a10 /a10 727 tmap a11 /a11 728 " Normal + Visual map 729 map a12 /a12 730 sunmap a12 731 ounmap a12 732 " Normal + Selectmode map 733 map a13 /a13 734 xunmap a13 735 ounmap a13 736 " Normal + OpPending map 737 map a14 /a14 738 vunmap a14 739 " Visual + Selectmode map 740 map a15 /a15 741 nunmap a15 742 ounmap a15 743 " Visual + OpPending map 744 map a16 /a16 745 nunmap a16 746 sunmap a16 747 " Selectmode + OpPending map 748 map a17 /a17 749 nunmap a17 750 xunmap a17 751 " Normal + Visual + Selectmode map 752 map a18 /a18 753 ounmap a18 754 " Normal + Visual + OpPending map 755 map a19 /a19 756 sunmap a19 757 " Normal + Selectmode + OpPending map 758 map a20 /a20 759 xunmap a20 760 " Visual + Selectmode + OpPending map 761 map a21 /a21 762 nunmap a21 763 " Mapping to Nop 764 map a22 <Nop> 765 " Script local mapping 766 map <script> a23 /a23 767 768 " Newline in {lhs} and {rhs} of a map 769 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>" 770 771 " Abbreviation 772 abbr a25 A25 773 cabbr a26 A26 774 iabbr a27 A27 775 776 mkvimrc! Xvimrc 777 let l = readfile('Xvimrc') 778 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "')) 779 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "')) 780 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "')) 781 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "')) 782 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "')) 783 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "')) 784 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "')) 785 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "')) 786 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "')) 787 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "')) 788 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "')) 789 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'], 790 \ filter(copy(l), 'v:val =~ " a12 "')) 791 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'], 792 \ filter(copy(l), 'v:val =~ " a13 "')) 793 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'], 794 \ filter(copy(l), 'v:val =~ " a14 "')) 795 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "')) 796 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'], 797 \ filter(copy(l), 'v:val =~ " a16 "')) 798 call assert_equal(['smap a17 /a17', 'omap a17 /a17'], 799 \ filter(copy(l), 'v:val =~ " a17 "')) 800 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'], 801 \ filter(copy(l), 'v:val =~ " a18 "')) 802 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'], 803 \ filter(copy(l), 'v:val =~ " a19 "')) 804 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'], 805 \ filter(copy(l), 'v:val =~ " a20 "')) 806 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'], 807 \ filter(copy(l), 'v:val =~ " a21 "')) 808 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "')) 809 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "')) 810 call assert_equal(["map a24<NL> ia24<NL>\x16\e"], 811 \ filter(copy(l), 'v:val =~ " a24"')) 812 813 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "')) 814 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "')) 815 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "')) 816 call delete('Xvimrc') 817 818 mapclear 819 nmapclear 820 vmapclear 821 xmapclear 822 smapclear 823 omapclear 824 imapclear 825 lmapclear 826 cmapclear 827 tmapclear 828endfunc 829 830" Test for recursive mapping ('maxmapdepth') 831func Test_map_recursive() 832 map x y 833 map y x 834 call assert_fails('normal x', 'E223:') 835 unmap x 836 unmap y 837endfunc 838 839" Test for removing an abbreviation using {rhs} and with space after {lhs} 840func Test_abbr_remove() 841 abbr foo bar 842 let d = maparg('foo', 'i', 1, 1) 843 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode]) 844 unabbr bar 845 call assert_equal({}, maparg('foo', 'i', 1, 1)) 846 847 abbr foo bar 848 unabbr foo<space><tab> 849 call assert_equal({}, maparg('foo', 'i', 1, 1)) 850endfunc 851 852" Trigger an abbreviation using a special key 853func Test_abbr_trigger_special() 854 new 855 iabbr teh the 856 call feedkeys("iteh\<F2>\<Esc>", 'xt') 857 call assert_equal('the<F2>', getline(1)) 858 iunab teh 859 close! 860endfunc 861 862" Test for '<' in 'cpoptions' 863func Test_map_cpo_special_keycode() 864 set cpo-=< 865 imap x<Bslash>k Test 866 let d = maparg('x<Bslash>k', 'i', 0, 1) 867 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode]) 868 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx') 869 call assert_equal('"imap x\k', @:) 870 iunmap x<Bslash>k 871 set cpo+=< 872 imap x<Bslash>k Test 873 let d = maparg('x<Bslash>k', 'i', 0, 1) 874 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode]) 875 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx') 876 call assert_equal('"imap x<Bslash>k', @:) 877 iunmap x<Bslash>k 878 set cpo-=< 879 " Modifying 'cpo' above adds some default mappings, remove them 880 mapclear 881 mapclear! 882endfunc 883 884" Test for <Cmd> key in maps to execute commands 885func Test_map_cmdkey() 886 new 887 888 " Error cases 889 let x = 0 890 noremap <F3> <Cmd><Cmd>let x = 1<CR> 891 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:') 892 call assert_equal(0, x) 893 894 noremap <F3> <Cmd><F3>let x = 2<CR> 895 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1137:') 896 call assert_equal(0, x) 897 898 noremap <F3> <Cmd>let x = 3 899 call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1135:') 900 call assert_equal(0, x) 901 902 " works in various modes and sees the correct mode() 903 noremap <F3> <Cmd>let m = mode(1)<CR> 904 noremap! <F3> <Cmd>let m = mode(1)<CR> 905 906 " normal mode 907 call feedkeys("\<F3>", 'xt') 908 call assert_equal('n', m) 909 910 " visual mode 911 call feedkeys("v\<F3>", 'xt!') 912 call assert_equal('v', m) 913 " shouldn't leave the visual mode 914 call assert_equal('v', mode(1)) 915 call feedkeys("\<Esc>", 'xt') 916 call assert_equal('n', mode(1)) 917 918 " visual mapping in select mode 919 call feedkeys("gh\<F3>", 'xt!') 920 call assert_equal('v', m) 921 " shouldn't leave select mode 922 call assert_equal('s', mode(1)) 923 call feedkeys("\<Esc>", 'xt') 924 call assert_equal('n', mode(1)) 925 926 " select mode mapping 927 snoremap <F3> <Cmd>let m = mode(1)<cr> 928 call feedkeys("gh\<F3>", 'xt!') 929 call assert_equal('s', m) 930 " shouldn't leave select mode 931 call assert_equal('s', mode(1)) 932 call feedkeys("\<Esc>", 'xt') 933 call assert_equal('n', mode(1)) 934 935 " operator-pending mode 936 call feedkeys("d\<F3>", 'xt!') 937 call assert_equal('no', m) 938 " leaves the operator-pending mode 939 call assert_equal('n', mode(1)) 940 941 " insert mode 942 call feedkeys("i\<F3>abc", 'xt') 943 call assert_equal('i', m) 944 call assert_equal('abc', getline('.')) 945 946 " replace mode 947 call feedkeys("0R\<F3>two", 'xt') 948 call assert_equal('R', m) 949 call assert_equal('two', getline('.')) 950 951 " virtual replace mode 952 call setline('.', "one\ttwo") 953 call feedkeys("4|gR\<F3>xxx", 'xt') 954 call assert_equal('Rv', m) 955 call assert_equal("onexxx\ttwo", getline('.')) 956 957 " cmdline mode 958 call feedkeys(":\<F3>\"xxx\<CR>", 'xt!') 959 call assert_equal('c', m) 960 call assert_equal('"xxx', @:) 961 962 " terminal mode 963 if CanRunVimInTerminal() 964 tnoremap <F3> <Cmd>let m = mode(1)<CR> 965 let buf = Run_shell_in_terminal({}) 966 call feedkeys("\<F3>", 'xt') 967 call assert_equal('t', m) 968 call assert_equal('t', mode(1)) 969 call StopShellInTerminal(buf) 970 call TermWait(buf) 971 close! 972 tunmap <F3> 973 endif 974 975 " invoke cmdline mode recursively 976 noremap! <F2> <Cmd>norm! :foo<CR> 977 %d 978 call setline(1, ['some short lines', 'of test text']) 979 call feedkeys(":bar\<F2>x\<C-B>\"\r", 'xt') 980 call assert_equal('"barx', @:) 981 unmap! <F2> 982 983 " test for calling a <SID> function 984 let lines =<< trim END 985 map <F2> <Cmd>call <SID>do_it()<CR> 986 func s:do_it() 987 let g:x = 32 988 endfunc 989 END 990 call writefile(lines, 'Xscript') 991 source Xscript 992 call feedkeys("\<F2>", 'xt') 993 call assert_equal(32, g:x) 994 call delete('Xscript') 995 996 unmap <F3> 997 unmap! <F3> 998 %bw! 999 1000 " command line ending in "0" is handled without errors 1001 onoremap ix <cmd>eval 0<cr> 1002 call feedkeys('dix.', 'xt') 1003 ounmap ix 1004endfunc 1005 1006" text object enters visual mode 1007func TextObj() 1008 if mode() !=# "v" 1009 normal! v 1010 end 1011 call cursor(1, 3) 1012 normal! o 1013 call cursor(2, 4) 1014endfunc 1015 1016func s:cmdmap(lhs, rhs) 1017 exe 'noremap ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>' 1018 exe 'noremap! ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>' 1019endfunc 1020 1021func s:cmdunmap(lhs) 1022 exe 'unmap ' .. a:lhs 1023 exe 'unmap! ' .. a:lhs 1024endfunc 1025 1026" Map various <Fx> keys used by the <Cmd> key tests 1027func s:setupMaps() 1028 call s:cmdmap('<F3>', 'let m = mode(1)') 1029 call s:cmdmap('<F4>', 'normal! ww') 1030 call s:cmdmap('<F5>', 'normal! "ay') 1031 call s:cmdmap('<F6>', 'throw "very error"') 1032 call s:cmdmap('<F7>', 'call TextObj()') 1033 call s:cmdmap('<F8>', 'startinsert') 1034 call s:cmdmap('<F9>', 'stopinsert') 1035endfunc 1036 1037" Remove the mappings setup by setupMaps() 1038func s:cleanupMaps() 1039 call s:cmdunmap('<F3>') 1040 call s:cmdunmap('<F4>') 1041 call s:cmdunmap('<F5>') 1042 call s:cmdunmap('<F6>') 1043 call s:cmdunmap('<F7>') 1044 call s:cmdunmap('<F8>') 1045 call s:cmdunmap('<F9>') 1046endfunc 1047 1048" Test for <Cmd> mapping in normal mode 1049func Test_map_cmdkey_normal_mode() 1050 new 1051 call s:setupMaps() 1052 1053 " check v:count and v:register works 1054 call s:cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]') 1055 call feedkeys("\<F2>", 'xt') 1056 call assert_equal(['n', 0, '"'], s) 1057 call feedkeys("7\<F2>", 'xt') 1058 call assert_equal(['n', 7, '"'], s) 1059 call feedkeys("\"e\<F2>", 'xt') 1060 call assert_equal(['n', 0, 'e'], s) 1061 call feedkeys("5\"k\<F2>", 'xt') 1062 call assert_equal(['n', 5, 'k'], s) 1063 call s:cmdunmap('<F2>') 1064 1065 call setline(1, ['some short lines', 'of test text']) 1066 call feedkeys("\<F7>y", 'xt') 1067 call assert_equal("me short lines\nof t", @") 1068 call assert_equal('v', getregtype('"')) 1069 call assert_equal([0, 1, 3, 0], getpos("'<")) 1070 call assert_equal([0, 2, 4, 0], getpos("'>")) 1071 1072 " startinsert 1073 %d 1074 call feedkeys("\<F8>abc", 'xt') 1075 call assert_equal('abc', getline(1)) 1076 1077 " feedkeys are not executed immediately 1078 noremap ,a <Cmd>call feedkeys("aalpha") \| let g:a = getline(2)<CR> 1079 %d 1080 call setline(1, ['some short lines', 'of test text']) 1081 call cursor(2, 3) 1082 call feedkeys(",a\<F3>", 'xt') 1083 call assert_equal('of test text', g:a) 1084 call assert_equal('n', m) 1085 call assert_equal(['some short lines', 'of alphatest text'], getline(1, '$')) 1086 nunmap ,a 1087 1088 " feedkeys(..., 'x') is executed immediately, but insert mode is aborted 1089 noremap ,b <Cmd>call feedkeys("abeta", 'x') \| let g:b = getline(2)<CR> 1090 call feedkeys(",b\<F3>", 'xt') 1091 call assert_equal('n', m) 1092 call assert_equal('of alphabetatest text', g:b) 1093 nunmap ,b 1094 1095 call s:cleanupMaps() 1096 %bw! 1097endfunc 1098 1099" Test for <Cmd> mapping with the :normal command 1100func Test_map_cmdkey_normal_cmd() 1101 new 1102 noremap ,x <Cmd>call append(1, "xx") \| call append(1, "aa")<CR> 1103 noremap ,f <Cmd>nosuchcommand<CR> 1104 noremap ,e <Cmd>throw "very error" \| call append(1, "yy")<CR> 1105 noremap ,m <Cmd>echoerr "The message." \| call append(1, "zz")<CR> 1106 noremap ,w <Cmd>for i in range(5) \| if i==1 \| echoerr "Err" \| endif \| call append(1, i) \| endfor<CR> 1107 1108 call setline(1, ['some short lines', 'of test text']) 1109 exe "norm ,x\r" 1110 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$')) 1111 1112 call assert_fails('norm ,f', 'E492:') 1113 call assert_fails('norm ,e', 'very error') 1114 call assert_fails('norm ,m', 'The message.') 1115 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$')) 1116 1117 %d 1118 let caught_err = 0 1119 try 1120 exe "normal ,w" 1121 catch /Vim(echoerr):Err/ 1122 let caught_err = 1 1123 endtry 1124 call assert_equal(1, caught_err) 1125 call assert_equal(['', '0'], getline(1, '$')) 1126 1127 %d 1128 call assert_fails('normal ,w', 'Err') 1129 call assert_equal(['', '4', '3', '2' ,'1', '0'], getline(1, '$')) 1130 call assert_equal(1, line('.')) 1131 1132 nunmap ,x 1133 nunmap ,f 1134 nunmap ,e 1135 nunmap ,m 1136 nunmap ,w 1137 %bw! 1138endfunc 1139 1140" Test for <Cmd> mapping in visual mode 1141func Test_map_cmdkey_visual_mode() 1142 new 1143 set showmode 1144 call s:setupMaps() 1145 1146 call setline(1, ['some short lines', 'of test text']) 1147 call feedkeys("v\<F4>", 'xt!') 1148 call assert_equal(['v', 1, 12], [mode(1), col('v'), col('.')]) 1149 1150 " can invoke an opeartor, ending the visual mode 1151 let @a = '' 1152 call feedkeys("\<F5>", 'xt!') 1153 call assert_equal('n', mode(1)) 1154 call assert_equal('some short l', @a) 1155 1156 " error doesn't interrupt visual mode 1157 call assert_fails('call feedkeys("ggvw\<F6>", "xt!")', 'E605:') 1158 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')]) 1159 call feedkeys("\<F7>", 'xt!') 1160 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1161 1162 " startinsert gives "-- (insert) VISUAL --" mode 1163 call feedkeys("\<F8>", 'xt!') 1164 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1165 redraw! 1166 call assert_match('^-- (insert) VISUAL --', Screenline(&lines)) 1167 call feedkeys("\<Esc>new ", 'x') 1168 call assert_equal(['some short lines', 'of new test text'], getline(1, '$')) 1169 1170 call s:cleanupMaps() 1171 set showmode& 1172 %bw! 1173endfunc 1174 1175" Test for <Cmd> mapping in select mode 1176func Test_map_cmdkey_select_mode() 1177 new 1178 set showmode 1179 call s:setupMaps() 1180 1181 snoremap <F1> <cmd>throw "very error"<CR> 1182 snoremap <F2> <cmd>normal! <c-g>"by<CR> 1183 call setline(1, ['some short lines', 'of test text']) 1184 1185 call feedkeys("gh\<F4>", "xt!") 1186 call assert_equal(['s', 1, 12], [mode(1), col('v'), col('.')]) 1187 redraw! 1188 call assert_match('^-- SELECT --', Screenline(&lines)) 1189 1190 " visual mapping in select mode restarts select mode after operator 1191 let @a = '' 1192 call feedkeys("\<F5>", 'xt!') 1193 call assert_equal('s', mode(1)) 1194 call assert_equal('some short l', @a) 1195 1196 " select mode mapping works, and does not restart select mode 1197 let @b = '' 1198 call feedkeys("\<F2>", 'xt!') 1199 call assert_equal('n', mode(1)) 1200 call assert_equal('some short l', @b) 1201 1202 " error doesn't interrupt temporary visual mode 1203 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F6>", "xt!")', 'E605:') 1204 redraw! 1205 call assert_match('^-- VISUAL --', Screenline(&lines)) 1206 " quirk: restoration of select mode is not performed 1207 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')]) 1208 1209 " error doesn't interrupt select mode 1210 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F1>", "xt!")', 'E605:') 1211 redraw! 1212 call assert_match('^-- SELECT --', Screenline(&lines)) 1213 call assert_equal(['s', 1, 6], [mode(1), col('v'), col('.')]) 1214 1215 call feedkeys("\<F7>", 'xt!') 1216 redraw! 1217 call assert_match('^-- SELECT --', Screenline(&lines)) 1218 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1219 1220 " startinsert gives "-- SELECT (insert) --" mode 1221 call feedkeys("\<F8>", 'xt!') 1222 redraw! 1223 call assert_match('^-- (insert) SELECT --', Screenline(&lines)) 1224 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1225 call feedkeys("\<Esc>new ", 'x') 1226 call assert_equal(['some short lines', 'of new test text'], getline(1, '$')) 1227 1228 sunmap <F1> 1229 sunmap <F2> 1230 call s:cleanupMaps() 1231 set showmode& 1232 %bw! 1233endfunc 1234 1235" Test for <Cmd> mapping in operator-pending mode 1236func Test_map_cmdkey_op_pending_mode() 1237 new 1238 call s:setupMaps() 1239 1240 call setline(1, ['some short lines', 'of test text']) 1241 call feedkeys("d\<F4>", 'xt') 1242 call assert_equal(['lines', 'of test text'], getline(1, '$')) 1243 call assert_equal(['some short '], getreg('"', 1, 1)) 1244 " create a new undo point 1245 let &undolevels = &undolevels 1246 1247 call feedkeys(".", 'xt') 1248 call assert_equal(['test text'], getline(1, '$')) 1249 call assert_equal(['lines', 'of '], getreg('"', 1, 1)) 1250 " create a new undo point 1251 let &undolevels = &undolevels 1252 1253 call feedkeys("uu", 'xt') 1254 call assert_equal(['some short lines', 'of test text'], getline(1, '$')) 1255 1256 " error aborts operator-pending, operator not performed 1257 call assert_fails('call feedkeys("d\<F6>", "xt")', 'E605:') 1258 call assert_equal(['some short lines', 'of test text'], getline(1, '$')) 1259 1260 call feedkeys("\"bd\<F7>", 'xt') 1261 call assert_equal(['soest text'], getline(1, '$')) 1262 call assert_equal(['me short lines', 'of t'], getreg('b', 1, 1)) 1263 1264 " startinsert aborts operator 1265 call feedkeys("d\<F8>cc", 'xt') 1266 call assert_equal(['soccest text'], getline(1, '$')) 1267 1268 call s:cleanupMaps() 1269 %bw! 1270endfunc 1271 1272" Test for <Cmd> mapping in insert mode 1273func Test_map_cmdkey_insert_mode() 1274 new 1275 call s:setupMaps() 1276 1277 call setline(1, ['some short lines', 'of test text']) 1278 " works the same as <C-O>w<C-O>w 1279 call feedkeys("iindeed \<F4>little ", 'xt') 1280 call assert_equal(['indeed some short little lines', 'of test text'], getline(1, '$')) 1281 call assert_fails('call feedkeys("i\<F6> 2", "xt")', 'E605:') 1282 call assert_equal(['indeed some short little 2 lines', 'of test text'], getline(1, '$')) 1283 1284 " Note when entering visual mode from InsertEnter autocmd, an async event, 1285 " or a <Cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode. 1286 call feedkeys("i\<F7>stuff ", 'xt') 1287 call assert_equal(['indeed some short little 2 lines', 'of stuff test text'], getline(1, '$')) 1288 call assert_equal(['v', 1, 3, 2, 9], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1289 1290 call feedkeys("\<F5>", 'xt') 1291 call assert_equal(['deed some short little 2 lines', 'of stuff '], getreg('a', 1, 1)) 1292 1293 " also works as part of abbreviation 1294 abbr foo <Cmd>let g:y = 17<CR>bar 1295 exe "normal i\<space>foo " 1296 call assert_equal(17, g:y) 1297 call assert_equal('in bar deed some short little 2 lines', getline(1)) 1298 unabbr foo 1299 1300 " :startinsert does nothing 1301 call setline(1, 'foo bar') 1302 call feedkeys("ggi\<F8>vim", 'xt') 1303 call assert_equal('vimfoo bar', getline(1)) 1304 1305 " :stopinsert works 1306 call feedkeys("ggi\<F9>Abc", 'xt') 1307 call assert_equal('vimfoo barbc', getline(1)) 1308 1309 call s:cleanupMaps() 1310 %bw! 1311endfunc 1312 1313" Test for <Cmd> mapping in insert-completion mode 1314func Test_map_cmdkey_insert_complete_mode() 1315 new 1316 call s:setupMaps() 1317 1318 call setline(1, 'some short lines') 1319 call feedkeys("os\<C-X>\<C-N>\<F3>\<C-N> ", 'xt') 1320 call assert_equal('ic', m) 1321 call assert_equal(['some short lines', 'short '], getline(1, '$')) 1322 1323 call s:cleanupMaps() 1324 %bw! 1325endfunc 1326 1327" Test for <Cmd> mapping in cmdline mode 1328func Test_map_cmdkey_cmdline_mode() 1329 new 1330 call s:setupMaps() 1331 1332 call setline(1, ['some short lines', 'of test text']) 1333 let x = 0 1334 call feedkeys(":let x\<F3>= 10\r", 'xt') 1335 call assert_equal('c', m) 1336 call assert_equal(10, x) 1337 1338 " exception doesn't leave cmdline mode 1339 call assert_fails('call feedkeys(":let x\<F6>= 20\r", "xt")', 'E605:') 1340 call assert_equal(20, x) 1341 1342 " move cursor in the buffer from cmdline mode 1343 call feedkeys(":let x\<F4>= 30\r", 'xt') 1344 call assert_equal(30, x) 1345 call assert_equal(12, col('.')) 1346 1347 " :startinsert takes effect after leaving cmdline mode 1348 call feedkeys(":let x\<F8>= 40\rnew ", 'xt') 1349 call assert_equal(40, x) 1350 call assert_equal('some short new lines', getline(1)) 1351 1352 call s:cleanupMaps() 1353 %bw! 1354endfunc 1355 1356func Test_map_cmdkey_redo() 1357 func SelectDash() 1358 call search('^---\n\zs', 'bcW') 1359 norm! V 1360 call search('\n\ze---$', 'W') 1361 endfunc 1362 1363 let text =<< trim END 1364 --- 1365 aaa 1366 --- 1367 bbb 1368 bbb 1369 --- 1370 ccc 1371 ccc 1372 ccc 1373 --- 1374 END 1375 new Xcmdtext 1376 call setline(1, text) 1377 1378 onoremap <silent> i- <Cmd>call SelectDash()<CR> 1379 call feedkeys('2Gdi-', 'xt') 1380 call assert_equal(['---', '---'], getline(1, 2)) 1381 call feedkeys('j.', 'xt') 1382 call assert_equal(['---', '---', '---'], getline(1, 3)) 1383 call feedkeys('j.', 'xt') 1384 call assert_equal(['---', '---', '---', '---'], getline(1, 4)) 1385 1386 bwipe! 1387 call delete('Xcmdtext') 1388 delfunc SelectDash 1389 ounmap i- 1390endfunc 1391 1392" Test for using <script> with a map to remap characters in rhs 1393func Test_script_local_remap() 1394 new 1395 inoremap <buffer> <SID>xyz mno 1396 inoremap <buffer> <script> abc st<SID>xyzre 1397 normal iabc 1398 call assert_equal('stmnore', getline(1)) 1399 bwipe! 1400endfunc 1401 1402" vim: shiftwidth=2 sts=2 expandtab 1403