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