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 " reset 'isident' to check it isn't used 449 set isident= 450 inoremap <C-m> CtrlM 451 inoremap <A-S> AltS 452 inoremap <S-/> ShiftSlash 453 set isident& 454 call assert_equal([ 455 \ 'i <S-/> * ShiftSlash', 456 \ 'i <M-S> * AltS', 457 \ 'i <C-M> * CtrlM', 458 \], execute('imap')->trim()->split("\n")) 459 iunmap <C-M> 460 iunmap <A-S> 461 call assert_equal(['i <S-/> * ShiftSlash'], execute('imap')->trim()->split("\n")) 462 iunmap <S-/> 463 call assert_equal(['No mapping found'], execute('imap')->trim()->split("\n")) 464 465 " List global, buffer local and script local mappings 466 nmap ,f /^\k\+ (<CR> 467 nmap <buffer> ,f /^\k\+ (<CR> 468 nmap <script> ,fs /^\k\+ (<CR> 469 call assert_equal(['n ,f @/^\k\+ (<CR>', 470 \ 'n ,fs & /^\k\+ (<CR>', 471 \ 'n ,f /^\k\+ (<CR>'], 472 \ execute('nmap ,f')->trim()->split("\n")) 473 474 " List <Nop> mapping 475 nmap ,n <Nop> 476 call assert_equal(['n ,n <Nop>'], 477 \ execute('nmap ,n')->trim()->split("\n")) 478 479 " verbose map 480 call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$", 481 \ execute('verbose map ,n')->trim()->split("\n")[1]) 482 483 " map to CTRL-V 484 exe "nmap ,k \<C-V>" 485 call assert_equal(['n ,k <Nop>'], 486 \ execute('nmap ,k')->trim()->split("\n")) 487 488 nmapclear 489endfunc 490 491func Test_expr_map_gets_cursor() 492 new 493 call setline(1, ['one', 'some w!rd']) 494 func StoreColumn() 495 let g:exprLine = line('.') 496 let g:exprCol = col('.') 497 return 'x' 498 endfunc 499 nnoremap <expr> x StoreColumn() 500 2 501 nmap ! f!<Ignore>x 502 call feedkeys("!", 'xt') 503 call assert_equal('some wrd', getline(2)) 504 call assert_equal(2, g:exprLine) 505 call assert_equal(7, g:exprCol) 506 507 bwipe! 508 unlet g:exprLine 509 unlet g:exprCol 510 delfunc StoreColumn 511 nunmap x 512 nunmap ! 513endfunc 514 515func Test_expr_map_restore_cursor() 516 CheckScreendump 517 518 let lines =<< trim END 519 call setline(1, ['one', 'two', 'three']) 520 2 521 set ls=2 522 hi! link StatusLine ErrorMsg 523 noremap <expr> <C-B> Func() 524 func Func() 525 let g:on = !get(g:, 'on', 0) 526 redraws 527 return '' 528 endfunc 529 func Status() 530 return get(g:, 'on', 0) ? '[on]' : '' 531 endfunc 532 set stl=%{Status()} 533 END 534 call writefile(lines, 'XtestExprMap') 535 let buf = RunVimInTerminal('-S XtestExprMap', #{rows: 10}) 536 call TermWait(buf) 537 call term_sendkeys(buf, "\<C-B>") 538 call VerifyScreenDump(buf, 'Test_map_expr_1', {}) 539 540 " clean up 541 call StopVimInTerminal(buf) 542 call delete('XtestExprMap') 543endfunc 544 545" Test for mapping errors 546func Test_map_error() 547 call assert_fails('unmap', 'E474:') 548 call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:') 549 call assert_fails('unmap abc', 'E31:') 550 call assert_fails('unabbr abc', 'E24:') 551 call assert_equal('', maparg('')) 552 call assert_fails('echo maparg("abc", [])', 'E730:') 553 554 " unique map 555 map ,w /[#&!]<CR> 556 call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:') 557 " unique buffer-local map 558 call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:') 559 unmap ,w 560 561 " unique abbreviation 562 abbr SP special 563 call assert_fails("abbr <unique> SP special", 'E226:') 564 " unique buffer-local map 565 call assert_fails("abbr <buffer> <unique> SP special", 'E224:') 566 unabbr SP 567 568 call assert_fails('mapclear abc', 'E474:') 569 call assert_fails('abclear abc', 'E474:') 570 call assert_fails('abbr $xyz abc', 'E474:') 571 572 " space character in an abbreviation 573 call assert_fails('abbr ab<space> ABC', 'E474:') 574 575 " invalid <expr> map 576 map <expr> ,f abc 577 call assert_fails('normal ,f', 'E121:') 578 unmap <expr> ,f 579 580 " Recursive use of :normal in a map 581 set maxmapdepth=100 582 map gq :normal gq<CR> 583 call assert_fails('normal gq', 'E192:') 584 unmap gq 585 set maxmapdepth& 586endfunc 587 588" Test for <special> key mapping 589func Test_map_special() 590 new 591 let old_cpo = &cpo 592 set cpo+=< 593 imap <F12> Blue 594 call feedkeys("i\<F12>", "x") 595 call assert_equal("<F12>", getline(1)) 596 call feedkeys("ddi<F12>", "x") 597 call assert_equal("Blue", getline(1)) 598 iunmap <F12> 599 imap <special> <F12> Green 600 call feedkeys("ddi\<F12>", "x") 601 call assert_equal("Green", getline(1)) 602 call feedkeys("ddi<F12>", "x") 603 call assert_equal("<F12>", getline(1)) 604 iunmap <special> <F12> 605 let &cpo = old_cpo 606 %bwipe! 607endfunc 608 609" Test for hasmapto() 610func Test_hasmapto() 611 call assert_equal(0, hasmapto('/^\k\+ (')) 612 map ,f /^\k\+ (<CR> 613 call assert_equal(1, hasmapto('/^\k\+ (')) 614 unmap ,f 615 616 " Insert mode mapping 617 call assert_equal(0, hasmapto('/^\k\+ (', 'i')) 618 imap ,f /^\k\+ (<CR> 619 call assert_equal(1, hasmapto('/^\k\+ (', 'i')) 620 iunmap ,f 621 622 " Normal mode mapping 623 call assert_equal(0, hasmapto('/^\k\+ (', 'n')) 624 nmap ,f /^\k\+ (<CR> 625 call assert_equal(1, hasmapto('/^\k\+ (')) 626 call assert_equal(1, hasmapto('/^\k\+ (', 'n')) 627 nunmap ,f 628 629 " Visual and Select mode mapping 630 call assert_equal(0, hasmapto('/^\k\+ (', 'v')) 631 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 632 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 633 vmap ,f /^\k\+ (<CR> 634 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 635 call assert_equal(1, hasmapto('/^\k\+ (', 'x')) 636 call assert_equal(1, hasmapto('/^\k\+ (', 's')) 637 vunmap ,f 638 639 " Visual mode mapping 640 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 641 xmap ,f /^\k\+ (<CR> 642 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 643 call assert_equal(1, hasmapto('/^\k\+ (', 'x')) 644 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 645 xunmap ,f 646 647 " Select mode mapping 648 call assert_equal(0, hasmapto('/^\k\+ (', 's')) 649 smap ,f /^\k\+ (<CR> 650 call assert_equal(1, hasmapto('/^\k\+ (', 'v')) 651 call assert_equal(0, hasmapto('/^\k\+ (', 'x')) 652 call assert_equal(1, hasmapto('/^\k\+ (', 's')) 653 sunmap ,f 654 655 " Operator-pending mode mapping 656 call assert_equal(0, hasmapto('/^\k\+ (', 'o')) 657 omap ,f /^\k\+ (<CR> 658 call assert_equal(1, hasmapto('/^\k\+ (', 'o')) 659 ounmap ,f 660 661 " Language mapping 662 call assert_equal(0, hasmapto('/^\k\+ (', 'l')) 663 lmap ,f /^\k\+ (<CR> 664 call assert_equal(1, hasmapto('/^\k\+ (', 'l')) 665 lunmap ,f 666 667 " Cmdline mode mapping 668 call assert_equal(0, hasmapto('/^\k\+ (', 'c')) 669 cmap ,f /^\k\+ (<CR> 670 call assert_equal(1, hasmapto('/^\k\+ (', 'c')) 671 cunmap ,f 672 673 call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1)) 674endfunc 675 676" Test for command-line completion of maps 677func Test_mapcomplete() 678 call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>', 679 \ '<silent>', '<special>', '<unique>'], 680 \ getcompletion('', 'mapping')) 681 call assert_equal([], getcompletion(',d', 'mapping')) 682 683 call feedkeys(":unmap <buf\<C-A>\<C-B>\"\<CR>", 'tx') 684 call assert_equal('"unmap <buffer>', @:) 685 686 call feedkeys(":unabbr <buf\<C-A>\<C-B>\"\<CR>", 'tx') 687 call assert_equal('"unabbr <buffer>', @:) 688 689 call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx') 690 call assert_equal("\"abbr! \x01", @:) 691 692 " Multiple matches for a map 693 nmap ,f /H<CR> 694 omap ,f /H<CR> 695 call feedkeys(":map ,\<C-A>\<C-B>\"\<CR>", 'tx') 696 call assert_equal('"map ,f', @:) 697 mapclear 698endfunc 699 700" Test for <expr> in abbreviation 701func Test_expr_abbr() 702 new 703 iabbr <expr> teh "the" 704 call feedkeys("iteh ", "tx") 705 call assert_equal('the ', getline(1)) 706 iabclear 707 call setline(1, '') 708 709 " invalid <expr> abbreviation 710 abbr <expr> hte GetAbbr() 711 call assert_fails('normal ihte ', 'E117:') 712 call assert_equal('', getline(1)) 713 unabbr <expr> hte 714 715 close! 716endfunc 717 718" Test for storing mappings in different modes in a vimrc file 719func Test_mkvimrc_mapmodes() 720 map a1 /a1 721 nmap a2 /a2 722 vmap a3 /a3 723 smap a4 /a4 724 xmap a5 /a5 725 omap a6 /a6 726 map! a7 /a7 727 imap a8 /a8 728 lmap a9 /a9 729 cmap a10 /a10 730 tmap a11 /a11 731 " Normal + Visual map 732 map a12 /a12 733 sunmap a12 734 ounmap a12 735 " Normal + Selectmode map 736 map a13 /a13 737 xunmap a13 738 ounmap a13 739 " Normal + OpPending map 740 map a14 /a14 741 vunmap a14 742 " Visual + Selectmode map 743 map a15 /a15 744 nunmap a15 745 ounmap a15 746 " Visual + OpPending map 747 map a16 /a16 748 nunmap a16 749 sunmap a16 750 " Selectmode + OpPending map 751 map a17 /a17 752 nunmap a17 753 xunmap a17 754 " Normal + Visual + Selectmode map 755 map a18 /a18 756 ounmap a18 757 " Normal + Visual + OpPending map 758 map a19 /a19 759 sunmap a19 760 " Normal + Selectmode + OpPending map 761 map a20 /a20 762 xunmap a20 763 " Visual + Selectmode + OpPending map 764 map a21 /a21 765 nunmap a21 766 " Mapping to Nop 767 map a22 <Nop> 768 " Script local mapping 769 map <script> a23 /a23 770 771 " Newline in {lhs} and {rhs} of a map 772 exe "map a24\<C-V>\<C-J> ia24\<C-V>\<C-J><Esc>" 773 774 " Abbreviation 775 abbr a25 A25 776 cabbr a26 A26 777 iabbr a27 A27 778 779 mkvimrc! Xvimrc 780 let l = readfile('Xvimrc') 781 call assert_equal(['map a1 /a1'], filter(copy(l), 'v:val =~ " a1 "')) 782 call assert_equal(['nmap a2 /a2'], filter(copy(l), 'v:val =~ " a2 "')) 783 call assert_equal(['vmap a3 /a3'], filter(copy(l), 'v:val =~ " a3 "')) 784 call assert_equal(['smap a4 /a4'], filter(copy(l), 'v:val =~ " a4 "')) 785 call assert_equal(['xmap a5 /a5'], filter(copy(l), 'v:val =~ " a5 "')) 786 call assert_equal(['omap a6 /a6'], filter(copy(l), 'v:val =~ " a6 "')) 787 call assert_equal(['map! a7 /a7'], filter(copy(l), 'v:val =~ " a7 "')) 788 call assert_equal(['imap a8 /a8'], filter(copy(l), 'v:val =~ " a8 "')) 789 call assert_equal(['lmap a9 /a9'], filter(copy(l), 'v:val =~ " a9 "')) 790 call assert_equal(['cmap a10 /a10'], filter(copy(l), 'v:val =~ " a10 "')) 791 call assert_equal(['tmap a11 /a11'], filter(copy(l), 'v:val =~ " a11 "')) 792 call assert_equal(['nmap a12 /a12', 'xmap a12 /a12'], 793 \ filter(copy(l), 'v:val =~ " a12 "')) 794 call assert_equal(['nmap a13 /a13', 'smap a13 /a13'], 795 \ filter(copy(l), 'v:val =~ " a13 "')) 796 call assert_equal(['nmap a14 /a14', 'omap a14 /a14'], 797 \ filter(copy(l), 'v:val =~ " a14 "')) 798 call assert_equal(['vmap a15 /a15'], filter(copy(l), 'v:val =~ " a15 "')) 799 call assert_equal(['xmap a16 /a16', 'omap a16 /a16'], 800 \ filter(copy(l), 'v:val =~ " a16 "')) 801 call assert_equal(['smap a17 /a17', 'omap a17 /a17'], 802 \ filter(copy(l), 'v:val =~ " a17 "')) 803 call assert_equal(['nmap a18 /a18', 'vmap a18 /a18'], 804 \ filter(copy(l), 'v:val =~ " a18 "')) 805 call assert_equal(['nmap a19 /a19', 'xmap a19 /a19', 'omap a19 /a19'], 806 \ filter(copy(l), 'v:val =~ " a19 "')) 807 call assert_equal(['nmap a20 /a20', 'smap a20 /a20', 'omap a20 /a20'], 808 \ filter(copy(l), 'v:val =~ " a20 "')) 809 call assert_equal(['vmap a21 /a21', 'omap a21 /a21'], 810 \ filter(copy(l), 'v:val =~ " a21 "')) 811 call assert_equal(['map a22 <Nop>'], filter(copy(l), 'v:val =~ " a22 "')) 812 call assert_equal([], filter(copy(l), 'v:val =~ " a23 "')) 813 call assert_equal(["map a24<NL> ia24<NL>\x16\e"], 814 \ filter(copy(l), 'v:val =~ " a24"')) 815 816 call assert_equal(['abbr a25 A25'], filter(copy(l), 'v:val =~ " a25 "')) 817 call assert_equal(['cabbr a26 A26'], filter(copy(l), 'v:val =~ " a26 "')) 818 call assert_equal(['iabbr a27 A27'], filter(copy(l), 'v:val =~ " a27 "')) 819 call delete('Xvimrc') 820 821 mapclear 822 nmapclear 823 vmapclear 824 xmapclear 825 smapclear 826 omapclear 827 imapclear 828 lmapclear 829 cmapclear 830 tmapclear 831endfunc 832 833" Test for recursive mapping ('maxmapdepth') 834func Test_map_recursive() 835 map x y 836 map y x 837 call assert_fails('normal x', 'E223:') 838 unmap x 839 unmap y 840endfunc 841 842" Test for removing an abbreviation using {rhs} and with space after {lhs} 843func Test_abbr_remove() 844 abbr foo bar 845 let d = maparg('foo', 'i', 1, 1) 846 call assert_equal(['foo', 'bar', '!'], [d.lhs, d.rhs, d.mode]) 847 unabbr bar 848 call assert_equal({}, maparg('foo', 'i', 1, 1)) 849 850 abbr foo bar 851 unabbr foo<space><tab> 852 call assert_equal({}, maparg('foo', 'i', 1, 1)) 853endfunc 854 855" Trigger an abbreviation using a special key 856func Test_abbr_trigger_special() 857 new 858 iabbr teh the 859 call feedkeys("iteh\<F2>\<Esc>", 'xt') 860 call assert_equal('the<F2>', getline(1)) 861 iunab teh 862 close! 863endfunc 864 865" Test for '<' in 'cpoptions' 866func Test_map_cpo_special_keycode() 867 set cpo-=< 868 imap x<Bslash>k Test 869 let d = maparg('x<Bslash>k', 'i', 0, 1) 870 call assert_equal(['x\k', 'Test', 'i'], [d.lhs, d.rhs, d.mode]) 871 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx') 872 call assert_equal('"imap x\k', @:) 873 iunmap x<Bslash>k 874 set cpo+=< 875 imap x<Bslash>k Test 876 let d = maparg('x<Bslash>k', 'i', 0, 1) 877 call assert_equal(['x<Bslash>k', 'Test', 'i'], [d.lhs, d.rhs, d.mode]) 878 call feedkeys(":imap x\<C-A>\<C-B>\"\<CR>", 'tx') 879 call assert_equal('"imap x<Bslash>k', @:) 880 iunmap x<Bslash>k 881 set cpo-=< 882 " Modifying 'cpo' above adds some default mappings, remove them 883 mapclear 884 mapclear! 885endfunc 886 887" Test for <Cmd> key in maps to execute commands 888func Test_map_cmdkey() 889 new 890 891 " Error cases 892 let x = 0 893 noremap <F3> <Cmd><Cmd>let x = 1<CR> 894 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1136:') 895 call assert_equal(0, x) 896 897 noremap <F3> <Cmd><F3>let x = 2<CR> 898 call assert_fails('call feedkeys("\<F3>", "xt")', 'E1137:') 899 call assert_equal(0, x) 900 901 noremap <F3> <Cmd>let x = 3 902 call assert_fails('call feedkeys("\<F3>", "xt!")', 'E1135:') 903 call assert_equal(0, x) 904 905 " works in various modes and sees the correct mode() 906 noremap <F3> <Cmd>let m = mode(1)<CR> 907 noremap! <F3> <Cmd>let m = mode(1)<CR> 908 909 " normal mode 910 call feedkeys("\<F3>", 'xt') 911 call assert_equal('n', m) 912 913 " visual mode 914 call feedkeys("v\<F3>", 'xt!') 915 call assert_equal('v', m) 916 " shouldn't leave the visual mode 917 call assert_equal('v', mode(1)) 918 call feedkeys("\<Esc>", 'xt') 919 call assert_equal('n', mode(1)) 920 921 " visual mapping in select mode 922 call feedkeys("gh\<F3>", 'xt!') 923 call assert_equal('v', m) 924 " shouldn't leave select mode 925 call assert_equal('s', mode(1)) 926 call feedkeys("\<Esc>", 'xt') 927 call assert_equal('n', mode(1)) 928 929 " select mode mapping 930 snoremap <F3> <Cmd>let m = mode(1)<cr> 931 call feedkeys("gh\<F3>", 'xt!') 932 call assert_equal('s', m) 933 " shouldn't leave select mode 934 call assert_equal('s', mode(1)) 935 call feedkeys("\<Esc>", 'xt') 936 call assert_equal('n', mode(1)) 937 938 " operator-pending mode 939 call feedkeys("d\<F3>", 'xt!') 940 call assert_equal('no', m) 941 " leaves the operator-pending mode 942 call assert_equal('n', mode(1)) 943 944 " insert mode 945 call feedkeys("i\<F3>abc", 'xt') 946 call assert_equal('i', m) 947 call assert_equal('abc', getline('.')) 948 949 " replace mode 950 call feedkeys("0R\<F3>two", 'xt') 951 call assert_equal('R', m) 952 call assert_equal('two', getline('.')) 953 954 " virtual replace mode 955 call setline('.', "one\ttwo") 956 call feedkeys("4|gR\<F3>xxx", 'xt') 957 call assert_equal('Rv', m) 958 call assert_equal("onexxx\ttwo", getline('.')) 959 960 " cmdline mode 961 call feedkeys(":\<F3>\"xxx\<CR>", 'xt!') 962 call assert_equal('c', m) 963 call assert_equal('"xxx', @:) 964 965 " terminal mode 966 if CanRunVimInTerminal() 967 tnoremap <F3> <Cmd>let m = mode(1)<CR> 968 let buf = Run_shell_in_terminal({}) 969 call feedkeys("\<F3>", 'xt') 970 call assert_equal('t', m) 971 call assert_equal('t', mode(1)) 972 call StopShellInTerminal(buf) 973 call TermWait(buf) 974 close! 975 tunmap <F3> 976 endif 977 978 " invoke cmdline mode recursively 979 noremap! <F2> <Cmd>norm! :foo<CR> 980 %d 981 call setline(1, ['some short lines', 'of test text']) 982 call feedkeys(":bar\<F2>x\<C-B>\"\r", 'xt') 983 call assert_equal('"barx', @:) 984 unmap! <F2> 985 986 " test for calling a <SID> function 987 let lines =<< trim END 988 map <F2> <Cmd>call <SID>do_it()<CR> 989 func s:do_it() 990 let g:x = 32 991 endfunc 992 END 993 call writefile(lines, 'Xscript') 994 source Xscript 995 call feedkeys("\<F2>", 'xt') 996 call assert_equal(32, g:x) 997 call delete('Xscript') 998 999 unmap <F3> 1000 unmap! <F3> 1001 %bw! 1002 1003 " command line ending in "0" is handled without errors 1004 onoremap ix <cmd>eval 0<cr> 1005 call feedkeys('dix.', 'xt') 1006 ounmap ix 1007endfunc 1008 1009" text object enters visual mode 1010func TextObj() 1011 if mode() !=# "v" 1012 normal! v 1013 end 1014 call cursor(1, 3) 1015 normal! o 1016 call cursor(2, 4) 1017endfunc 1018 1019func s:cmdmap(lhs, rhs) 1020 exe 'noremap ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>' 1021 exe 'noremap! ' .. a:lhs .. ' <Cmd>' .. a:rhs .. '<CR>' 1022endfunc 1023 1024func s:cmdunmap(lhs) 1025 exe 'unmap ' .. a:lhs 1026 exe 'unmap! ' .. a:lhs 1027endfunc 1028 1029" Map various <Fx> keys used by the <Cmd> key tests 1030func s:setupMaps() 1031 call s:cmdmap('<F3>', 'let m = mode(1)') 1032 call s:cmdmap('<F4>', 'normal! ww') 1033 call s:cmdmap('<F5>', 'normal! "ay') 1034 call s:cmdmap('<F6>', 'throw "very error"') 1035 call s:cmdmap('<F7>', 'call TextObj()') 1036 call s:cmdmap('<F8>', 'startinsert') 1037 call s:cmdmap('<F9>', 'stopinsert') 1038endfunc 1039 1040" Remove the mappings setup by setupMaps() 1041func s:cleanupMaps() 1042 call s:cmdunmap('<F3>') 1043 call s:cmdunmap('<F4>') 1044 call s:cmdunmap('<F5>') 1045 call s:cmdunmap('<F6>') 1046 call s:cmdunmap('<F7>') 1047 call s:cmdunmap('<F8>') 1048 call s:cmdunmap('<F9>') 1049endfunc 1050 1051" Test for <Cmd> mapping in normal mode 1052func Test_map_cmdkey_normal_mode() 1053 new 1054 call s:setupMaps() 1055 1056 " check v:count and v:register works 1057 call s:cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]') 1058 call feedkeys("\<F2>", 'xt') 1059 call assert_equal(['n', 0, '"'], s) 1060 call feedkeys("7\<F2>", 'xt') 1061 call assert_equal(['n', 7, '"'], s) 1062 call feedkeys("\"e\<F2>", 'xt') 1063 call assert_equal(['n', 0, 'e'], s) 1064 call feedkeys("5\"k\<F2>", 'xt') 1065 call assert_equal(['n', 5, 'k'], s) 1066 call s:cmdunmap('<F2>') 1067 1068 call setline(1, ['some short lines', 'of test text']) 1069 call feedkeys("\<F7>y", 'xt') 1070 call assert_equal("me short lines\nof t", @") 1071 call assert_equal('v', getregtype('"')) 1072 call assert_equal([0, 1, 3, 0], getpos("'<")) 1073 call assert_equal([0, 2, 4, 0], getpos("'>")) 1074 1075 " startinsert 1076 %d 1077 call feedkeys("\<F8>abc", 'xt') 1078 call assert_equal('abc', getline(1)) 1079 1080 " feedkeys are not executed immediately 1081 noremap ,a <Cmd>call feedkeys("aalpha") \| let g:a = getline(2)<CR> 1082 %d 1083 call setline(1, ['some short lines', 'of test text']) 1084 call cursor(2, 3) 1085 call feedkeys(",a\<F3>", 'xt') 1086 call assert_equal('of test text', g:a) 1087 call assert_equal('n', m) 1088 call assert_equal(['some short lines', 'of alphatest text'], getline(1, '$')) 1089 nunmap ,a 1090 1091 " feedkeys(..., 'x') is executed immediately, but insert mode is aborted 1092 noremap ,b <Cmd>call feedkeys("abeta", 'x') \| let g:b = getline(2)<CR> 1093 call feedkeys(",b\<F3>", 'xt') 1094 call assert_equal('n', m) 1095 call assert_equal('of alphabetatest text', g:b) 1096 nunmap ,b 1097 1098 call s:cleanupMaps() 1099 %bw! 1100endfunc 1101 1102" Test for <Cmd> mapping with the :normal command 1103func Test_map_cmdkey_normal_cmd() 1104 new 1105 noremap ,x <Cmd>call append(1, "xx") \| call append(1, "aa")<CR> 1106 noremap ,f <Cmd>nosuchcommand<CR> 1107 noremap ,e <Cmd>throw "very error" \| call append(1, "yy")<CR> 1108 noremap ,m <Cmd>echoerr "The message." \| call append(1, "zz")<CR> 1109 noremap ,w <Cmd>for i in range(5) \| if i==1 \| echoerr "Err" \| endif \| call append(1, i) \| endfor<CR> 1110 1111 call setline(1, ['some short lines', 'of test text']) 1112 exe "norm ,x\r" 1113 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$')) 1114 1115 call assert_fails('norm ,f', 'E492:') 1116 call assert_fails('norm ,e', 'very error') 1117 call assert_fails('norm ,m', 'The message.') 1118 call assert_equal(['some short lines', 'aa', 'xx', 'of test text'], getline(1, '$')) 1119 1120 %d 1121 let caught_err = 0 1122 try 1123 exe "normal ,w" 1124 catch /Vim(echoerr):Err/ 1125 let caught_err = 1 1126 endtry 1127 call assert_equal(1, caught_err) 1128 call assert_equal(['', '0'], getline(1, '$')) 1129 1130 %d 1131 call assert_fails('normal ,w', 'Err') 1132 call assert_equal(['', '4', '3', '2' ,'1', '0'], getline(1, '$')) 1133 call assert_equal(1, line('.')) 1134 1135 nunmap ,x 1136 nunmap ,f 1137 nunmap ,e 1138 nunmap ,m 1139 nunmap ,w 1140 %bw! 1141endfunc 1142 1143" Test for <Cmd> mapping in visual mode 1144func Test_map_cmdkey_visual_mode() 1145 new 1146 set showmode 1147 call s:setupMaps() 1148 1149 call setline(1, ['some short lines', 'of test text']) 1150 call feedkeys("v\<F4>", 'xt!') 1151 call assert_equal(['v', 1, 12], [mode(1), col('v'), col('.')]) 1152 1153 " can invoke an opeartor, ending the visual mode 1154 let @a = '' 1155 call feedkeys("\<F5>", 'xt!') 1156 call assert_equal('n', mode(1)) 1157 call assert_equal('some short l', @a) 1158 1159 " error doesn't interrupt visual mode 1160 call assert_fails('call feedkeys("ggvw\<F6>", "xt!")', 'E605:') 1161 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')]) 1162 call feedkeys("\<F7>", 'xt!') 1163 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1164 1165 " startinsert gives "-- (insert) VISUAL --" mode 1166 call feedkeys("\<F8>", 'xt!') 1167 call assert_equal(['v', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1168 redraw! 1169 call assert_match('^-- (insert) VISUAL --', Screenline(&lines)) 1170 call feedkeys("\<Esc>new ", 'x') 1171 call assert_equal(['some short lines', 'of new test text'], getline(1, '$')) 1172 1173 call s:cleanupMaps() 1174 set showmode& 1175 %bw! 1176endfunc 1177 1178" Test for <Cmd> mapping in select mode 1179func Test_map_cmdkey_select_mode() 1180 new 1181 set showmode 1182 call s:setupMaps() 1183 1184 snoremap <F1> <cmd>throw "very error"<CR> 1185 snoremap <F2> <cmd>normal! <c-g>"by<CR> 1186 call setline(1, ['some short lines', 'of test text']) 1187 1188 call feedkeys("gh\<F4>", "xt!") 1189 call assert_equal(['s', 1, 12], [mode(1), col('v'), col('.')]) 1190 redraw! 1191 call assert_match('^-- SELECT --', Screenline(&lines)) 1192 1193 " visual mapping in select mode restarts select mode after operator 1194 let @a = '' 1195 call feedkeys("\<F5>", 'xt!') 1196 call assert_equal('s', mode(1)) 1197 call assert_equal('some short l', @a) 1198 1199 " select mode mapping works, and does not restart select mode 1200 let @b = '' 1201 call feedkeys("\<F2>", 'xt!') 1202 call assert_equal('n', mode(1)) 1203 call assert_equal('some short l', @b) 1204 1205 " error doesn't interrupt temporary visual mode 1206 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F6>", "xt!")', 'E605:') 1207 redraw! 1208 call assert_match('^-- VISUAL --', Screenline(&lines)) 1209 " quirk: restoration of select mode is not performed 1210 call assert_equal(['v', 1, 6], [mode(1), col('v'), col('.')]) 1211 1212 " error doesn't interrupt select mode 1213 call assert_fails('call feedkeys("\<Esc>ggvw\<C-G>\<F1>", "xt!")', 'E605:') 1214 redraw! 1215 call assert_match('^-- SELECT --', Screenline(&lines)) 1216 call assert_equal(['s', 1, 6], [mode(1), col('v'), col('.')]) 1217 1218 call feedkeys("\<F7>", 'xt!') 1219 redraw! 1220 call assert_match('^-- SELECT --', Screenline(&lines)) 1221 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1222 1223 " startinsert gives "-- SELECT (insert) --" mode 1224 call feedkeys("\<F8>", 'xt!') 1225 redraw! 1226 call assert_match('^-- (insert) SELECT --', Screenline(&lines)) 1227 call assert_equal(['s', 1, 3, 2, 4], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1228 call feedkeys("\<Esc>new ", 'x') 1229 call assert_equal(['some short lines', 'of new test text'], getline(1, '$')) 1230 1231 sunmap <F1> 1232 sunmap <F2> 1233 call s:cleanupMaps() 1234 set showmode& 1235 %bw! 1236endfunc 1237 1238" Test for <Cmd> mapping in operator-pending mode 1239func Test_map_cmdkey_op_pending_mode() 1240 new 1241 call s:setupMaps() 1242 1243 call setline(1, ['some short lines', 'of test text']) 1244 call feedkeys("d\<F4>", 'xt') 1245 call assert_equal(['lines', 'of test text'], getline(1, '$')) 1246 call assert_equal(['some short '], getreg('"', 1, 1)) 1247 " create a new undo point 1248 let &undolevels = &undolevels 1249 1250 call feedkeys(".", 'xt') 1251 call assert_equal(['test text'], getline(1, '$')) 1252 call assert_equal(['lines', 'of '], getreg('"', 1, 1)) 1253 " create a new undo point 1254 let &undolevels = &undolevels 1255 1256 call feedkeys("uu", 'xt') 1257 call assert_equal(['some short lines', 'of test text'], getline(1, '$')) 1258 1259 " error aborts operator-pending, operator not performed 1260 call assert_fails('call feedkeys("d\<F6>", "xt")', 'E605:') 1261 call assert_equal(['some short lines', 'of test text'], getline(1, '$')) 1262 1263 call feedkeys("\"bd\<F7>", 'xt') 1264 call assert_equal(['soest text'], getline(1, '$')) 1265 call assert_equal(['me short lines', 'of t'], getreg('b', 1, 1)) 1266 1267 " startinsert aborts operator 1268 call feedkeys("d\<F8>cc", 'xt') 1269 call assert_equal(['soccest text'], getline(1, '$')) 1270 1271 call s:cleanupMaps() 1272 %bw! 1273endfunc 1274 1275" Test for <Cmd> mapping in insert mode 1276func Test_map_cmdkey_insert_mode() 1277 new 1278 call s:setupMaps() 1279 1280 call setline(1, ['some short lines', 'of test text']) 1281 " works the same as <C-O>w<C-O>w 1282 call feedkeys("iindeed \<F4>little ", 'xt') 1283 call assert_equal(['indeed some short little lines', 'of test text'], getline(1, '$')) 1284 call assert_fails('call feedkeys("i\<F6> 2", "xt")', 'E605:') 1285 call assert_equal(['indeed some short little 2 lines', 'of test text'], getline(1, '$')) 1286 1287 " Note when entering visual mode from InsertEnter autocmd, an async event, 1288 " or a <Cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode. 1289 call feedkeys("i\<F7>stuff ", 'xt') 1290 call assert_equal(['indeed some short little 2 lines', 'of stuff test text'], getline(1, '$')) 1291 call assert_equal(['v', 1, 3, 2, 9], [mode(1), line('v'), col('v'), line('.'), col('.')]) 1292 1293 call feedkeys("\<F5>", 'xt') 1294 call assert_equal(['deed some short little 2 lines', 'of stuff '], getreg('a', 1, 1)) 1295 1296 " also works as part of abbreviation 1297 abbr foo <Cmd>let g:y = 17<CR>bar 1298 exe "normal i\<space>foo " 1299 call assert_equal(17, g:y) 1300 call assert_equal('in bar deed some short little 2 lines', getline(1)) 1301 unabbr foo 1302 1303 " :startinsert does nothing 1304 call setline(1, 'foo bar') 1305 call feedkeys("ggi\<F8>vim", 'xt') 1306 call assert_equal('vimfoo bar', getline(1)) 1307 1308 " :stopinsert works 1309 call feedkeys("ggi\<F9>Abc", 'xt') 1310 call assert_equal('vimfoo barbc', getline(1)) 1311 1312 call s:cleanupMaps() 1313 %bw! 1314endfunc 1315 1316" Test for <Cmd> mapping in insert-completion mode 1317func Test_map_cmdkey_insert_complete_mode() 1318 new 1319 call s:setupMaps() 1320 1321 call setline(1, 'some short lines') 1322 call feedkeys("os\<C-X>\<C-N>\<F3>\<C-N> ", 'xt') 1323 call assert_equal('ic', m) 1324 call assert_equal(['some short lines', 'short '], getline(1, '$')) 1325 1326 call s:cleanupMaps() 1327 %bw! 1328endfunc 1329 1330" Test for <Cmd> mapping in cmdline mode 1331func Test_map_cmdkey_cmdline_mode() 1332 new 1333 call s:setupMaps() 1334 1335 call setline(1, ['some short lines', 'of test text']) 1336 let x = 0 1337 call feedkeys(":let x\<F3>= 10\r", 'xt') 1338 call assert_equal('c', m) 1339 call assert_equal(10, x) 1340 1341 " exception doesn't leave cmdline mode 1342 call assert_fails('call feedkeys(":let x\<F6>= 20\r", "xt")', 'E605:') 1343 call assert_equal(20, x) 1344 1345 " move cursor in the buffer from cmdline mode 1346 call feedkeys(":let x\<F4>= 30\r", 'xt') 1347 call assert_equal(30, x) 1348 call assert_equal(12, col('.')) 1349 1350 " :startinsert takes effect after leaving cmdline mode 1351 call feedkeys(":let x\<F8>= 40\rnew ", 'xt') 1352 call assert_equal(40, x) 1353 call assert_equal('some short new lines', getline(1)) 1354 1355 call s:cleanupMaps() 1356 %bw! 1357endfunc 1358 1359func Test_map_cmdkey_redo() 1360 func SelectDash() 1361 call search('^---\n\zs', 'bcW') 1362 norm! V 1363 call search('\n\ze---$', 'W') 1364 endfunc 1365 1366 let text =<< trim END 1367 --- 1368 aaa 1369 --- 1370 bbb 1371 bbb 1372 --- 1373 ccc 1374 ccc 1375 ccc 1376 --- 1377 END 1378 new Xcmdtext 1379 call setline(1, text) 1380 1381 onoremap <silent> i- <Cmd>call SelectDash()<CR> 1382 call feedkeys('2Gdi-', 'xt') 1383 call assert_equal(['---', '---'], getline(1, 2)) 1384 call feedkeys('j.', 'xt') 1385 call assert_equal(['---', '---', '---'], getline(1, 3)) 1386 call feedkeys('j.', 'xt') 1387 call assert_equal(['---', '---', '---', '---'], getline(1, 4)) 1388 1389 bwipe! 1390 call delete('Xcmdtext') 1391 delfunc SelectDash 1392 ounmap i- 1393endfunc 1394 1395" Test for using <script> with a map to remap characters in rhs 1396func Test_script_local_remap() 1397 new 1398 inoremap <buffer> <SID>xyz mno 1399 inoremap <buffer> <script> abc st<SID>xyzre 1400 normal iabc 1401 call assert_equal('stmnore', getline(1)) 1402 bwipe! 1403endfunc 1404 1405func Test_abbreviate_multi_byte() 1406 new 1407 iabbrev foo bar 1408 call feedkeys("ifoo…\<Esc>", 'xt') 1409 call assert_equal("bar…", getline(1)) 1410 iunabbrev foo 1411 bwipe! 1412endfunc 1413 1414" vim: shiftwidth=2 sts=2 expandtab 1415