1" Tests for autocommands 2 3func! s:cleanup_buffers() abort 4 for bnr in range(1, bufnr('$')) 5 if bufloaded(bnr) && bufnr('%') != bnr 6 execute 'bd! ' . bnr 7 endif 8 endfor 9endfunc 10 11func Test_vim_did_enter() 12 call assert_false(v:vim_did_enter) 13 14 " This script will never reach the main loop, can't check if v:vim_did_enter 15 " becomes one. 16endfunc 17 18if has('timers') 19 func ExitInsertMode(id) 20 call feedkeys("\<Esc>") 21 endfunc 22 23 func Test_cursorhold_insert() 24 " Need to move the cursor. 25 call feedkeys("ggG", "xt") 26 27 let g:triggered = 0 28 au CursorHoldI * let g:triggered += 1 29 set updatetime=20 30 call timer_start(100, 'ExitInsertMode') 31 call feedkeys('a', 'x!') 32 call assert_equal(1, g:triggered) 33 au! CursorHoldI 34 set updatetime& 35 endfunc 36 37 func Test_cursorhold_insert_ctrl_x() 38 let g:triggered = 0 39 au CursorHoldI * let g:triggered += 1 40 set updatetime=20 41 call timer_start(100, 'ExitInsertMode') 42 " CursorHoldI does not trigger after CTRL-X 43 call feedkeys("a\<C-X>", 'x!') 44 call assert_equal(0, g:triggered) 45 au! CursorHoldI 46 set updatetime& 47 endfunc 48endif 49 50func Test_bufunload() 51 augroup test_bufunload_group 52 autocmd! 53 autocmd BufUnload * call add(s:li, "bufunload") 54 autocmd BufDelete * call add(s:li, "bufdelete") 55 autocmd BufWipeout * call add(s:li, "bufwipeout") 56 augroup END 57 58 let s:li=[] 59 new 60 setlocal bufhidden= 61 bunload 62 call assert_equal(["bufunload", "bufdelete"], s:li) 63 64 let s:li=[] 65 new 66 setlocal bufhidden=delete 67 bunload 68 call assert_equal(["bufunload", "bufdelete"], s:li) 69 70 let s:li=[] 71 new 72 setlocal bufhidden=unload 73 bwipeout 74 call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) 75 76 au! test_bufunload_group 77 augroup! test_bufunload_group 78endfunc 79 80" SEGV occurs in older versions. (At least 7.4.2005 or older) 81func Test_autocmd_bufunload_with_tabnext() 82 tabedit 83 tabfirst 84 85 augroup test_autocmd_bufunload_with_tabnext_group 86 autocmd! 87 autocmd BufUnload <buffer> tabnext 88 augroup END 89 90 quit 91 call assert_equal(2, tabpagenr('$')) 92 93 autocmd! test_autocmd_bufunload_with_tabnext_group 94 augroup! test_autocmd_bufunload_with_tabnext_group 95 tablast 96 quit 97endfunc 98 99func Test_autocmd_bufwinleave_with_tabfirst() 100 tabedit 101 augroup sample 102 autocmd! 103 autocmd BufWinLeave <buffer> tabfirst 104 augroup END 105 call setline(1, ['a', 'b', 'c']) 106 edit! a.txt 107 tabclose 108endfunc 109 110" SEGV occurs in older versions. (At least 7.4.2321 or older) 111func Test_autocmd_bufunload_avoiding_SEGV_01() 112 split aa.txt 113 let lastbuf = bufnr('$') 114 115 augroup test_autocmd_bufunload 116 autocmd! 117 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' 118 augroup END 119 120 call assert_fails('edit bb.txt', 'E937:') 121 122 autocmd! test_autocmd_bufunload 123 augroup! test_autocmd_bufunload 124 bwipe! aa.txt 125 bwipe! bb.txt 126endfunc 127 128" SEGV occurs in older versions. (At least 7.4.2321 or older) 129func Test_autocmd_bufunload_avoiding_SEGV_02() 130 setlocal buftype=nowrite 131 let lastbuf = bufnr('$') 132 133 augroup test_autocmd_bufunload 134 autocmd! 135 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' 136 augroup END 137 138 normal! i1 139 call assert_fails('edit a.txt', 'E517:') 140 call feedkeys("\<CR>") 141 142 autocmd! test_autocmd_bufunload 143 augroup! test_autocmd_bufunload 144 bwipe! a.txt 145endfunc 146 147func Test_win_tab_autocmd() 148 let g:record = [] 149 150 augroup testing 151 au WinNew * call add(g:record, 'WinNew') 152 au WinEnter * call add(g:record, 'WinEnter') 153 au WinLeave * call add(g:record, 'WinLeave') 154 au TabNew * call add(g:record, 'TabNew') 155 au TabClosed * call add(g:record, 'TabClosed') 156 au TabEnter * call add(g:record, 'TabEnter') 157 au TabLeave * call add(g:record, 'TabLeave') 158 augroup END 159 160 split 161 tabnew 162 close 163 close 164 165 call assert_equal([ 166 \ 'WinLeave', 'WinNew', 'WinEnter', 167 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', 168 \ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter', 169 \ 'WinLeave', 'WinEnter' 170 \ ], g:record) 171 172 let g:record = [] 173 tabnew somefile 174 tabnext 175 bwipe somefile 176 177 call assert_equal([ 178 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', 179 \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 180 \ 'TabClosed' 181 \ ], g:record) 182 183 augroup testing 184 au! 185 augroup END 186 unlet g:record 187endfunc 188 189func s:AddAnAutocmd() 190 augroup vimBarTest 191 au BufReadCmd * echo 'hello' 192 augroup END 193 call assert_equal(3, len(split(execute('au vimBarTest'), "\n"))) 194endfunc 195 196func Test_early_bar() 197 " test that a bar is recognized before the {event} 198 call s:AddAnAutocmd() 199 augroup vimBarTest | au! | augroup END 200 call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) 201 202 call s:AddAnAutocmd() 203 augroup vimBarTest| au!| augroup END 204 call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) 205 206 " test that a bar is recognized after the {event} 207 call s:AddAnAutocmd() 208 augroup vimBarTest| au!BufReadCmd| augroup END 209 call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) 210 211 " test that a bar is recognized after the {group} 212 call s:AddAnAutocmd() 213 au! vimBarTest|echo 'hello' 214 call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) 215endfunc 216 217func RemoveGroup() 218 autocmd! StartOK 219 augroup! StartOK 220endfunc 221 222func Test_augroup_warning() 223 augroup TheWarning 224 au VimEnter * echo 'entering' 225 augroup END 226 call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0) 227 redir => res 228 augroup! TheWarning 229 redir END 230 call assert_true(match(res, "W19:") >= 0) 231 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0) 232 233 " check "Another" does not take the pace of the deleted entry 234 augroup Another 235 augroup END 236 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0) 237 augroup! Another 238 239 " no warning for postpone aucmd delete 240 augroup StartOK 241 au VimEnter * call RemoveGroup() 242 augroup END 243 call assert_true(match(execute('au VimEnter'), "StartOK.*VimEnter") >= 0) 244 redir => res 245 doautocmd VimEnter 246 redir END 247 call assert_true(match(res, "W19:") < 0) 248 au! VimEnter 249endfunc 250 251func Test_BufReadCmdHelp() 252 " This used to cause access to free memory 253 au BufReadCmd * e +h 254 help 255 256 au! BufReadCmd 257endfunc 258 259func Test_BufReadCmdHelpJump() 260 " This used to cause access to free memory 261 au BufReadCmd * e +h{ 262 " } to fix highlighting 263 call assert_fails('help', 'E434:') 264 265 au! BufReadCmd 266endfunc 267 268func Test_augroup_deleted() 269 " This caused a crash before E936 was introduced 270 augroup x 271 call assert_fails('augroup! x', 'E936:') 272 au VimEnter * echo 273 augroup end 274 augroup! x 275 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0) 276 au! VimEnter 277endfunc 278 279" Tests for autocommands on :close command. 280" This used to be in test13. 281func Test_three_windows() 282 " Clean up buffers, because in some cases this function fails. 283 call s:cleanup_buffers() 284 285 " Write three files and open them, each in a window. 286 " Then go to next window, with autocommand that deletes the previous one. 287 " Do this twice, writing the file. 288 e! Xtestje1 289 call setline(1, 'testje1') 290 w 291 sp Xtestje2 292 call setline(1, 'testje2') 293 w 294 sp Xtestje3 295 call setline(1, 'testje3') 296 w 297 wincmd w 298 au WinLeave Xtestje2 bwipe 299 wincmd w 300 call assert_equal('Xtestje1', expand('%')) 301 302 au WinLeave Xtestje1 bwipe Xtestje3 303 close 304 call assert_equal('Xtestje1', expand('%')) 305 306 " Test deleting the buffer on a Unload event. If this goes wrong there 307 " will be the ATTENTION prompt. 308 e Xtestje1 309 au! 310 au! BufUnload Xtestje1 bwipe 311 call assert_fails('e Xtestje3', 'E937:') 312 call assert_equal('Xtestje3', expand('%')) 313 314 e Xtestje2 315 sp Xtestje1 316 call assert_fails('e', 'E937:') 317 call assert_equal('Xtestje2', expand('%')) 318 319 " Test changing buffers in a BufWipeout autocommand. If this goes wrong 320 " there are ml_line errors and/or a Crash. 321 au! 322 only 323 e Xanother 324 e Xtestje1 325 bwipe Xtestje2 326 bwipe Xtestje3 327 au BufWipeout Xtestje1 buf Xtestje1 328 bwipe 329 call assert_equal('Xanother', expand('%')) 330 331 only 332 help 333 wincmd w 334 1quit 335 call assert_equal('Xanother', expand('%')) 336 337 au! 338 enew 339 bwipe! Xtestje1 340 call delete('Xtestje1') 341 call delete('Xtestje2') 342 call delete('Xtestje3') 343endfunc 344 345func Test_BufEnter() 346 au! BufEnter 347 au Bufenter * let val = val . '+' 348 let g:val = '' 349 split NewFile 350 call assert_equal('+', g:val) 351 bwipe! 352 call assert_equal('++', g:val) 353 354 " Also get BufEnter when editing a directory 355 call mkdir('Xdir') 356 split Xdir 357 call assert_equal('+++', g:val) 358 359 " On MS-Windows we can't edit the directory, make sure we wipe the right 360 " buffer. 361 bwipe! Xdir 362 363 call delete('Xdir', 'd') 364 au! BufEnter 365endfunc 366 367" Closing a window might cause an endless loop 368" E814 for older Vims 369func Test_autocmd_bufwipe_in_SessLoadPost() 370 edit Xtest 371 tabnew 372 file Xsomething 373 set noswapfile 374 mksession! 375 376 let content = ['set nocp noswapfile', 377 \ 'let v:swapchoice="e"', 378 \ 'augroup test_autocmd_sessionload', 379 \ 'autocmd!', 380 \ 'autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"', 381 \ 'augroup END', 382 \ '', 383 \ 'func WriteErrors()', 384 \ ' call writefile([execute("messages")], "Xerrors")', 385 \ 'endfunc', 386 \ 'au VimLeave * call WriteErrors()', 387 \ ] 388 call writefile(content, 'Xvimrc') 389 call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq') 390 let errors = join(readfile('Xerrors')) 391 call assert_match('E814', errors) 392 393 set swapfile 394 for file in ['Session.vim', 'Xvimrc', 'Xerrors'] 395 call delete(file) 396 endfor 397endfunc 398 399" SEGV occurs in older versions. 400func Test_autocmd_bufwipe_in_SessLoadPost2() 401 tabnew 402 set noswapfile 403 mksession! 404 405 let content = ['set nocp noswapfile', 406 \ 'function! DeleteInactiveBufs()', 407 \ ' tabfirst', 408 \ ' let tabblist = []', 409 \ ' for i in range(1, tabpagenr(''$''))', 410 \ ' call extend(tabblist, tabpagebuflist(i))', 411 \ ' endfor', 412 \ ' for b in range(1, bufnr(''$''))', 413 \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')', 414 \ ' exec ''bwipeout '' . b', 415 \ ' endif', 416 \ ' endfor', 417 \ ' echomsg "SessionLoadPost DONE"', 418 \ 'endfunction', 419 \ 'au SessionLoadPost * call DeleteInactiveBufs()', 420 \ '', 421 \ 'func WriteErrors()', 422 \ ' call writefile([execute("messages")], "Xerrors")', 423 \ 'endfunc', 424 \ 'au VimLeave * call WriteErrors()', 425 \ ] 426 call writefile(content, 'Xvimrc') 427 call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq') 428 let errors = join(readfile('Xerrors')) 429 " This probably only ever matches on unix. 430 call assert_notmatch('Caught deadly signal SEGV', errors) 431 call assert_match('SessionLoadPost DONE', errors) 432 433 set swapfile 434 for file in ['Session.vim', 'Xvimrc', 'Xerrors'] 435 call delete(file) 436 endfor 437endfunc 438 439func Test_empty_doau() 440 doau \| 441endfunc 442 443func s:AutoCommandOptionSet(match) 444 let item = remove(g:options, 0) 445 let expected = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", item[0], item[1], item[2], item[3]) 446 let actual = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", a:match, v:option_old, v:option_new, v:option_type) 447 let g:opt = [expected, actual] 448 "call assert_equal(expected, actual) 449endfunc 450 451func Test_OptionSet() 452 if !has("eval") || !has("autocmd") || !exists("+autochdir") 453 return 454 endif 455 456 badd test_autocmd.vim 457 458 call test_override('starting', 1) 459 set nocp 460 au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>")) 461 462 " 1: Setting number option" 463 let g:options=[['number', 0, 1, 'global']] 464 set nu 465 call assert_equal([], g:options) 466 call assert_equal(g:opt[0], g:opt[1]) 467 468 " 2: Setting local number option" 469 let g:options=[['number', 1, 0, 'local']] 470 setlocal nonu 471 call assert_equal([], g:options) 472 call assert_equal(g:opt[0], g:opt[1]) 473 474 " 3: Setting global number option" 475 let g:options=[['number', 1, 0, 'global']] 476 setglobal nonu 477 call assert_equal([], g:options) 478 call assert_equal(g:opt[0], g:opt[1]) 479 480 " 4: Setting local autoindent option" 481 let g:options=[['autoindent', 0, 1, 'local']] 482 setlocal ai 483 call assert_equal([], g:options) 484 call assert_equal(g:opt[0], g:opt[1]) 485 486 " 5: Setting global autoindent option" 487 let g:options=[['autoindent', 0, 1, 'global']] 488 setglobal ai 489 call assert_equal([], g:options) 490 call assert_equal(g:opt[0], g:opt[1]) 491 492 " 6: Setting global autoindent option" 493 let g:options=[['autoindent', 1, 0, 'global']] 494 set ai! 495 call assert_equal([], g:options) 496 call assert_equal(g:opt[0], g:opt[1]) 497 498 " Should not print anything, use :noa 499 " 7: don't trigger OptionSet" 500 let g:options=[['invalid', 1, 1, 'invalid']] 501 noa set nonu 502 call assert_equal([['invalid', 1, 1, 'invalid']], g:options) 503 call assert_equal(g:opt[0], g:opt[1]) 504 505 " 8: Setting several global list and number option" 506 let g:options=[['list', 0, 1, 'global'], ['number', 0, 1, 'global']] 507 set list nu 508 call assert_equal([], g:options) 509 call assert_equal(g:opt[0], g:opt[1]) 510 511 " 9: don't trigger OptionSet" 512 let g:options=[['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']] 513 noa set nolist nonu 514 call assert_equal([['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']], g:options) 515 call assert_equal(g:opt[0], g:opt[1]) 516 517 " 10: Setting global acd" 518 let g:options=[['autochdir', 0, 1, 'local']] 519 setlocal acd 520 call assert_equal([], g:options) 521 call assert_equal(g:opt[0], g:opt[1]) 522 523 " 11: Setting global autoread (also sets local value)" 524 let g:options=[['autoread', 0, 1, 'global']] 525 set ar 526 call assert_equal([], g:options) 527 call assert_equal(g:opt[0], g:opt[1]) 528 529 " 12: Setting local autoread" 530 let g:options=[['autoread', 1, 1, 'local']] 531 setlocal ar 532 call assert_equal([], g:options) 533 call assert_equal(g:opt[0], g:opt[1]) 534 535 " 13: Setting global autoread" 536 let g:options=[['autoread', 1, 0, 'global']] 537 setglobal invar 538 call assert_equal([], g:options) 539 call assert_equal(g:opt[0], g:opt[1]) 540 541 " 14: Setting option backspace through :let" 542 let g:options=[['backspace', '', 'eol,indent,start', 'global']] 543 let &bs="eol,indent,start" 544 call assert_equal([], g:options) 545 call assert_equal(g:opt[0], g:opt[1]) 546 547 " 15: Setting option backspace through setbufvar()" 548 let g:options=[['backup', 0, 1, 'local']] 549 " try twice, first time, shouldn't trigger because option name is invalid, 550 " second time, it should trigger 551 let bnum = bufnr('%') 552 call assert_fails("call setbufvar(bnum, '&l:bk', 1)", "E355") 553 " should trigger, use correct option name 554 call setbufvar(bnum, '&backup', 1) 555 call assert_equal([], g:options) 556 call assert_equal(g:opt[0], g:opt[1]) 557 558 " 16: Setting number option using setwinvar" 559 let g:options=[['number', 0, 1, 'local']] 560 call setwinvar(0, '&number', 1) 561 call assert_equal([], g:options) 562 call assert_equal(g:opt[0], g:opt[1]) 563 564 " 17: Setting key option, shouldn't trigger" 565 let g:options=[['key', 'invalid', 'invalid1', 'invalid']] 566 setlocal key=blah 567 setlocal key= 568 call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options) 569 call assert_equal(g:opt[0], g:opt[1]) 570 571 " 18: Setting string option" 572 let oldval = &tags 573 let g:options=[['tags', oldval, 'tagpath', 'global']] 574 set tags=tagpath 575 call assert_equal([], g:options) 576 call assert_equal(g:opt[0], g:opt[1]) 577 578 " 1l: Resetting string option" 579 let g:options=[['tags', 'tagpath', oldval, 'global']] 580 set tags& 581 call assert_equal([], g:options) 582 call assert_equal(g:opt[0], g:opt[1]) 583 584 " Cleanup 585 au! OptionSet 586 for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp'] 587 exe printf(":set %s&vi", opt) 588 endfor 589 call test_override('starting', 0) 590 delfunc! AutoCommandOptionSet 591endfunc 592 593func Test_OptionSet_diffmode() 594 call test_override('starting', 1) 595 " 18: Changing an option when enetering diff mode 596 new 597 au OptionSet diff :let &l:cul=v:option_new 598 599 call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) 600 call assert_equal(0, &l:cul) 601 diffthis 602 call assert_equal(1, &l:cul) 603 604 vnew 605 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) 606 call assert_equal(0, &l:cul) 607 diffthis 608 call assert_equal(1, &l:cul) 609 610 diffoff 611 call assert_equal(0, &l:cul) 612 call assert_equal(1, getwinvar(2, '&l:cul')) 613 bw! 614 615 call assert_equal(1, &l:cul) 616 diffoff! 617 call assert_equal(0, &l:cul) 618 call assert_equal(0, getwinvar(1, '&l:cul')) 619 bw! 620 621 " Cleanup 622 au! OptionSet 623 call test_override('starting', 0) 624endfunc 625 626func Test_OptionSet_diffmode_close() 627 call test_override('starting', 1) 628 " 19: Try to close the current window when entering diff mode 629 " should not segfault 630 new 631 au OptionSet diff close 632 633 call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) 634 call assert_fails(':diffthis', 'E788') 635 call assert_equal(1, &diff) 636 vnew 637 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) 638 call assert_fails(':diffthis', 'E788') 639 call assert_equal(1, &diff) 640 bw! 641 call assert_fails(':diffoff!', 'E788') 642 bw! 643 644 " Cleanup 645 au! OptionSet 646 call test_override('starting', 0) 647 "delfunc! AutoCommandOptionSet 648endfunc 649 650" Test for Bufleave autocommand that deletes the buffer we are about to edit. 651func Test_BufleaveWithDelete() 652 new | edit Xfile1 653 654 augroup test_bufleavewithdelete 655 autocmd! 656 autocmd BufLeave Xfile1 bwipe Xfile2 657 augroup END 658 659 call assert_fails('edit Xfile2', 'E143:') 660 call assert_equal('Xfile1', bufname('%')) 661 662 autocmd! test_bufleavewithdelete BufLeave Xfile1 663 augroup! test_bufleavewithdelete 664 665 new 666 bwipe! Xfile1 667endfunc 668 669" Test for autocommand that changes the buffer list, when doing ":ball". 670func Test_Acmd_BufAll() 671 enew! 672 %bwipe! 673 call writefile(['Test file Xxx1'], 'Xxx1') 674 call writefile(['Test file Xxx2'], 'Xxx2') 675 call writefile(['Test file Xxx3'], 'Xxx3') 676 677 " Add three files to the buffer list 678 split Xxx1 679 close 680 split Xxx2 681 close 682 split Xxx3 683 close 684 685 " Wipe the buffer when the buffer is opened 686 au BufReadPost Xxx2 bwipe 687 688 call append(0, 'Test file Xxx4') 689 ball 690 691 call assert_equal(2, winnr('$')) 692 call assert_equal('Xxx1', bufname(winbufnr(winnr('$')))) 693 wincmd t 694 695 au! BufReadPost 696 %bwipe! 697 call delete('Xxx1') 698 call delete('Xxx2') 699 call delete('Xxx3') 700 enew! | only 701endfunc 702 703" Test for autocommand that changes current buffer on BufEnter event. 704" Check if modelines are interpreted for the correct buffer. 705func Test_Acmd_BufEnter() 706 %bwipe! 707 call writefile(['start of test file Xxx1', 708 \ "\<Tab>this is a test", 709 \ 'end of test file Xxx1'], 'Xxx1') 710 call writefile(['start of test file Xxx2', 711 \ 'vim: set noai :', 712 \ "\<Tab>this is a test", 713 \ 'end of test file Xxx2'], 'Xxx2') 714 715 au BufEnter Xxx2 brew 716 set ai modeline modelines=3 717 edit Xxx1 718 " edit Xxx2, autocmd will do :brew 719 edit Xxx2 720 exe "normal G?this is a\<CR>" 721 " Append text with autoindent to this file 722 normal othis should be auto-indented 723 call assert_equal("\<Tab>this should be auto-indented", getline('.')) 724 call assert_equal(3, line('.')) 725 " Remove autocmd and edit Xxx2 again 726 au! BufEnter Xxx2 727 buf! Xxx2 728 exe "normal G?this is a\<CR>" 729 " append text without autoindent to Xxx 730 normal othis should be in column 1 731 call assert_equal("this should be in column 1", getline('.')) 732 call assert_equal(4, line('.')) 733 734 %bwipe! 735 call delete('Xxx1') 736 call delete('Xxx2') 737 set ai&vim modeline&vim modelines&vim 738endfunc 739 740" Test for issue #57 741" do not move cursor on <c-o> when autoindent is set 742func Test_ai_CTRL_O() 743 enew! 744 set ai 745 let save_fo = &fo 746 set fo+=r 747 exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>" 748 exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>" 749 call assert_equal(['# abc', 'def', 'def'], getline(2, 4)) 750 751 set ai&vim 752 let &fo = save_fo 753 enew! 754endfunc 755 756" Test for autocommand that deletes the current buffer on BufLeave event. 757" Also test deleting the last buffer, should give a new, empty buffer. 758func Test_BufLeave_Wipe() 759 %bwipe! 760 let content = ['start of test file Xxx', 761 \ 'this is a test', 762 \ 'end of test file Xxx'] 763 call writefile(content, 'Xxx1') 764 call writefile(content, 'Xxx2') 765 766 au BufLeave Xxx2 bwipe 767 edit Xxx1 768 split Xxx2 769 " delete buffer Xxx2, we should be back to Xxx1 770 bwipe 771 call assert_equal('Xxx1', bufname('%')) 772 call assert_equal(1, winnr('$')) 773 774 " Create an alternate buffer 775 %write! test.out 776 call assert_equal('test.out', bufname('#')) 777 " delete alternate buffer 778 bwipe test.out 779 call assert_equal('Xxx1', bufname('%')) 780 call assert_equal('', bufname('#')) 781 782 au BufLeave Xxx1 bwipe 783 " delete current buffer, get an empty one 784 bwipe! 785 call assert_equal(1, line('$')) 786 call assert_equal('', bufname('%')) 787 let g:bufinfo = getbufinfo() 788 call assert_equal(1, len(g:bufinfo)) 789 790 call delete('Xxx1') 791 call delete('Xxx2') 792 call delete('test.out') 793 %bwipe 794 au! BufLeave 795 796 " check that bufinfo doesn't contain a pointer to freed memory 797 call test_garbagecollect_now() 798endfunc 799 800func Test_QuitPre() 801 edit Xfoo 802 let winid = win_getid(winnr()) 803 split Xbar 804 au! QuitPre * let g:afile = expand('<afile>') 805 " Close the other window, <afile> should be correct. 806 exe win_id2win(winid) . 'q' 807 call assert_equal('Xfoo', g:afile) 808 809 unlet g:afile 810 bwipe Xfoo 811 bwipe Xbar 812endfunc 813 814func Test_Cmdline() 815 au! CmdlineEnter : let g:entered = expand('<afile>') 816 au! CmdlineLeave : let g:left = expand('<afile>') 817 let g:entered = 0 818 let g:left = 0 819 call feedkeys(":echo 'hello'\<CR>", 'xt') 820 call assert_equal(':', g:entered) 821 call assert_equal(':', g:left) 822 au! CmdlineEnter 823 au! CmdlineLeave 824 825 au! CmdlineEnter / let g:entered = expand('<afile>') 826 au! CmdlineLeave / let g:left = expand('<afile>') 827 let g:entered = 0 828 let g:left = 0 829 new 830 call setline(1, 'hello') 831 call feedkeys("/hello\<CR>", 'xt') 832 call assert_equal('/', g:entered) 833 call assert_equal('/', g:left) 834 bwipe! 835 au! CmdlineEnter 836 au! CmdlineLeave 837endfunc 838 839" Test for BufWritePre autocommand that deletes or unloads the buffer. 840func Test_BufWritePre() 841 %bwipe 842 au BufWritePre Xxx1 bunload 843 au BufWritePre Xxx2 bwipe 844 845 call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1') 846 call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2') 847 848 edit Xtest 849 e! Xxx2 850 bdel Xtest 851 e Xxx1 852 " write it, will unload it and give an error msg 853 call assert_fails('w', 'E203') 854 call assert_equal('Xxx2', bufname('%')) 855 edit Xtest 856 e! Xxx2 857 bwipe Xtest 858 " write it, will delete the buffer and give an error msg 859 call assert_fails('w', 'E203') 860 call assert_equal('Xxx1', bufname('%')) 861 au! BufWritePre 862 call delete('Xxx1') 863 call delete('Xxx2') 864endfunc 865 866" Test for BufUnload autocommand that unloads all the other buffers 867func Test_bufunload_all() 868 call writefile(['Test file Xxx1'], 'Xxx1')" 869 call writefile(['Test file Xxx2'], 'Xxx2')" 870 871 let content = [ 872 \ "func UnloadAllBufs()", 873 \ " let i = 1", 874 \ " while i <= bufnr('$')", 875 \ " if i != bufnr('%') && bufloaded(i)", 876 \ " exe i . 'bunload'", 877 \ " endif", 878 \ " let i += 1", 879 \ " endwhile", 880 \ "endfunc", 881 \ "au BufUnload * call UnloadAllBufs()", 882 \ "au VimLeave * call writefile(['Test Finished'], 'Xout')", 883 \ "edit Xxx1", 884 \ "split Xxx2", 885 \ "q"] 886 call writefile(content, 'Xtest') 887 888 call delete('Xout') 889 call system(v:progpath. ' --clean -N --not-a-term -S Xtest') 890 call assert_true(filereadable('Xout')) 891 892 call delete('Xxx1') 893 call delete('Xxx2') 894 call delete('Xtest') 895 call delete('Xout') 896endfunc 897 898" Some tests for buffer-local autocommands 899func Test_buflocal_autocmd() 900 let g:bname = '' 901 edit xx 902 au BufLeave <buffer> let g:bname = expand("%") 903 " here, autocommand for xx should trigger. 904 " but autocommand shall not apply to buffer named <buffer>. 905 edit somefile 906 call assert_equal('xx', g:bname) 907 let g:bname = '' 908 " here, autocommand shall be auto-deleted 909 bwipe xx 910 " autocmd should not trigger 911 edit xx 912 call assert_equal('', g:bname) 913 " autocmd should not trigger 914 edit somefile 915 call assert_equal('', g:bname) 916 enew 917 unlet g:bname 918endfunc 919 920" Test for "*Cmd" autocommands 921func Test_Cmd_Autocmds() 922 call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx') 923 924 enew! 925 au BufReadCmd XtestA 0r Xxx|$del 926 edit XtestA " will read text of Xxd instead 927 call assert_equal('start of Xxx', getline(1)) 928 929 au BufWriteCmd XtestA call append(line("$"), "write") 930 write " will append a line to the file 931 call assert_equal('write', getline('$')) 932 call assert_fails('read XtestA', 'E484') " should not read anything 933 call assert_equal('write', getline(4)) 934 935 " now we have: 936 " 1 start of Xxx 937 " 2 abc2 938 " 3 end of Xxx 939 " 4 write 940 941 au FileReadCmd XtestB '[r Xxx 942 2r XtestB " will read Xxx below line 2 instead 943 call assert_equal('start of Xxx', getline(3)) 944 945 " now we have: 946 " 1 start of Xxx 947 " 2 abc2 948 " 3 start of Xxx 949 " 4 abc2 950 " 5 end of Xxx 951 " 6 end of Xxx 952 " 7 write 953 954 au FileWriteCmd XtestC '[,']copy $ 955 normal 4GA1 956 4,5w XtestC " will copy lines 4 and 5 to the end 957 call assert_equal("\tabc21", getline(8)) 958 call assert_fails('r XtestC', 'E484') " should not read anything 959 call assert_equal("end of Xxx", getline(9)) 960 961 " now we have: 962 " 1 start of Xxx 963 " 2 abc2 964 " 3 start of Xxx 965 " 4 abc21 966 " 5 end of Xxx 967 " 6 end of Xxx 968 " 7 write 969 " 8 abc21 970 " 9 end of Xxx 971 972 let g:lines = [] 973 au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']"))) 974 w >>XtestD " will add lines to 'lines' 975 call assert_equal(9, len(g:lines)) 976 call assert_fails('$r XtestD', 'E484') " should not read anything 977 call assert_equal(9, line('$')) 978 call assert_equal('end of Xxx', getline('$')) 979 980 au BufReadCmd XtestE 0r Xxx|$del 981 sp XtestE " split window with test.out 982 call assert_equal('end of Xxx', getline(3)) 983 984 let g:lines = [] 985 exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>" 986 au BufWriteCmd XtestE call extend(g:lines, getline(0, '$')) 987 wall " will write other window to 'lines' 988 call assert_equal(4, len(g:lines), g:lines) 989 call assert_equal('asdf', g:lines[2]) 990 991 au! BufReadCmd 992 au! BufWriteCmd 993 au! FileReadCmd 994 au! FileWriteCmd 995 au! FileAppendCmd 996 %bwipe! 997 call delete('Xxx') 998 enew! 999endfunc 1000 1001func SetChangeMarks(start, end) 1002 exe a:start. 'mark [' 1003 exe a:end. 'mark ]' 1004endfunc 1005 1006" Verify the effects of autocmds on '[ and '] 1007func Test_change_mark_in_autocmds() 1008 edit! Xtest 1009 call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u", 'xtn') 1010 1011 call SetChangeMarks(2, 3) 1012 write 1013 call assert_equal([1, 4], [line("'["), line("']")]) 1014 1015 call SetChangeMarks(2, 3) 1016 au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")]) 1017 write 1018 au! BufWritePre 1019 1020 if executable('cat') 1021 write XtestFilter 1022 write >> XtestFilter 1023 1024 call SetChangeMarks(2, 3) 1025 " Marks are set to the entire range of the write 1026 au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")]) 1027 " '[ is adjusted to just before the line that will receive the filtered 1028 " data 1029 au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")]) 1030 " The filtered data is read into the buffer, and the source lines are 1031 " still present, so the range is after the source lines 1032 au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")]) 1033 %!cat XtestFilter 1034 " After the filtered data is read, the original lines are deleted 1035 call assert_equal([1, 8], [line("'["), line("']")]) 1036 au! FilterWritePre,FilterReadPre,FilterReadPost 1037 undo 1038 1039 call SetChangeMarks(1, 4) 1040 au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")]) 1041 au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")]) 1042 au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")]) 1043 2,3!cat XtestFilter 1044 call assert_equal([2, 9], [line("'["), line("']")]) 1045 au! FilterWritePre,FilterReadPre,FilterReadPost 1046 undo 1047 1048 call delete('XtestFilter') 1049 endif 1050 1051 call SetChangeMarks(1, 4) 1052 au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")]) 1053 2,3write Xtest2 1054 au! FileWritePre 1055 1056 call SetChangeMarks(2, 3) 1057 au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")]) 1058 write >> Xtest2 1059 au! FileAppendPre 1060 1061 call SetChangeMarks(1, 4) 1062 au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")]) 1063 2,3write >> Xtest2 1064 au! FileAppendPre 1065 1066 call SetChangeMarks(1, 1) 1067 au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")]) 1068 au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")]) 1069 3read Xtest2 1070 au! FileReadPre,FileReadPost 1071 undo 1072 1073 call SetChangeMarks(4, 4) 1074 " When the line is 0, it's adjusted to 1 1075 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")]) 1076 au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")]) 1077 0read Xtest2 1078 au! FileReadPre,FileReadPost 1079 undo 1080 1081 call SetChangeMarks(4, 4) 1082 " When the line is 0, it's adjusted to 1 1083 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")]) 1084 au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")]) 1085 1read Xtest2 1086 au! FileReadPre,FileReadPost 1087 undo 1088 1089 bwipe! 1090 call delete('Xtest') 1091 call delete('Xtest2') 1092endfunc 1093 1094func Test_Filter_noshelltemp() 1095 if !executable('cat') 1096 return 1097 endif 1098 1099 enew! 1100 call setline(1, ['a', 'b', 'c', 'd']) 1101 1102 let shelltemp = &shelltemp 1103 set shelltemp 1104 1105 let g:filter_au = 0 1106 au FilterWritePre * let g:filter_au += 1 1107 au FilterReadPre * let g:filter_au += 1 1108 au FilterReadPost * let g:filter_au += 1 1109 %!cat 1110 call assert_equal(3, g:filter_au) 1111 1112 if has('filterpipe') 1113 set noshelltemp 1114 1115 let g:filter_au = 0 1116 au FilterWritePre * let g:filter_au += 1 1117 au FilterReadPre * let g:filter_au += 1 1118 au FilterReadPost * let g:filter_au += 1 1119 %!cat 1120 call assert_equal(0, g:filter_au) 1121 endif 1122 1123 au! FilterWritePre,FilterReadPre,FilterReadPost 1124 let &shelltemp = shelltemp 1125 bwipe! 1126endfunc 1127 1128func Test_TextYankPost() 1129 enew! 1130 call setline(1, ['foo']) 1131 1132 let g:event = [] 1133 au TextYankPost * let g:event = copy(v:event) 1134 1135 call assert_equal({}, v:event) 1136 call assert_fails('let v:event = {}', 'E46:') 1137 call assert_fails('let v:event.mykey = 0', 'E742:') 1138 1139 norm "ayiw 1140 call assert_equal( 1141 \{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'}, 1142 \g:event) 1143 norm y_ 1144 call assert_equal( 1145 \{'regcontents': ['foo'], 'regname': '', 'operator': 'y', 'regtype': 'V'}, 1146 \g:event) 1147 call feedkeys("\<C-V>y", 'x') 1148 call assert_equal( 1149 \{'regcontents': ['f'], 'regname': '', 'operator': 'y', 'regtype': "\x161"}, 1150 \g:event) 1151 norm "xciwbar 1152 call assert_equal( 1153 \{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'}, 1154 \g:event) 1155 norm "bdiw 1156 call assert_equal( 1157 \{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'}, 1158 \g:event) 1159 1160 call assert_equal({}, v:event) 1161 1162 au! TextYankPost 1163 unlet g:event 1164 bwipe! 1165endfunc 1166