1" Tests for tagjump (tags and special searches) 2 3source check.vim 4source screendump.vim 5 6" SEGV occurs in older versions. (At least 7.4.1748 or older) 7func Test_ptag_with_notagstack() 8 CheckFeature quickfix 9 10 set notagstack 11 call assert_fails('ptag does_not_exist_tag_name', 'E426') 12 set tagstack&vim 13endfunc 14 15func Test_cancel_ptjump() 16 CheckFeature quickfix 17 18 set tags=Xtags 19 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 20 \ "word\tfile1\tcmd1", 21 \ "word\tfile2\tcmd2"], 22 \ 'Xtags') 23 24 only! 25 call feedkeys(":ptjump word\<CR>\<CR>", "xt") 26 help 27 call assert_equal(2, winnr('$')) 28 29 call delete('Xtags') 30 set tags& 31 quit 32endfunc 33 34func Test_static_tagjump() 35 set tags=Xtags 36 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 37 \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)", 38 \ "word\tXfile2\tcmd2"], 39 \ 'Xtags') 40 new Xfile1 41 call setline(1, ['empty', 'one()', 'empty']) 42 write 43 tag one 44 call assert_equal(2, line('.')) 45 46 bwipe! 47 set tags& 48 call delete('Xtags') 49 call delete('Xfile1') 50endfunc 51 52func Test_duplicate_tagjump() 53 set tags=Xtags 54 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 55 \ "thesame\tXfile1\t1;\"\td\tfile:", 56 \ "thesame\tXfile1\t2;\"\td\tfile:", 57 \ "thesame\tXfile1\t3;\"\td\tfile:", 58 \ ], 59 \ 'Xtags') 60 new Xfile1 61 call setline(1, ['thesame one', 'thesame two', 'thesame three']) 62 write 63 tag thesame 64 call assert_equal(1, line('.')) 65 tnext 66 call assert_equal(2, line('.')) 67 tnext 68 call assert_equal(3, line('.')) 69 70 bwipe! 71 set tags& 72 call delete('Xtags') 73 call delete('Xfile1') 74endfunc 75 76func Test_tagjump_switchbuf() 77 CheckFeature quickfix 78 79 set tags=Xtags 80 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 81 \ "second\tXfile1\t2", 82 \ "third\tXfile1\t3",], 83 \ 'Xtags') 84 call writefile(['first', 'second', 'third'], 'Xfile1') 85 86 enew | only 87 set switchbuf= 88 stag second 89 call assert_equal(2, winnr('$')) 90 call assert_equal(2, line('.')) 91 stag third 92 call assert_equal(3, winnr('$')) 93 call assert_equal(3, line('.')) 94 95 enew | only 96 set switchbuf=useopen 97 stag second 98 call assert_equal(2, winnr('$')) 99 call assert_equal(2, line('.')) 100 stag third 101 call assert_equal(2, winnr('$')) 102 call assert_equal(3, line('.')) 103 104 enew | only 105 set switchbuf=usetab 106 tab stag second 107 call assert_equal(2, tabpagenr('$')) 108 call assert_equal(2, line('.')) 109 1tabnext | stag third 110 call assert_equal(2, tabpagenr('$')) 111 call assert_equal(3, line('.')) 112 113 tabclose! 114 enew | only 115 call delete('Xfile1') 116 call delete('Xtags') 117 set tags& 118 set switchbuf&vim 119endfunc 120 121" Tests for [ CTRL-I and CTRL-W CTRL-I commands 122function Test_keyword_jump() 123 call writefile(["#include Xinclude", "", 124 \ "", 125 \ "/* test text test tex start here", 126 \ " some text", 127 \ " test text", 128 \ " start OK if found this line", 129 \ " start found wrong line", 130 \ "test text"], 'Xtestfile') 131 call writefile(["/* test text test tex start here", 132 \ " some text", 133 \ " test text", 134 \ " start OK if found this line", 135 \ " start found wrong line", 136 \ "test text"], 'Xinclude') 137 new Xtestfile 138 call cursor(1,1) 139 call search("start") 140 exe "normal! 5[\<C-I>" 141 call assert_equal(" start OK if found this line", getline('.')) 142 call cursor(1,1) 143 call search("start") 144 exe "normal! 5\<C-W>\<C-I>" 145 call assert_equal(" start OK if found this line", getline('.')) 146 enew! | only 147 call delete('Xtestfile') 148 call delete('Xinclude') 149endfunction 150 151" Test for jumping to a tag with 'hidden' set, with symbolic link in path of 152" tag. This only works for Unix, because of the symbolic link. 153func Test_tag_symbolic() 154 if !has('unix') 155 return 156 endif 157 set hidden 158 call delete("Xtest.dir", "rf") 159 call system("ln -s . Xtest.dir") 160 " Create a tags file with the current directory name inserted. 161 call writefile([ 162 \ "SECTION_OFF " . getcwd() . "/Xtest.dir/Xtest.c /^#define SECTION_OFF 3$/", 163 \ '', 164 \ ], 'Xtags') 165 call writefile(['#define SECTION_OFF 3', 166 \ '#define NUM_SECTIONS 3'], 'Xtest.c') 167 168 " Try jumping to a tag, but with a path that contains a symbolic link. When 169 " wrong, this will give the ATTENTION message. The next space will then be 170 " eaten by hit-return, instead of moving the cursor to 'd'. 171 set tags=Xtags 172 enew! 173 call append(0, 'SECTION_OFF') 174 call cursor(1,1) 175 exe "normal \<C-]> " 176 call assert_equal('Xtest.c', expand('%:t')) 177 call assert_equal(2, col('.')) 178 179 set hidden& 180 set tags& 181 enew! 182 call delete('Xtags') 183 call delete('Xtest.c') 184 call delete("Xtest.dir", "rf") 185 %bwipe! 186endfunc 187 188" Tests for tag search with !_TAG_FILE_ENCODING. 189" Depends on the test83-tags2 and test83-tags3 files. 190func Test_tag_file_encoding() 191 if has('vms') 192 return 193 endif 194 195 if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21" 196 return 197 endif 198 199 let save_enc = &encoding 200 set encoding=utf8 201 202 let content = ['text for tags1', 'abcdefghijklmnopqrs'] 203 call writefile(content, 'Xtags1.txt') 204 let content = ['text for tags2', 'ABC'] 205 call writefile(content, 'Xtags2.txt') 206 let content = ['text for tags3', 'ABC'] 207 call writefile(content, 'Xtags3.txt') 208 let content = ['!_TAG_FILE_ENCODING utf-8 //', 'abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs'] 209 call writefile(content, 'Xtags1') 210 211 " case1: 212 new 213 set tags=Xtags1 214 tag abcdefghijklmnopqrs 215 call assert_equal('Xtags1.txt', expand('%:t')) 216 call assert_equal('abcdefghijklmnopqrs', getline('.')) 217 close 218 219 " case2: 220 new 221 set tags=test83-tags2 222 tag /.BC 223 call assert_equal('Xtags2.txt', expand('%:t')) 224 call assert_equal('ABC', getline('.')) 225 close 226 227 " case3: 228 new 229 set tags=test83-tags3 230 tag abc50 231 call assert_equal('Xtags3.txt', expand('%:t')) 232 call assert_equal('ABC', getline('.')) 233 close 234 235 set tags& 236 let &encoding = save_enc 237 call delete('Xtags1.txt') 238 call delete('Xtags2.txt') 239 call delete('Xtags3.txt') 240 call delete('Xtags1') 241endfunc 242 243func Test_tagjump_etags() 244 if !has('emacs_tags') 245 return 246 endif 247 call writefile([ 248 \ "void foo() {}", 249 \ "int main(int argc, char **argv)", 250 \ "{", 251 \ "\tfoo();", 252 \ "\treturn 0;", 253 \ "}", 254 \ ], 'Xmain.c') 255 256 call writefile([ 257 \ "\x0c", 258 \ "Xmain.c,64", 259 \ "void foo() {}\x7ffoo\x011,0", 260 \ "int main(int argc, char **argv)\x7fmain\x012,14", 261 \ ], 'Xtags') 262 set tags=Xtags 263 ta foo 264 call assert_equal('void foo() {}', getline('.')) 265 266 call delete('Xtags') 267 call delete('Xmain.c') 268 bwipe! 269endfunc 270 271" Test for getting and modifying the tag stack 272func Test_getsettagstack() 273 call writefile(['line1', 'line2', 'line3'], 'Xfile1') 274 call writefile(['line1', 'line2', 'line3'], 'Xfile2') 275 call writefile(['line1', 'line2', 'line3'], 'Xfile3') 276 277 enew | only 278 call settagstack(1, {'items' : []}) 279 call assert_equal(0, gettagstack(1).length) 280 call assert_equal([], 1->gettagstack().items) 281 " Error cases 282 call assert_equal({}, gettagstack(100)) 283 call assert_equal(-1, settagstack(100, {'items' : []})) 284 call assert_fails('call settagstack(1, [1, 10])', 'E715') 285 call assert_fails("call settagstack(1, {'items' : 10})", 'E714') 286 call assert_fails("call settagstack(1, {'items' : []}, 10)", 'E928') 287 call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962') 288 call assert_equal(-1, settagstack(0, test_null_dict())) 289 290 set tags=Xtags 291 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 292 \ "one\tXfile1\t1", 293 \ "three\tXfile3\t3", 294 \ "two\tXfile2\t2"], 295 \ 'Xtags') 296 297 let stk = [] 298 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'one', 299 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 300 tag one 301 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'two', 302 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 303 tag two 304 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'three', 305 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 306 tag three 307 call assert_equal(3, gettagstack(1).length) 308 call assert_equal(stk, gettagstack(1).items) 309 " Check for default - current window 310 call assert_equal(3, gettagstack().length) 311 call assert_equal(stk, gettagstack().items) 312 313 " Try to set current index to invalid values 314 call settagstack(1, {'curidx' : -1}) 315 call assert_equal(1, gettagstack().curidx) 316 eval {'curidx' : 50}->settagstack(1) 317 call assert_equal(4, gettagstack().curidx) 318 319 " Try pushing invalid items onto the stack 320 call settagstack(1, {'items' : []}) 321 call settagstack(1, {'items' : ["plate"]}, 'a') 322 call assert_equal(0, gettagstack().length) 323 call assert_equal([], gettagstack().items) 324 call settagstack(1, {'items' : [{"tagname" : "abc"}]}, 'a') 325 call assert_equal(0, gettagstack().length) 326 call assert_equal([], gettagstack().items) 327 call settagstack(1, {'items' : [{"from" : 100}]}, 'a') 328 call assert_equal(0, gettagstack().length) 329 call assert_equal([], gettagstack().items) 330 call settagstack(1, {'items' : [{"from" : [2, 1, 0, 0]}]}, 'a') 331 call assert_equal(0, gettagstack().length) 332 call assert_equal([], gettagstack().items) 333 334 " Push one item at a time to the stack 335 call settagstack(1, {'items' : []}) 336 call settagstack(1, {'items' : [stk[0]]}, 'a') 337 call settagstack(1, {'items' : [stk[1]]}, 'a') 338 call settagstack(1, {'items' : [stk[2]]}, 'a') 339 call settagstack(1, {'curidx' : 4}) 340 call assert_equal({'length' : 3, 'curidx' : 4, 'items' : stk}, 341 \ gettagstack(1)) 342 343 " Try pushing items onto a full stack 344 for i in range(7) 345 call settagstack(1, {'items' : stk}, 'a') 346 endfor 347 call assert_equal(20, gettagstack().length) 348 call settagstack(1, 349 \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a') 350 call assert_equal('abc', gettagstack().items[19].tagname) 351 352 " truncate the tag stack 353 call settagstack(1, 354 \ {'curidx' : 9, 355 \ 'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') 356 let t = gettagstack() 357 call assert_equal(9, t.length) 358 call assert_equal(10, t.curidx) 359 360 " truncate the tag stack without pushing any new items 361 call settagstack(1, {'curidx' : 5}, 't') 362 let t = gettagstack() 363 call assert_equal(4, t.length) 364 call assert_equal(5, t.curidx) 365 366 " truncate an empty tag stack and push new items 367 call settagstack(1, {'items' : []}) 368 call settagstack(1, 369 \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') 370 let t = gettagstack() 371 call assert_equal(1, t.length) 372 call assert_equal(2, t.curidx) 373 374 " Tag with multiple matches 375 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 376 \ "two\tXfile1\t1", 377 \ "two\tXfile2\t3", 378 \ "two\tXfile3\t2"], 379 \ 'Xtags') 380 call settagstack(1, {'items' : []}) 381 tag two 382 tnext 383 tnext 384 call assert_equal(1, gettagstack().length) 385 call assert_equal(3, gettagstack().items[0].matchnr) 386 387 " Memory allocation failures 388 call test_alloc_fail(GetAllocId('tagstack_items'), 0, 0) 389 call assert_fails('call gettagstack()', 'E342:') 390 call test_alloc_fail(GetAllocId('tagstack_from'), 0, 0) 391 call assert_fails('call gettagstack()', 'E342:') 392 call test_alloc_fail(GetAllocId('tagstack_details'), 0, 0) 393 call assert_fails('call gettagstack()', 'E342:') 394 395 call settagstack(1, {'items' : []}) 396 call delete('Xfile1') 397 call delete('Xfile2') 398 call delete('Xfile3') 399 call delete('Xtags') 400 set tags& 401endfunc 402 403func Test_tag_with_count() 404 call writefile([ 405 \ 'test Xtest.h /^void test();$/;" p typeref:typename:void signature:()', 406 \ ], 'Xtags') 407 call writefile([ 408 \ 'main Xtest.c /^int main()$/;" f typeref:typename:int signature:()', 409 \ 'test Xtest.c /^void test()$/;" f typeref:typename:void signature:()', 410 \ ], 'Ytags') 411 cal writefile([ 412 \ 'int main()', 413 \ 'void test()', 414 \ ], 'Xtest.c') 415 cal writefile([ 416 \ 'void test();', 417 \ ], 'Xtest.h') 418 set tags=Xtags,Ytags 419 420 new Xtest.c 421 let tl = taglist('test', 'Xtest.c') 422 call assert_equal(tl[0].filename, 'Xtest.c') 423 call assert_equal(tl[1].filename, 'Xtest.h') 424 425 tag test 426 call assert_equal(bufname('%'), 'Xtest.c') 427 1tag test 428 call assert_equal(bufname('%'), 'Xtest.c') 429 2tag test 430 call assert_equal(bufname('%'), 'Xtest.h') 431 432 set tags& 433 call delete('Xtags') 434 call delete('Ytags') 435 bwipe Xtest.h 436 bwipe Xtest.c 437 call delete('Xtest.h') 438 call delete('Xtest.c') 439endfunc 440 441func Test_tagnr_recall() 442 call writefile([ 443 \ 'test Xtest.h /^void test();$/;" p', 444 \ 'main Xtest.c /^int main()$/;" f', 445 \ 'test Xtest.c /^void test()$/;" f', 446 \ ], 'Xtags') 447 cal writefile([ 448 \ 'int main()', 449 \ 'void test()', 450 \ ], 'Xtest.c') 451 cal writefile([ 452 \ 'void test();', 453 \ ], 'Xtest.h') 454 set tags=Xtags 455 456 new Xtest.c 457 let tl = taglist('test', 'Xtest.c') 458 call assert_equal(tl[0].filename, 'Xtest.c') 459 call assert_equal(tl[1].filename, 'Xtest.h') 460 461 2tag test 462 call assert_equal(bufname('%'), 'Xtest.h') 463 pop 464 call assert_equal(bufname('%'), 'Xtest.c') 465 tag 466 call assert_equal(bufname('%'), 'Xtest.h') 467 468 set tags& 469 call delete('Xtags') 470 bwipe Xtest.h 471 bwipe Xtest.c 472 call delete('Xtest.h') 473 call delete('Xtest.c') 474endfunc 475 476func Test_tag_line_toolong() 477 call writefile([ 478 \ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' 479 \ ], 'Xtags') 480 set tags=Xtags 481 let old_vbs = &verbose 482 set verbose=5 483 " ":tjump" should give "tag not found" not "Format error in tags file" 484 call assert_fails('tj /foo', 'E426') 485 try 486 tj /foo 487 catch /^Vim\%((\a\+)\)\=:E431/ 488 call assert_report(v:exception) 489 catch /.*/ 490 endtry 491 call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) 492 493 call writefile([ 494 \ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' 495 \ ], 'Xtags') 496 call assert_fails('tj /foo', 'E426') 497 try 498 tj /foo 499 catch /^Vim\%((\a\+)\)\=:E431/ 500 call assert_report(v:exception) 501 catch /.*/ 502 endtry 503 call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) 504 505 " binary search works in file with long line 506 call writefile([ 507 \ 'asdfasfd nowhere 16', 508 \ 'foobar Xsomewhere 3; " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567', 509 \ 'zasdfasfd nowhere 16', 510 \ ], 'Xtags') 511 call writefile([ 512 \ 'one', 513 \ 'two', 514 \ 'trhee', 515 \ 'four', 516 \ ], 'Xsomewhere') 517 tag foobar 518 call assert_equal('Xsomewhere', expand('%')) 519 call assert_equal(3, getcurpos()[1]) 520 521 call delete('Xtags') 522 call delete('Xsomewhere') 523 set tags& 524 let &verbose = old_vbs 525endfunc 526 527" Check that using :tselect does not run into the hit-enter prompt. 528" Requires a terminal to trigger that prompt. 529func Test_tselect() 530 CheckScreendump 531 532 call writefile([ 533 \ 'main Xtest.h /^void test();$/;" f', 534 \ 'main Xtest.c /^int main()$/;" f', 535 \ 'main Xtest.x /^void test()$/;" f', 536 \ ], 'Xtags') 537 cal writefile([ 538 \ 'int main()', 539 \ 'void test()', 540 \ ], 'Xtest.c') 541 542 let lines =<< trim [SCRIPT] 543 set tags=Xtags 544 [SCRIPT] 545 call writefile(lines, 'XTest_tselect') 546 let buf = RunVimInTerminal('-S XTest_tselect', {'rows': 10, 'cols': 50}) 547 548 call TermWait(buf, 50) 549 call term_sendkeys(buf, ":tselect main\<CR>2\<CR>") 550 call VerifyScreenDump(buf, 'Test_tselect_1', {}) 551 552 call StopVimInTerminal(buf) 553 call delete('Xtags') 554 call delete('Xtest.c') 555 call delete('XTest_tselect') 556endfunc 557 558func Test_tagline() 559 call writefile([ 560 \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:1 language:Python class:Foo', 561 \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:3 language:Python class:Bar', 562 \], 'Xtags') 563 call writefile([ 564 \ ' def provision(self, **kwargs):', 565 \ ' pass', 566 \ ' def provision(self, **kwargs):', 567 \ ' pass', 568 \], 'Xtest.py') 569 570 set tags=Xtags 571 572 1tag provision 573 call assert_equal(line('.'), 1) 574 2tag provision 575 call assert_equal(line('.'), 3) 576 577 call delete('Xtags') 578 call delete('Xtest.py') 579 set tags& 580endfunc 581 582" Test for expanding environment variable in a tag file name 583func Test_tag_envvar() 584 call writefile(["Func1\t$FOO\t/^Func1/"], 'Xtags') 585 set tags=Xtags 586 587 let $FOO='TagTestEnv' 588 589 let caught_exception = v:false 590 try 591 tag Func1 592 catch /E429:/ 593 call assert_match('E429:.*"TagTestEnv".*', v:exception) 594 let caught_exception = v:true 595 endtry 596 call assert_true(caught_exception) 597 598 set tags& 599 call delete('Xtags') 600 unlet $FOO 601endfunc 602 603" Test for :ptag 604func Test_tag_preview() 605 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 606 \ "second\tXfile1\t2", 607 \ "third\tXfile1\t3",], 608 \ 'Xtags') 609 set tags=Xtags 610 call writefile(['first', 'second', 'third'], 'Xfile1') 611 612 enew | only 613 ptag third 614 call assert_equal(2, winnr()) 615 call assert_equal(2, winnr('$')) 616 call assert_equal(1, getwinvar(1, '&previewwindow')) 617 call assert_equal(0, getwinvar(2, '&previewwindow')) 618 wincmd P 619 call assert_equal(3, line('.')) 620 621 " jump to the tag again 622 wincmd w 623 ptag third 624 wincmd P 625 call assert_equal(3, line('.')) 626 627 " jump to the newer tag 628 wincmd w 629 ptag 630 wincmd P 631 call assert_equal(3, line('.')) 632 633 " close the preview window 634 pclose 635 call assert_equal(1, winnr('$')) 636 637 call delete('Xfile1') 638 call delete('Xtags') 639 set tags& 640endfunc 641 642" Tests for guessing the tag location 643func Test_tag_guess() 644 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 645 \ "func1\tXfoo\t/^int func1(int x)/", 646 \ "func2\tXfoo\t/^int func2(int y)/", 647 \ "func3\tXfoo\t/^func3/", 648 \ "func4\tXfoo\t/^func4/"], 649 \ 'Xtags') 650 set tags=Xtags 651 let code =<< trim [CODE] 652 653 int FUNC1 (int x) { } 654 int 655 func2 (int y) { } 656 int * func3 () { } 657 658 [CODE] 659 call writefile(code, 'Xfoo') 660 661 let v:statusmsg = '' 662 ta func1 663 call assert_match('E435:', v:statusmsg) 664 call assert_equal(2, line('.')) 665 let v:statusmsg = '' 666 ta func2 667 call assert_match('E435:', v:statusmsg) 668 call assert_equal(4, line('.')) 669 let v:statusmsg = '' 670 ta func3 671 call assert_match('E435:', v:statusmsg) 672 call assert_equal(5, line('.')) 673 call assert_fails('ta func4', 'E434:') 674 675 call delete('Xtags') 676 call delete('Xfoo') 677 set tags& 678endfunc 679 680" Test for an unsorted tags file 681func Test_tag_sort() 682 call writefile([ 683 \ "first\tXfoo\t1", 684 \ "ten\tXfoo\t3", 685 \ "six\tXfoo\t2"], 686 \ 'Xtags') 687 set tags=Xtags 688 let code =<< trim [CODE] 689 int first() {} 690 int six() {} 691 int ten() {} 692 [CODE] 693 call writefile(code, 'Xfoo') 694 695 call assert_fails('tag first', 'E432:') 696 697 call delete('Xtags') 698 call delete('Xfoo') 699 set tags& 700 %bwipe 701endfunc 702 703" Test for an unsorted tags file 704func Test_tag_fold() 705 call writefile([ 706 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 707 \ "!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/", 708 \ "first\tXfoo\t1", 709 \ "second\tXfoo\t2", 710 \ "third\tXfoo\t3"], 711 \ 'Xtags') 712 set tags=Xtags 713 let code =<< trim [CODE] 714 int first() {} 715 int second() {} 716 int third() {} 717 [CODE] 718 call writefile(code, 'Xfoo') 719 720 enew 721 tag second 722 call assert_equal('Xfoo', bufname('')) 723 call assert_equal(2, line('.')) 724 725 call delete('Xtags') 726 call delete('Xfoo') 727 set tags& 728 %bwipe 729endfunc 730 731" Test for the :ltag command 732func Test_ltag() 733 call writefile([ 734 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 735 \ "first\tXfoo\t1", 736 \ "second\tXfoo\t/^int second() {}$/", 737 \ "third\tXfoo\t3"], 738 \ 'Xtags') 739 set tags=Xtags 740 let code =<< trim [CODE] 741 int first() {} 742 int second() {} 743 int third() {} 744 [CODE] 745 call writefile(code, 'Xfoo') 746 747 enew 748 call setloclist(0, [], 'f') 749 ltag third 750 call assert_equal('Xfoo', bufname('')) 751 call assert_equal(3, line('.')) 752 call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0, 753 \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 754 \ 'module': '', 'text': 'third'}], getloclist(0)) 755 756 ltag second 757 call assert_equal(2, line('.')) 758 call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0, 759 \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0, 760 \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0)) 761 762 call delete('Xtags') 763 call delete('Xfoo') 764 set tags& 765 %bwipe 766endfunc 767 768" Test for setting the last search pattern to the tag search pattern 769" when cpoptions has 't' 770func Test_tag_last_search_pat() 771 call writefile([ 772 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 773 \ "first\tXfoo\t/^int first() {}/", 774 \ "second\tXfoo\t/^int second() {}/", 775 \ "third\tXfoo\t/^int third() {}/"], 776 \ 'Xtags') 777 set tags=Xtags 778 let code =<< trim [CODE] 779 int first() {} 780 int second() {} 781 int third() {} 782 [CODE] 783 call writefile(code, 'Xfoo') 784 785 enew 786 let save_cpo = &cpo 787 set cpo+=t 788 let @/ = '' 789 tag second 790 call assert_equal('^int second() {}', @/) 791 let &cpo = save_cpo 792 793 call delete('Xtags') 794 call delete('Xfoo') 795 set tags& 796 %bwipe 797endfunc 798 799" Tag stack tests 800func Test_tag_stack() 801 let l = [] 802 for i in range(10, 31) 803 let l += ["var" .. i .. "\tXfoo\t/^int var" .. i .. ";$/"] 804 endfor 805 call writefile(l, 'Xtags') 806 set tags=Xtags 807 808 let l = [] 809 for i in range(10, 31) 810 let l += ["int var" .. i .. ";"] 811 endfor 812 call writefile(l, 'Xfoo') 813 814 " Jump to a tag when the tag stack is full. Oldest entry should be removed. 815 enew 816 for i in range(10, 30) 817 exe "tag var" .. i 818 endfor 819 let l = gettagstack() 820 call assert_equal(20, l.length) 821 call assert_equal('var11', l.items[0].tagname) 822 tag var31 823 let l = gettagstack() 824 call assert_equal('var12', l.items[0].tagname) 825 call assert_equal('var31', l.items[19].tagname) 826 827 " Use tnext with a single match 828 call assert_fails('tnext', 'E427:') 829 830 " Jump to newest entry from the top of the stack 831 call assert_fails('tag', 'E556:') 832 833 " Pop with zero count from the top of the stack 834 call assert_fails('0pop', 'E556:') 835 836 " Pop from an unsaved buffer 837 enew! 838 call append(1, "sample text") 839 call assert_fails('pop', 'E37:') 840 call assert_equal(21, gettagstack().curidx) 841 enew! 842 843 " Pop all the entries in the tag stack 844 call assert_fails('30pop', 'E555:') 845 846 " Pop with a count when already at the bottom of the stack 847 call assert_fails('exe "normal 4\<C-T>"', 'E555:') 848 call assert_equal(1, gettagstack().curidx) 849 850 " Jump to newest entry from the bottom of the stack with zero count 851 call assert_fails('0tag', 'E555:') 852 853 " Pop the tag stack when it is empty 854 call settagstack(1, {'items' : []}) 855 call assert_fails('pop', 'E73:') 856 857 call delete('Xtags') 858 call delete('Xfoo') 859 set tags& 860 %bwipe 861endfunc 862 863" Test for browsing multiple matching tags 864func Test_tag_multimatch() 865 call writefile([ 866 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 867 \ "first\tXfoo\t1", 868 \ "first\tXfoo\t2", 869 \ "first\tXfoo\t3"], 870 \ 'Xtags') 871 set tags=Xtags 872 let code =<< trim [CODE] 873 int first() {} 874 int first() {} 875 int first() {} 876 [CODE] 877 call writefile(code, 'Xfoo') 878 879 call settagstack(1, {'items' : []}) 880 tag first 881 tlast 882 call assert_equal(3, line('.')) 883 call assert_fails('tnext', 'E428:') 884 tfirst 885 call assert_equal(1, line('.')) 886 call assert_fails('tprev', 'E425:') 887 888 tlast 889 call feedkeys("5\<CR>", 't') 890 tselect first 891 call assert_equal(2, gettagstack().curidx) 892 893 set ignorecase 894 tag FIRST 895 tnext 896 call assert_equal(2, line('.')) 897 tlast 898 tprev 899 call assert_equal(2, line('.')) 900 tNext 901 call assert_equal(1, line('.')) 902 set ignorecase& 903 904 call delete('Xtags') 905 call delete('Xfoo') 906 set tags& 907 %bwipe 908endfunc 909 910" Test for previewing multiple matching tags 911func Test_preview_tag_multimatch() 912 call writefile([ 913 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 914 \ "first\tXfoo\t1", 915 \ "first\tXfoo\t2", 916 \ "first\tXfoo\t3"], 917 \ 'Xtags') 918 set tags=Xtags 919 let code =<< trim [CODE] 920 int first() {} 921 int first() {} 922 int first() {} 923 [CODE] 924 call writefile(code, 'Xfoo') 925 926 enew | only 927 ptag first 928 ptlast 929 wincmd P 930 call assert_equal(3, line('.')) 931 wincmd w 932 call assert_fails('ptnext', 'E428:') 933 ptprev 934 wincmd P 935 call assert_equal(2, line('.')) 936 wincmd w 937 ptfirst 938 wincmd P 939 call assert_equal(1, line('.')) 940 wincmd w 941 call assert_fails('ptprev', 'E425:') 942 ptnext 943 wincmd P 944 call assert_equal(2, line('.')) 945 wincmd w 946 ptlast 947 call feedkeys("5\<CR>", 't') 948 ptselect first 949 wincmd P 950 call assert_equal(3, line('.')) 951 952 pclose 953 954 call delete('Xtags') 955 call delete('Xfoo') 956 set tags& 957 %bwipe 958endfunc 959 960" Test for jumping to multiple matching tags across multiple :tags commands 961func Test_tnext_multimatch() 962 call writefile([ 963 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 964 \ "first\tXfoo1\t1", 965 \ "first\tXfoo2\t1", 966 \ "first\tXfoo3\t1"], 967 \ 'Xtags') 968 set tags=Xtags 969 let code =<< trim [CODE] 970 int first() {} 971 [CODE] 972 call writefile(code, 'Xfoo1') 973 call writefile(code, 'Xfoo2') 974 call writefile(code, 'Xfoo3') 975 976 tag first 977 tag first 978 pop 979 tnext 980 tnext 981 call assert_fails('tnext', 'E428:') 982 983 call delete('Xtags') 984 call delete('Xfoo1') 985 call delete('Xfoo2') 986 call delete('Xfoo3') 987 set tags& 988 %bwipe 989endfunc 990 991" Test for jumping to multiple matching tags in non-existing files 992func Test_multimatch_non_existing_files() 993 call writefile([ 994 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 995 \ "first\tXfoo1\t1", 996 \ "first\tXfoo2\t1", 997 \ "first\tXfoo3\t1"], 998 \ 'Xtags') 999 set tags=Xtags 1000 1001 call settagstack(1, {'items' : []}) 1002 call assert_fails('tag first', 'E429:') 1003 call assert_equal(3, gettagstack().items[0].matchnr) 1004 1005 call delete('Xtags') 1006 set tags& 1007 %bwipe 1008endfunc 1009 1010func Test_tselect_listing() 1011 call writefile([ 1012 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 1013 \ "first\tXfoo\t1" .. ';"' .. "\tv\ttyperef:typename:int\tfile:", 1014 \ "first\tXfoo\t2" .. ';"' .. "\tv\ttyperef:typename:char\tfile:"], 1015 \ 'Xtags') 1016 set tags=Xtags 1017 1018 let code =<< trim [CODE] 1019 static int first; 1020 static char first; 1021 [CODE] 1022 call writefile(code, 'Xfoo') 1023 1024 call feedkeys("\<CR>", "t") 1025 let l = split(execute("tselect first"), "\n") 1026 let expected =<< [DATA] 1027 # pri kind tag file 1028 1 FS v first Xfoo 1029 typeref:typename:int 1030 1 1031 2 FS v first Xfoo 1032 typeref:typename:char 1033 2 1034Type number and <Enter> (empty cancels): 1035[DATA] 1036 call assert_equal(expected, l) 1037 1038 call delete('Xtags') 1039 call delete('Xfoo') 1040 set tags& 1041 %bwipe 1042endfunc 1043 1044" Test for :isearch, :ilist, :ijump and :isplit commands 1045" Test for [i, ]i, [I, ]I, [ CTRL-I, ] CTRL-I and CTRL-W i commands 1046func Test_inc_search() 1047 new 1048 call setline(1, ['1:foo', '2:foo', 'foo', '3:foo', '4:foo']) 1049 call cursor(3, 1) 1050 1051 " Test for [i and ]i 1052 call assert_equal('1:foo', execute('normal [i')) 1053 call assert_equal('2:foo', execute('normal 2[i')) 1054 call assert_fails('normal 3[i', 'E387:') 1055 call assert_equal('3:foo', execute('normal ]i')) 1056 call assert_equal('4:foo', execute('normal 2]i')) 1057 call assert_fails('normal 3]i', 'E389:') 1058 1059 " Test for :isearch 1060 call assert_equal('1:foo', execute('isearch foo')) 1061 call assert_equal('3:foo', execute('isearch 4 /foo/')) 1062 call assert_fails('isearch 3 foo', 'E387:') 1063 call assert_equal('3:foo', execute('+1,$isearch foo')) 1064 call assert_fails('1,.-1isearch 3 foo', 'E389:') 1065 call assert_fails('isearch bar', 'E389:') 1066 call assert_fails('isearch /foo/3', 'E488:') 1067 1068 " Test for [I and ]I 1069 call assert_equal([ 1070 \ ' 1: 1 1:foo', 1071 \ ' 2: 2 2:foo', 1072 \ ' 3: 3 foo', 1073 \ ' 4: 4 3:foo', 1074 \ ' 5: 5 4:foo'], split(execute('normal [I'), "\n")) 1075 call assert_equal([ 1076 \ ' 1: 4 3:foo', 1077 \ ' 2: 5 4:foo'], split(execute('normal ]I'), "\n")) 1078 1079 " Test for :ilist 1080 call assert_equal([ 1081 \ ' 1: 1 1:foo', 1082 \ ' 2: 2 2:foo', 1083 \ ' 3: 3 foo', 1084 \ ' 4: 4 3:foo', 1085 \ ' 5: 5 4:foo'], split(execute('ilist foo'), "\n")) 1086 call assert_equal([ 1087 \ ' 1: 4 3:foo', 1088 \ ' 2: 5 4:foo'], split(execute('+1,$ilist /foo/'), "\n")) 1089 call assert_fails('ilist bar', 'E389:') 1090 1091 " Test for [ CTRL-I and ] CTRL-I 1092 exe "normal [\t" 1093 call assert_equal([1, 3], [line('.'), col('.')]) 1094 exe "normal 2j4[\t" 1095 call assert_equal([4, 3], [line('.'), col('.')]) 1096 call assert_fails("normal k3[\t", 'E387:') 1097 call assert_fails("normal 6[\t", 'E389:') 1098 exe "normal ]\t" 1099 call assert_equal([4, 3], [line('.'), col('.')]) 1100 exe "normal k2]\t" 1101 call assert_equal([5, 3], [line('.'), col('.')]) 1102 call assert_fails("normal 2k3]\t", 'E389:') 1103 1104 " Test for :ijump 1105 call cursor(3, 1) 1106 ijump foo 1107 call assert_equal([1, 3], [line('.'), col('.')]) 1108 call cursor(3, 1) 1109 ijump 4 /foo/ 1110 call assert_equal([4, 3], [line('.'), col('.')]) 1111 call cursor(3, 1) 1112 call assert_fails('ijump 3 foo', 'E387:') 1113 +,$ijump 2 foo 1114 call assert_equal([5, 3], [line('.'), col('.')]) 1115 call assert_fails('ijump bar', 'E389:') 1116 1117 " Test for CTRL-W i 1118 call cursor(3, 1) 1119 wincmd i 1120 call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')]) 1121 close 1122 5wincmd i 1123 call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')]) 1124 close 1125 call assert_fails('3wincmd i', 'E387:') 1126 call assert_fails('6wincmd i', 'E389:') 1127 1128 " Test for :isplit 1129 isplit foo 1130 call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')]) 1131 close 1132 isplit 5 /foo/ 1133 call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')]) 1134 close 1135 call assert_fails('isplit 3 foo', 'E387:') 1136 call assert_fails('isplit 6 foo', 'E389:') 1137 call assert_fails('isplit bar', 'E389:') 1138 1139 close! 1140endfunc 1141 1142" Test for :dsearch, :dlist, :djump and :dsplit commands 1143" Test for [d, ]d, [D, ]D, [ CTRL-D, ] CTRL-D and CTRL-W d commands 1144func Test_macro_search() 1145 new 1146 call setline(1, ['#define FOO 1', '#define FOO 2', '#define FOO 3', 1147 \ '#define FOO 4', '#define FOO 5']) 1148 call cursor(3, 9) 1149 1150 " Test for [d and ]d 1151 call assert_equal('#define FOO 1', execute('normal [d')) 1152 call assert_equal('#define FOO 2', execute('normal 2[d')) 1153 call assert_fails('normal 3[d', 'E387:') 1154 call assert_equal('#define FOO 4', execute('normal ]d')) 1155 call assert_equal('#define FOO 5', execute('normal 2]d')) 1156 call assert_fails('normal 3]d', 'E388:') 1157 1158 " Test for :dsearch 1159 call assert_equal('#define FOO 1', execute('dsearch FOO')) 1160 call assert_equal('#define FOO 5', execute('dsearch 5 /FOO/')) 1161 call assert_fails('dsearch 3 FOO', 'E387:') 1162 call assert_equal('#define FOO 4', execute('+1,$dsearch FOO')) 1163 call assert_fails('1,.-1dsearch 3 FOO', 'E388:') 1164 call assert_fails('dsearch BAR', 'E388:') 1165 1166 " Test for [D and ]D 1167 call assert_equal([ 1168 \ ' 1: 1 #define FOO 1', 1169 \ ' 2: 2 #define FOO 2', 1170 \ ' 3: 3 #define FOO 3', 1171 \ ' 4: 4 #define FOO 4', 1172 \ ' 5: 5 #define FOO 5'], split(execute('normal [D'), "\n")) 1173 call assert_equal([ 1174 \ ' 1: 4 #define FOO 4', 1175 \ ' 2: 5 #define FOO 5'], split(execute('normal ]D'), "\n")) 1176 1177 " Test for :dlist 1178 call assert_equal([ 1179 \ ' 1: 1 #define FOO 1', 1180 \ ' 2: 2 #define FOO 2', 1181 \ ' 3: 3 #define FOO 3', 1182 \ ' 4: 4 #define FOO 4', 1183 \ ' 5: 5 #define FOO 5'], split(execute('dlist FOO'), "\n")) 1184 call assert_equal([ 1185 \ ' 1: 4 #define FOO 4', 1186 \ ' 2: 5 #define FOO 5'], split(execute('+1,$dlist /FOO/'), "\n")) 1187 call assert_fails('dlist BAR', 'E388:') 1188 1189 " Test for [ CTRL-D and ] CTRL-D 1190 exe "normal [\<C-D>" 1191 call assert_equal([1, 9], [line('.'), col('.')]) 1192 exe "normal 2j4[\<C-D>" 1193 call assert_equal([4, 9], [line('.'), col('.')]) 1194 call assert_fails("normal k3[\<C-D>", 'E387:') 1195 call assert_fails("normal 6[\<C-D>", 'E388:') 1196 exe "normal ]\<C-D>" 1197 call assert_equal([4, 9], [line('.'), col('.')]) 1198 exe "normal k2]\<C-D>" 1199 call assert_equal([5, 9], [line('.'), col('.')]) 1200 call assert_fails("normal 2k3]\<C-D>", 'E388:') 1201 1202 " Test for :djump 1203 call cursor(3, 9) 1204 djump FOO 1205 call assert_equal([1, 9], [line('.'), col('.')]) 1206 call cursor(3, 9) 1207 djump 4 /FOO/ 1208 call assert_equal([4, 9], [line('.'), col('.')]) 1209 call cursor(3, 9) 1210 call assert_fails('djump 3 FOO', 'E387:') 1211 +,$djump 2 FOO 1212 call assert_equal([5, 9], [line('.'), col('.')]) 1213 call assert_fails('djump BAR', 'E388:') 1214 1215 " Test for CTRL-W d 1216 call cursor(3, 9) 1217 wincmd d 1218 call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')]) 1219 close 1220 5wincmd d 1221 call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')]) 1222 close 1223 call assert_fails('3wincmd d', 'E387:') 1224 call assert_fails('6wincmd d', 'E388:') 1225 1226 " Test for :dsplit 1227 dsplit FOO 1228 call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')]) 1229 close 1230 dsplit 5 /FOO/ 1231 call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')]) 1232 close 1233 call assert_fails('dsplit 3 FOO', 'E387:') 1234 call assert_fails('dsplit 6 FOO', 'E388:') 1235 call assert_fails('dsplit BAR', 'E388:') 1236 1237 close! 1238endfunc 1239 1240" Test for [*, [/, ]* and ]/ 1241func Test_comment_search() 1242 new 1243 call setline(1, ['', '/*', ' *', ' *', ' */']) 1244 normal! 4gg[/ 1245 call assert_equal([2, 1], [line('.'), col('.')]) 1246 normal! 3gg[* 1247 call assert_equal([2, 1], [line('.'), col('.')]) 1248 normal! 3gg]/ 1249 call assert_equal([5, 3], [line('.'), col('.')]) 1250 normal! 3gg]* 1251 call assert_equal([5, 3], [line('.'), col('.')]) 1252 %d 1253 call setline(1, ['', '/*', ' *', ' *']) 1254 call assert_beeps('normal! 3gg]/') 1255 %d 1256 call setline(1, ['', ' *', ' *', ' */']) 1257 call assert_beeps('normal! 4gg[/') 1258 %d 1259 call setline(1, ' /* comment */') 1260 normal! 15|[/ 1261 call assert_equal(9, col('.')) 1262 normal! 15|]/ 1263 call assert_equal(21, col('.')) 1264 call setline(1, ' comment */') 1265 call assert_beeps('normal! 15|[/') 1266 call setline(1, ' /* comment') 1267 call assert_beeps('normal! 15|]/') 1268 close! 1269endfunc 1270 1271" vim: shiftwidth=2 sts=2 expandtab 1272