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 289 set tags=Xtags 290 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 291 \ "one\tXfile1\t1", 292 \ "three\tXfile3\t3", 293 \ "two\tXfile2\t2"], 294 \ 'Xtags') 295 296 let stk = [] 297 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'one', 298 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 299 tag one 300 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'two', 301 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 302 tag two 303 call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'three', 304 \ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1}) 305 tag three 306 call assert_equal(3, gettagstack(1).length) 307 call assert_equal(stk, gettagstack(1).items) 308 " Check for default - current window 309 call assert_equal(3, gettagstack().length) 310 call assert_equal(stk, gettagstack().items) 311 312 " Try to set current index to invalid values 313 call settagstack(1, {'curidx' : -1}) 314 call assert_equal(1, gettagstack().curidx) 315 eval {'curidx' : 50}->settagstack(1) 316 call assert_equal(4, gettagstack().curidx) 317 318 " Try pushing invalid items onto the stack 319 call settagstack(1, {'items' : []}) 320 call settagstack(1, {'items' : ["plate"]}, 'a') 321 call assert_equal(0, gettagstack().length) 322 call assert_equal([], gettagstack().items) 323 call settagstack(1, {'items' : [{"tagname" : "abc"}]}, 'a') 324 call assert_equal(0, gettagstack().length) 325 call assert_equal([], gettagstack().items) 326 call settagstack(1, {'items' : [{"from" : 100}]}, 'a') 327 call assert_equal(0, gettagstack().length) 328 call assert_equal([], gettagstack().items) 329 call settagstack(1, {'items' : [{"from" : [2, 1, 0, 0]}]}, 'a') 330 call assert_equal(0, gettagstack().length) 331 call assert_equal([], gettagstack().items) 332 333 " Push one item at a time to the stack 334 call settagstack(1, {'items' : []}) 335 call settagstack(1, {'items' : [stk[0]]}, 'a') 336 call settagstack(1, {'items' : [stk[1]]}, 'a') 337 call settagstack(1, {'items' : [stk[2]]}, 'a') 338 call settagstack(1, {'curidx' : 4}) 339 call assert_equal({'length' : 3, 'curidx' : 4, 'items' : stk}, 340 \ gettagstack(1)) 341 342 " Try pushing items onto a full stack 343 for i in range(7) 344 call settagstack(1, {'items' : stk}, 'a') 345 endfor 346 call assert_equal(20, gettagstack().length) 347 call settagstack(1, 348 \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a') 349 call assert_equal('abc', gettagstack().items[19].tagname) 350 351 " truncate the tag stack 352 call settagstack(1, 353 \ {'curidx' : 9, 354 \ 'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') 355 let t = gettagstack() 356 call assert_equal(9, t.length) 357 call assert_equal(10, t.curidx) 358 359 " truncate the tag stack without pushing any new items 360 call settagstack(1, {'curidx' : 5}, 't') 361 let t = gettagstack() 362 call assert_equal(4, t.length) 363 call assert_equal(5, t.curidx) 364 365 " truncate an empty tag stack and push new items 366 call settagstack(1, {'items' : []}) 367 call settagstack(1, 368 \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') 369 let t = gettagstack() 370 call assert_equal(1, t.length) 371 call assert_equal(2, t.curidx) 372 373 " Tag with multiple matches 374 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 375 \ "two\tXfile1\t1", 376 \ "two\tXfile2\t3", 377 \ "two\tXfile3\t2"], 378 \ 'Xtags') 379 call settagstack(1, {'items' : []}) 380 tag two 381 tnext 382 tnext 383 call assert_equal(1, gettagstack().length) 384 call assert_equal(3, gettagstack().items[0].matchnr) 385 386 " Memory allocation failures 387 call test_alloc_fail(GetAllocId('tagstack_items'), 0, 0) 388 call assert_fails('call gettagstack()', 'E342:') 389 call test_alloc_fail(GetAllocId('tagstack_from'), 0, 0) 390 call assert_fails('call gettagstack()', 'E342:') 391 call test_alloc_fail(GetAllocId('tagstack_details'), 0, 0) 392 call assert_fails('call gettagstack()', 'E342:') 393 394 call settagstack(1, {'items' : []}) 395 call delete('Xfile1') 396 call delete('Xfile2') 397 call delete('Xfile3') 398 call delete('Xtags') 399 set tags& 400endfunc 401 402func Test_tag_with_count() 403 call writefile([ 404 \ 'test Xtest.h /^void test();$/;" p typeref:typename:void signature:()', 405 \ ], 'Xtags') 406 call writefile([ 407 \ 'main Xtest.c /^int main()$/;" f typeref:typename:int signature:()', 408 \ 'test Xtest.c /^void test()$/;" f typeref:typename:void signature:()', 409 \ ], 'Ytags') 410 cal writefile([ 411 \ 'int main()', 412 \ 'void test()', 413 \ ], 'Xtest.c') 414 cal writefile([ 415 \ 'void test();', 416 \ ], 'Xtest.h') 417 set tags=Xtags,Ytags 418 419 new Xtest.c 420 let tl = taglist('test', 'Xtest.c') 421 call assert_equal(tl[0].filename, 'Xtest.c') 422 call assert_equal(tl[1].filename, 'Xtest.h') 423 424 tag test 425 call assert_equal(bufname('%'), 'Xtest.c') 426 1tag test 427 call assert_equal(bufname('%'), 'Xtest.c') 428 2tag test 429 call assert_equal(bufname('%'), 'Xtest.h') 430 431 set tags& 432 call delete('Xtags') 433 call delete('Ytags') 434 bwipe Xtest.h 435 bwipe Xtest.c 436 call delete('Xtest.h') 437 call delete('Xtest.c') 438endfunc 439 440func Test_tagnr_recall() 441 call writefile([ 442 \ 'test Xtest.h /^void test();$/;" p', 443 \ 'main Xtest.c /^int main()$/;" f', 444 \ 'test Xtest.c /^void test()$/;" f', 445 \ ], 'Xtags') 446 cal writefile([ 447 \ 'int main()', 448 \ 'void test()', 449 \ ], 'Xtest.c') 450 cal writefile([ 451 \ 'void test();', 452 \ ], 'Xtest.h') 453 set tags=Xtags 454 455 new Xtest.c 456 let tl = taglist('test', 'Xtest.c') 457 call assert_equal(tl[0].filename, 'Xtest.c') 458 call assert_equal(tl[1].filename, 'Xtest.h') 459 460 2tag test 461 call assert_equal(bufname('%'), 'Xtest.h') 462 pop 463 call assert_equal(bufname('%'), 'Xtest.c') 464 tag 465 call assert_equal(bufname('%'), 'Xtest.h') 466 467 set tags& 468 call delete('Xtags') 469 bwipe Xtest.h 470 bwipe Xtest.c 471 call delete('Xtest.h') 472 call delete('Xtest.c') 473endfunc 474 475func Test_tag_line_toolong() 476 call writefile([ 477 \ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' 478 \ ], 'Xtags') 479 set tags=Xtags 480 let old_vbs = &verbose 481 set verbose=5 482 " ":tjump" should give "tag not found" not "Format error in tags file" 483 call assert_fails('tj /foo', 'E426') 484 try 485 tj /foo 486 catch /^Vim\%((\a\+)\)\=:E431/ 487 call assert_report(v:exception) 488 catch /.*/ 489 endtry 490 call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) 491 492 call writefile([ 493 \ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' 494 \ ], 'Xtags') 495 call assert_fails('tj /foo', 'E426') 496 try 497 tj /foo 498 catch /^Vim\%((\a\+)\)\=:E431/ 499 call assert_report(v:exception) 500 catch /.*/ 501 endtry 502 call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) 503 504 " binary search works in file with long line 505 call writefile([ 506 \ 'asdfasfd nowhere 16', 507 \ 'foobar Xsomewhere 3; " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567', 508 \ 'zasdfasfd nowhere 16', 509 \ ], 'Xtags') 510 call writefile([ 511 \ 'one', 512 \ 'two', 513 \ 'trhee', 514 \ 'four', 515 \ ], 'Xsomewhere') 516 tag foobar 517 call assert_equal('Xsomewhere', expand('%')) 518 call assert_equal(3, getcurpos()[1]) 519 520 call delete('Xtags') 521 call delete('Xsomewhere') 522 set tags& 523 let &verbose = old_vbs 524endfunc 525 526" Check that using :tselect does not run into the hit-enter prompt. 527" Requires a terminal to trigger that prompt. 528func Test_tselect() 529 CheckScreendump 530 531 call writefile([ 532 \ 'main Xtest.h /^void test();$/;" f', 533 \ 'main Xtest.c /^int main()$/;" f', 534 \ 'main Xtest.x /^void test()$/;" f', 535 \ ], 'Xtags') 536 cal writefile([ 537 \ 'int main()', 538 \ 'void test()', 539 \ ], 'Xtest.c') 540 541 let lines =<< trim [SCRIPT] 542 set tags=Xtags 543 [SCRIPT] 544 call writefile(lines, 'XTest_tselect') 545 let buf = RunVimInTerminal('-S XTest_tselect', {'rows': 10, 'cols': 50}) 546 547 call term_wait(buf, 100) 548 call term_sendkeys(buf, ":tselect main\<CR>2\<CR>") 549 call VerifyScreenDump(buf, 'Test_tselect_1', {}) 550 551 call StopVimInTerminal(buf) 552 call delete('Xtags') 553 call delete('Xtest.c') 554 call delete('XTest_tselect') 555endfunc 556 557func Test_tagline() 558 call writefile([ 559 \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:1 language:Python class:Foo', 560 \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:3 language:Python class:Bar', 561 \], 'Xtags') 562 call writefile([ 563 \ ' def provision(self, **kwargs):', 564 \ ' pass', 565 \ ' def provision(self, **kwargs):', 566 \ ' pass', 567 \], 'Xtest.py') 568 569 set tags=Xtags 570 571 1tag provision 572 call assert_equal(line('.'), 1) 573 2tag provision 574 call assert_equal(line('.'), 3) 575 576 call delete('Xtags') 577 call delete('Xtest.py') 578 set tags& 579endfunc 580 581" Test for expanding environment variable in a tag file name 582func Test_tag_envvar() 583 call writefile(["Func1\t$FOO\t/^Func1/"], 'Xtags') 584 set tags=Xtags 585 586 let $FOO='TagTestEnv' 587 588 let caught_exception = v:false 589 try 590 tag Func1 591 catch /E429:/ 592 call assert_match('E429:.*"TagTestEnv".*', v:exception) 593 let caught_exception = v:true 594 endtry 595 call assert_true(caught_exception) 596 597 set tags& 598 call delete('Xtags') 599 unlet $FOO 600endfunc 601 602" Test for :ptag 603func Test_tag_preview() 604 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 605 \ "second\tXfile1\t2", 606 \ "third\tXfile1\t3",], 607 \ 'Xtags') 608 set tags=Xtags 609 call writefile(['first', 'second', 'third'], 'Xfile1') 610 611 enew | only 612 ptag third 613 call assert_equal(2, winnr()) 614 call assert_equal(2, winnr('$')) 615 call assert_equal(1, getwinvar(1, '&previewwindow')) 616 call assert_equal(0, getwinvar(2, '&previewwindow')) 617 wincmd P 618 call assert_equal(3, line('.')) 619 620 " jump to the tag again 621 wincmd w 622 ptag third 623 wincmd P 624 call assert_equal(3, line('.')) 625 626 " jump to the newer tag 627 wincmd w 628 ptag 629 wincmd P 630 call assert_equal(3, line('.')) 631 632 " close the preview window 633 pclose 634 call assert_equal(1, winnr('$')) 635 636 call delete('Xfile1') 637 call delete('Xtags') 638 set tags& 639endfunc 640 641" Tests for guessing the tag location 642func Test_tag_guess() 643 call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", 644 \ "func1\tXfoo\t/^int func1(int x)/", 645 \ "func2\tXfoo\t/^int func2(int y)/", 646 \ "func3\tXfoo\t/^func3/", 647 \ "func4\tXfoo\t/^func4/"], 648 \ 'Xtags') 649 set tags=Xtags 650 let code =<< trim [CODE] 651 652 int FUNC1 (int x) { } 653 int 654 func2 (int y) { } 655 int * func3 () { } 656 657 [CODE] 658 call writefile(code, 'Xfoo') 659 660 let v:statusmsg = '' 661 ta func1 662 call assert_match('E435:', v:statusmsg) 663 call assert_equal(2, line('.')) 664 let v:statusmsg = '' 665 ta func2 666 call assert_match('E435:', v:statusmsg) 667 call assert_equal(4, line('.')) 668 let v:statusmsg = '' 669 ta func3 670 call assert_match('E435:', v:statusmsg) 671 call assert_equal(5, line('.')) 672 call assert_fails('ta func4', 'E434:') 673 674 call delete('Xtags') 675 call delete('Xfoo') 676 set tags& 677endfunc 678 679" Test for an unsorted tags file 680func Test_tag_sort() 681 call writefile([ 682 \ "first\tXfoo\t1", 683 \ "ten\tXfoo\t3", 684 \ "six\tXfoo\t2"], 685 \ 'Xtags') 686 set tags=Xtags 687 let code =<< trim [CODE] 688 int first() {} 689 int six() {} 690 int ten() {} 691 [CODE] 692 call writefile(code, 'Xfoo') 693 694 call assert_fails('tag first', 'E432:') 695 696 call delete('Xtags') 697 call delete('Xfoo') 698 set tags& 699 %bwipe 700endfunc 701 702" Test for an unsorted tags file 703func Test_tag_fold() 704 call writefile([ 705 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 706 \ "!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/", 707 \ "first\tXfoo\t1", 708 \ "second\tXfoo\t2", 709 \ "third\tXfoo\t3"], 710 \ 'Xtags') 711 set tags=Xtags 712 let code =<< trim [CODE] 713 int first() {} 714 int second() {} 715 int third() {} 716 [CODE] 717 call writefile(code, 'Xfoo') 718 719 enew 720 tag second 721 call assert_equal('Xfoo', bufname('')) 722 call assert_equal(2, line('.')) 723 724 call delete('Xtags') 725 call delete('Xfoo') 726 set tags& 727 %bwipe 728endfunc 729 730" Test for the :ltag command 731func Test_ltag() 732 call writefile([ 733 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 734 \ "first\tXfoo\t1", 735 \ "second\tXfoo\t/^int second() {}$/", 736 \ "third\tXfoo\t3"], 737 \ 'Xtags') 738 set tags=Xtags 739 let code =<< trim [CODE] 740 int first() {} 741 int second() {} 742 int third() {} 743 [CODE] 744 call writefile(code, 'Xfoo') 745 746 enew 747 call setloclist(0, [], 'f') 748 ltag third 749 call assert_equal('Xfoo', bufname('')) 750 call assert_equal(3, line('.')) 751 call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0, 752 \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 753 \ 'module': '', 'text': 'third'}], getloclist(0)) 754 755 ltag second 756 call assert_equal(2, line('.')) 757 call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0, 758 \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0, 759 \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0)) 760 761 call delete('Xtags') 762 call delete('Xfoo') 763 set tags& 764 %bwipe 765endfunc 766 767" Test for setting the last search pattern to the tag search pattern 768" when cpoptions has 't' 769func Test_tag_last_search_pat() 770 call writefile([ 771 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 772 \ "first\tXfoo\t/^int first() {}/", 773 \ "second\tXfoo\t/^int second() {}/", 774 \ "third\tXfoo\t/^int third() {}/"], 775 \ 'Xtags') 776 set tags=Xtags 777 let code =<< trim [CODE] 778 int first() {} 779 int second() {} 780 int third() {} 781 [CODE] 782 call writefile(code, 'Xfoo') 783 784 enew 785 let save_cpo = &cpo 786 set cpo+=t 787 let @/ = '' 788 tag second 789 call assert_equal('^int second() {}', @/) 790 let &cpo = save_cpo 791 792 call delete('Xtags') 793 call delete('Xfoo') 794 set tags& 795 %bwipe 796endfunc 797 798" Tag stack tests 799func Test_tag_stack() 800 let l = [] 801 for i in range(10, 31) 802 let l += ["var" .. i .. "\tXfoo\t/^int var" .. i .. ";$/"] 803 endfor 804 call writefile(l, 'Xtags') 805 set tags=Xtags 806 807 let l = [] 808 for i in range(10, 31) 809 let l += ["int var" .. i .. ";"] 810 endfor 811 call writefile(l, 'Xfoo') 812 813 " Jump to a tag when the tag stack is full. Oldest entry should be removed. 814 enew 815 for i in range(10, 30) 816 exe "tag var" .. i 817 endfor 818 let l = gettagstack() 819 call assert_equal(20, l.length) 820 call assert_equal('var11', l.items[0].tagname) 821 tag var31 822 let l = gettagstack() 823 call assert_equal('var12', l.items[0].tagname) 824 call assert_equal('var31', l.items[19].tagname) 825 826 " Use tnext with a single match 827 call assert_fails('tnext', 'E427:') 828 829 " Jump to newest entry from the top of the stack 830 call assert_fails('tag', 'E556:') 831 832 " Pop with zero count from the top of the stack 833 call assert_fails('0pop', 'E556:') 834 835 " Pop from an unsaved buffer 836 enew! 837 call append(1, "sample text") 838 call assert_fails('pop', 'E37:') 839 call assert_equal(21, gettagstack().curidx) 840 enew! 841 842 " Pop all the entries in the tag stack 843 call assert_fails('30pop', 'E555:') 844 845 " Pop with a count when already at the bottom of the stack 846 call assert_fails('exe "normal 4\<C-T>"', 'E555:') 847 call assert_equal(1, gettagstack().curidx) 848 849 " Jump to newest entry from the bottom of the stack with zero count 850 call assert_fails('0tag', 'E555:') 851 852 " Pop the tag stack when it is empty 853 call settagstack(1, {'items' : []}) 854 call assert_fails('pop', 'E73:') 855 856 call delete('Xtags') 857 call delete('Xfoo') 858 set tags& 859 %bwipe 860endfunc 861 862" Test for browsing multiple matching tags 863func Test_tag_multimatch() 864 call writefile([ 865 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 866 \ "first\tXfoo\t1", 867 \ "first\tXfoo\t2", 868 \ "first\tXfoo\t3"], 869 \ 'Xtags') 870 set tags=Xtags 871 let code =<< trim [CODE] 872 int first() {} 873 int first() {} 874 int first() {} 875 [CODE] 876 call writefile(code, 'Xfoo') 877 878 call settagstack(1, {'items' : []}) 879 tag first 880 tlast 881 call assert_equal(3, line('.')) 882 call assert_fails('tnext', 'E428:') 883 tfirst 884 call assert_equal(1, line('.')) 885 call assert_fails('tprev', 'E425:') 886 887 tlast 888 call feedkeys("5\<CR>", 't') 889 tselect first 890 call assert_equal(2, gettagstack().curidx) 891 892 set ignorecase 893 tag FIRST 894 tnext 895 call assert_equal(2, line('.')) 896 set ignorecase& 897 898 call delete('Xtags') 899 call delete('Xfoo') 900 set tags& 901 %bwipe 902endfunc 903 904" Test for previewing multiple matching tags 905func Test_preview_tag_multimatch() 906 call writefile([ 907 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 908 \ "first\tXfoo\t1", 909 \ "first\tXfoo\t2", 910 \ "first\tXfoo\t3"], 911 \ 'Xtags') 912 set tags=Xtags 913 let code =<< trim [CODE] 914 int first() {} 915 int first() {} 916 int first() {} 917 [CODE] 918 call writefile(code, 'Xfoo') 919 920 enew | only 921 ptag first 922 ptlast 923 wincmd P 924 call assert_equal(3, line('.')) 925 wincmd w 926 call assert_fails('ptnext', 'E428:') 927 ptprev 928 wincmd P 929 call assert_equal(2, line('.')) 930 wincmd w 931 ptfirst 932 wincmd P 933 call assert_equal(1, line('.')) 934 wincmd w 935 call assert_fails('ptprev', 'E425:') 936 ptnext 937 wincmd P 938 call assert_equal(2, line('.')) 939 wincmd w 940 ptlast 941 call feedkeys("5\<CR>", 't') 942 ptselect first 943 wincmd P 944 call assert_equal(3, line('.')) 945 946 pclose 947 948 call delete('Xtags') 949 call delete('Xfoo') 950 set tags& 951 %bwipe 952endfunc 953 954" Test for jumping to multiple matching tags across multiple :tags commands 955func Test_tnext_multimatch() 956 call writefile([ 957 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 958 \ "first\tXfoo1\t1", 959 \ "first\tXfoo2\t1", 960 \ "first\tXfoo3\t1"], 961 \ 'Xtags') 962 set tags=Xtags 963 let code =<< trim [CODE] 964 int first() {} 965 [CODE] 966 call writefile(code, 'Xfoo1') 967 call writefile(code, 'Xfoo2') 968 call writefile(code, 'Xfoo3') 969 970 tag first 971 tag first 972 pop 973 tnext 974 tnext 975 call assert_fails('tnext', 'E428:') 976 977 call delete('Xtags') 978 call delete('Xfoo1') 979 call delete('Xfoo2') 980 call delete('Xfoo3') 981 set tags& 982 %bwipe 983endfunc 984 985" Test for jumping to multiple matching tags in non-existing files 986func Test_multimatch_non_existing_files() 987 call writefile([ 988 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 989 \ "first\tXfoo1\t1", 990 \ "first\tXfoo2\t1", 991 \ "first\tXfoo3\t1"], 992 \ 'Xtags') 993 set tags=Xtags 994 995 call settagstack(1, {'items' : []}) 996 call assert_fails('tag first', 'E429:') 997 call assert_equal(3, gettagstack().items[0].matchnr) 998 999 call delete('Xtags') 1000 set tags& 1001 %bwipe 1002endfunc 1003 1004func Test_tselect_listing() 1005 call writefile([ 1006 \ "!_TAG_FILE_ENCODING\tutf-8\t//", 1007 \ "first\tXfoo\t1" .. ';"' .. "\tv\ttyperef:typename:int\tfile:", 1008 \ "first\tXfoo\t2" .. ';"' .. "\tv\ttyperef:typename:char\tfile:"], 1009 \ 'Xtags') 1010 set tags=Xtags 1011 1012 let code =<< trim [CODE] 1013 static int first; 1014 static char first; 1015 [CODE] 1016 call writefile(code, 'Xfoo') 1017 1018 call feedkeys("\<CR>", "t") 1019 let l = split(execute("tselect first"), "\n") 1020 let expected =<< [DATA] 1021 # pri kind tag file 1022 1 FS v first Xfoo 1023 typeref:typename:int 1024 1 1025 2 FS v first Xfoo 1026 typeref:typename:char 1027 2 1028Type number and <Enter> (empty cancels): 1029[DATA] 1030 call assert_equal(expected, l) 1031 1032 call delete('Xtags') 1033 call delete('Xfoo') 1034 set tags& 1035 %bwipe 1036endfunc 1037 1038" vim: shiftwidth=2 sts=2 expandtab 1039