1" Test for the quickfix feature. 2 3source check.vim 4CheckFeature quickfix 5 6source screendump.vim 7 8set encoding=utf-8 9 10func s:setup_commands(cchar) 11 if a:cchar == 'c' 12 command! -nargs=* -bang Xlist <mods>clist<bang> <args> 13 command! -nargs=* Xgetexpr <mods>cgetexpr <args> 14 command! -nargs=* Xaddexpr <mods>caddexpr <args> 15 command! -nargs=* -count Xolder <mods><count>colder <args> 16 command! -nargs=* Xnewer <mods>cnewer <args> 17 command! -nargs=* Xopen <mods> copen <args> 18 command! -nargs=* Xwindow <mods>cwindow <args> 19 command! -nargs=* Xbottom <mods>cbottom <args> 20 command! -nargs=* Xclose <mods>cclose <args> 21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args> 22 command! -nargs=* Xgetfile <mods>cgetfile <args> 23 command! -nargs=* Xaddfile <mods>caddfile <args> 24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args> 25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args> 26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args> 27 command! -nargs=* Xrewind <mods>crewind <args> 28 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args> 29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args> 30 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args> 31 command! -nargs=* -bang Xlast <mods>clast<bang> <args> 32 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args> 33 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args> 34 command! -nargs=* Xexpr <mods>cexpr <args> 35 command! -count -nargs=* Xvimgrep <mods> <count>vimgrep <args> 36 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args> 37 command! -nargs=* Xgrep <mods> grep <args> 38 command! -nargs=* Xgrepadd <mods> grepadd <args> 39 command! -nargs=* Xhelpgrep helpgrep <args> 40 command! -nargs=0 -count Xcc <count>cc 41 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow 42 command! -count=1 -nargs=0 Xabove <mods><count>cabove 43 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore 44 command! -count=1 -nargs=0 Xafter <mods><count>cafter 45 let g:Xgetlist = function('getqflist') 46 let g:Xsetlist = function('setqflist') 47 call setqflist([], 'f') 48 else 49 command! -nargs=* -bang Xlist <mods>llist<bang> <args> 50 command! -nargs=* Xgetexpr <mods>lgetexpr <args> 51 command! -nargs=* Xaddexpr <mods>laddexpr <args> 52 command! -nargs=* -count Xolder <mods><count>lolder <args> 53 command! -nargs=* Xnewer <mods>lnewer <args> 54 command! -nargs=* Xopen <mods> lopen <args> 55 command! -nargs=* Xwindow <mods>lwindow <args> 56 command! -nargs=* Xbottom <mods>lbottom <args> 57 command! -nargs=* Xclose <mods>lclose <args> 58 command! -nargs=* -bang Xfile <mods>lfile<bang> <args> 59 command! -nargs=* Xgetfile <mods>lgetfile <args> 60 command! -nargs=* Xaddfile <mods>laddfile <args> 61 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args> 62 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args> 63 command! -nargs=* Xaddbuffer <mods>laddbuffer <args> 64 command! -nargs=* Xrewind <mods>lrewind <args> 65 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args> 66 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args> 67 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args> 68 command! -nargs=* -bang Xlast <mods>llast<bang> <args> 69 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args> 70 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args> 71 command! -nargs=* Xexpr <mods>lexpr <args> 72 command! -count -nargs=* Xvimgrep <mods> <count>lvimgrep <args> 73 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args> 74 command! -nargs=* Xgrep <mods> lgrep <args> 75 command! -nargs=* Xgrepadd <mods> lgrepadd <args> 76 command! -nargs=* Xhelpgrep lhelpgrep <args> 77 command! -nargs=0 -count Xcc <count>ll 78 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow 79 command! -count=1 -nargs=0 Xabove <mods><count>labove 80 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore 81 command! -count=1 -nargs=0 Xafter <mods><count>lafter 82 let g:Xgetlist = function('getloclist', [0]) 83 let g:Xsetlist = function('setloclist', [0]) 84 call setloclist(0, [], 'f') 85 endif 86endfunc 87 88" Tests for the :clist and :llist commands 89func XlistTests(cchar) 90 call s:setup_commands(a:cchar) 91 92 if a:cchar == 'l' 93 call assert_fails('llist', 'E776:') 94 endif 95 " With an empty list, command should return error 96 Xgetexpr [] 97 silent! Xlist 98 call assert_true(v:errmsg ==# 'E42: No Errors') 99 100 " Populate the list and then try 101 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1', 102 \ 'non-error 2', 'Xtestfile2:2:2:Line2', 103 \ 'non-error| 3', 'Xtestfile3:3:1:Line3'] 104 105 " List only valid entries 106 let l = split(execute('Xlist', ''), "\n") 107 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 108 \ ' 4 Xtestfile2:2 col 2: Line2', 109 \ ' 6 Xtestfile3:3 col 1: Line3'], l) 110 111 " List all the entries 112 let l = split(execute('Xlist!', ''), "\n") 113 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1', 114 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2', 115 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l) 116 117 " List a range of errors 118 let l = split(execute('Xlist 3,6', ''), "\n") 119 call assert_equal([' 4 Xtestfile2:2 col 2: Line2', 120 \ ' 6 Xtestfile3:3 col 1: Line3'], l) 121 122 let l = split(execute('Xlist! 3,4', ''), "\n") 123 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 124 125 let l = split(execute('Xlist -6,-4', ''), "\n") 126 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l) 127 128 let l = split(execute('Xlist! -5,-3', ''), "\n") 129 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 130 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 131 132 " Test for '+' 133 let l = split(execute('Xlist! +2', ''), "\n") 134 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 135 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 136 137 " Different types of errors 138 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11}, 139 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22}, 140 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33}, 141 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44}, 142 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}]) 143 let l = split(execute('Xlist', ""), "\n") 144 call assert_equal([' 1:10 col 5 warning 11: Warning', 145 \ ' 2:20 col 10 error 22: Error', 146 \ ' 3:30 col 15 info 33: Info', 147 \ ' 4:40 col 20 x 44: Other', 148 \ ' 5:50 col 25 55: one'], l) 149 150 " Test for module names, one needs to explicitly set `'valid':v:true` so 151 call g:Xsetlist([ 152 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true}, 153 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true}, 154 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}]) 155 let l = split(execute('Xlist', ""), "\n") 156 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning', 157 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning', 158 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l) 159 160 " For help entries in the quickfix list, only the filename without directory 161 " should be displayed 162 Xhelpgrep setqflist() 163 let l = split(execute('Xlist 1', ''), "\n") 164 call assert_match('^ 1 [^\\/]\{-}:', l[0]) 165 166 " Error cases 167 call assert_fails('Xlist abc', 'E488:') 168endfunc 169 170func Test_clist() 171 call XlistTests('c') 172 call XlistTests('l') 173endfunc 174 175" Tests for the :colder, :cnewer, :lolder and :lnewer commands 176" Note that this test assumes that a quickfix/location list is 177" already set by the caller. 178func XageTests(cchar) 179 call s:setup_commands(a:cchar) 180 181 if a:cchar == 'l' 182 " No location list for the current window 183 call assert_fails('lolder', 'E776:') 184 call assert_fails('lnewer', 'E776:') 185 endif 186 187 let list = [{'bufnr': bufnr('%'), 'lnum': 1}] 188 call g:Xsetlist(list) 189 190 " Jumping to a non existent list should return error 191 silent! Xolder 99 192 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack') 193 194 silent! Xnewer 99 195 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack') 196 197 " Add three quickfix/location lists 198 Xgetexpr ['Xtestfile1:1:3:Line1'] 199 Xgetexpr ['Xtestfile2:2:2:Line2'] 200 Xgetexpr ['Xtestfile3:3:1:Line3'] 201 202 " Go back two lists 203 Xolder 204 let l = g:Xgetlist() 205 call assert_equal('Line2', l[0].text) 206 207 " Go forward two lists 208 Xnewer 209 let l = g:Xgetlist() 210 call assert_equal('Line3', l[0].text) 211 212 " Test for the optional count argument 213 Xolder 2 214 let l = g:Xgetlist() 215 call assert_equal('Line1', l[0].text) 216 217 Xnewer 2 218 let l = g:Xgetlist() 219 call assert_equal('Line3', l[0].text) 220endfunc 221 222func Test_cage() 223 call XageTests('c') 224 call XageTests('l') 225endfunc 226 227" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen 228" commands 229func XwindowTests(cchar) 230 call s:setup_commands(a:cchar) 231 232 " Opening the location list window without any errors should fail 233 if a:cchar == 'l' 234 call assert_fails('lopen', 'E776:') 235 endif 236 237 " Create a list with no valid entries 238 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3'] 239 240 " Quickfix/Location window should not open with no valid errors 241 Xwindow 242 call assert_true(winnr('$') == 1) 243 244 " Create a list with valid entries 245 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2', 246 \ 'Xtestfile3:3:1:Line3'] 247 248 " Open the window 249 Xwindow 250 call assert_true(winnr('$') == 2 && winnr() == 2 && 251 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1') 252 redraw! 253 254 " Close the window 255 Xclose 256 call assert_true(winnr('$') == 1) 257 258 " Create a list with no valid entries 259 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3'] 260 261 " Open the window 262 Xopen 5 263 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1' 264 \ && winheight('.') == 5) 265 266 " Opening the window again, should move the cursor to that window 267 wincmd t 268 Xopen 7 269 call assert_true(winnr('$') == 2 && winnr() == 2 && 270 \ winheight('.') == 7 && 271 \ getline('.') ==# '|| non-error 1') 272 273 " :cnext in quickfix window should move to the next entry 274 Xnext 275 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx) 276 277 " Calling cwindow should close the quickfix window with no valid errors 278 Xwindow 279 call assert_true(winnr('$') == 1) 280 281 " Specifying the width should adjust the width for a vertically split 282 " quickfix window. 283 vert Xopen 284 call assert_equal(10, winwidth(0)) 285 vert Xopen 12 286 call assert_equal(12, winwidth(0)) 287 Xclose 288 289 " Horizontally or vertically splitting the quickfix window should create a 290 " normal window/buffer 291 Xopen 292 wincmd s 293 call assert_equal(0, getwininfo(win_getid())[0].quickfix) 294 call assert_equal(0, getwininfo(win_getid())[0].loclist) 295 call assert_notequal('quickfix', &buftype) 296 close 297 Xopen 298 wincmd v 299 call assert_equal(0, getwininfo(win_getid())[0].quickfix) 300 call assert_equal(0, getwininfo(win_getid())[0].loclist) 301 call assert_notequal('quickfix', &buftype) 302 close 303 Xopen 304 Xclose 305 306 if a:cchar == 'c' 307 " Opening the quickfix window in multiple tab pages should reuse the 308 " quickfix buffer 309 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2', 310 \ 'Xtestfile3:3:1:Line3'] 311 Xopen 312 let qfbufnum = bufnr('%') 313 tabnew 314 Xopen 315 call assert_equal(qfbufnum, bufnr('%')) 316 new | only | tabonly 317 endif 318endfunc 319 320func Test_cwindow() 321 call XwindowTests('c') 322 call XwindowTests('l') 323endfunc 324 325func Test_copenHeight() 326 copen 327 wincmd H 328 let height = winheight(0) 329 copen 10 330 call assert_equal(height, winheight(0)) 331 quit 332endfunc 333 334func Test_copenHeight_tabline() 335 set tabline=foo showtabline=2 336 copen 337 wincmd H 338 let height = winheight(0) 339 copen 10 340 call assert_equal(height, winheight(0)) 341 quit 342 set tabline& showtabline& 343endfunc 344 345 346" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile 347" commands. 348func XfileTests(cchar) 349 call s:setup_commands(a:cchar) 350 351 call writefile(['Xtestfile1:700:10:Line 700', 352 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1') 353 354 enew! 355 Xfile Xqftestfile1 356 let l = g:Xgetlist() 357 call assert_true(len(l) == 2 && 358 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' && 359 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800') 360 361 " Test with a non existent file 362 call assert_fails('Xfile non_existent_file', 'E40') 363 364 " Run cfile/lfile from a modified buffer 365 enew! 366 silent! put ='Quickfix' 367 silent! Xfile Xqftestfile1 368 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)') 369 370 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1') 371 Xaddfile Xqftestfile1 372 let l = g:Xgetlist() 373 call assert_true(len(l) == 3 && 374 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900') 375 376 call writefile(['Xtestfile1:222:77:Line 222', 377 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1') 378 379 enew! 380 Xgetfile Xqftestfile1 381 let l = g:Xgetlist() 382 call assert_true(len(l) == 2 && 383 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' && 384 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333') 385 386 " Test for a file with a long line and without a newline at the end 387 let text = repeat('x', 1024) 388 let t = 'a.txt:18:' . text 389 call writefile([t], 'Xqftestfile1', 'b') 390 silent! Xfile Xqftestfile1 391 call assert_equal(text, g:Xgetlist()[0].text) 392 393 call delete('Xqftestfile1') 394endfunc 395 396func Test_cfile() 397 call XfileTests('c') 398 call XfileTests('l') 399endfunc 400 401" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and 402" :lgetbuffer commands. 403func XbufferTests(cchar) 404 call s:setup_commands(a:cchar) 405 406 enew! 407 silent! call setline(1, ['Xtestfile7:700:10:Line 700', 408 \ 'Xtestfile8:800:15:Line 800']) 409 Xbuffer! 410 let l = g:Xgetlist() 411 call assert_true(len(l) == 2 && 412 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' && 413 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800') 414 415 enew! 416 silent! call setline(1, ['Xtestfile9:900:55:Line 900', 417 \ 'Xtestfile10:950:66:Line 950']) 418 Xgetbuffer 419 let l = g:Xgetlist() 420 call assert_true(len(l) == 2 && 421 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' && 422 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950') 423 424 enew! 425 silent! call setline(1, ['Xtestfile11:700:20:Line 700', 426 \ 'Xtestfile12:750:25:Line 750']) 427 Xaddbuffer 428 let l = g:Xgetlist() 429 call assert_true(len(l) == 4 && 430 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' && 431 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' && 432 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750') 433 enew! 434 435 " Check for invalid buffer 436 call assert_fails('Xbuffer 199', 'E474:') 437 438 " Check for unloaded buffer 439 edit Xtestfile1 440 let bnr = bufnr('%') 441 enew! 442 call assert_fails('Xbuffer ' . bnr, 'E681:') 443 444 " Check for invalid range 445 " Using Xbuffer will not run the range check in the cbuffer/lbuffer 446 " commands. So directly call the commands. 447 if (a:cchar == 'c') 448 call assert_fails('900,999cbuffer', 'E16:') 449 else 450 call assert_fails('900,999lbuffer', 'E16:') 451 endif 452endfunc 453 454func Test_cbuffer() 455 call XbufferTests('c') 456 call XbufferTests('l') 457endfunc 458 459func XexprTests(cchar) 460 call s:setup_commands(a:cchar) 461 462 call assert_fails('Xexpr 10', 'E777:') 463endfunc 464 465func Test_cexpr() 466 call XexprTests('c') 467 call XexprTests('l') 468endfunc 469 470" Tests for :cnext, :cprev, :cfirst, :clast commands 471func Xtest_browse(cchar) 472 call s:setup_commands(a:cchar) 473 474 call g:Xsetlist([], 'f') 475 " Jumping to first or next location list entry without any error should 476 " result in failure 477 if a:cchar == 'c' 478 let err = 'E42:' 479 let cmd = '$cc' 480 else 481 let err = 'E776:' 482 let cmd = '$ll' 483 endif 484 call assert_fails('Xnext', err) 485 call assert_fails('Xprev', err) 486 call assert_fails('Xnfile', err) 487 call assert_fails('Xpfile', err) 488 call assert_fails(cmd, err) 489 490 Xexpr '' 491 call assert_fails(cmd, 'E42:') 492 493 call s:create_test_file('Xqftestfile1') 494 call s:create_test_file('Xqftestfile2') 495 496 Xgetexpr ['Xqftestfile1:5:Line5', 497 \ 'Xqftestfile1:6:Line6', 498 \ 'Xqftestfile2:10:Line10', 499 \ 'Xqftestfile2:11:Line11', 500 \ 'RegularLine1', 501 \ 'RegularLine2'] 502 503 Xfirst 504 call assert_fails('-5Xcc', 'E16:') 505 call assert_fails('Xprev', 'E553') 506 call assert_fails('Xpfile', 'E553') 507 Xnfile 508 call assert_equal('Xqftestfile2', @%) 509 call assert_equal(10, line('.')) 510 Xpfile 511 call assert_equal('Xqftestfile1', @%) 512 call assert_equal(6, line('.')) 513 5Xcc 514 call assert_equal(5, g:Xgetlist({'idx':0}).idx) 515 2Xcc 516 call assert_equal(2, g:Xgetlist({'idx':0}).idx) 517 if a:cchar == 'c' 518 cc 519 else 520 ll 521 endif 522 call assert_equal(2, g:Xgetlist({'idx':0}).idx) 523 10Xcc 524 call assert_equal(6, g:Xgetlist({'idx':0}).idx) 525 Xlast 526 Xprev 527 call assert_equal('Xqftestfile2', @%) 528 call assert_equal(11, line('.')) 529 call assert_fails('Xnext', 'E553') 530 call assert_fails('Xnfile', 'E553') 531 " To process the range using quickfix list entries, directly use the 532 " quickfix commands (don't use the user defined commands) 533 if a:cchar == 'c' 534 $cc 535 else 536 $ll 537 endif 538 call assert_equal(6, g:Xgetlist({'idx':0}).idx) 539 Xrewind 540 call assert_equal('Xqftestfile1', @%) 541 call assert_equal(5, line('.')) 542 543 10Xnext 544 call assert_equal('Xqftestfile2', @%) 545 call assert_equal(11, line('.')) 546 10Xprev 547 call assert_equal('Xqftestfile1', @%) 548 call assert_equal(5, line('.')) 549 550 " Jumping to an error from the error window using cc command 551 Xgetexpr ['Xqftestfile1:5:Line5', 552 \ 'Xqftestfile1:6:Line6', 553 \ 'Xqftestfile2:10:Line10', 554 \ 'Xqftestfile2:11:Line11'] 555 Xopen 556 10Xcc 557 call assert_equal(11, line('.')) 558 call assert_equal('Xqftestfile2', @%) 559 Xopen 560 call cursor(2, 1) 561 if a:cchar == 'c' 562 .cc 563 else 564 .ll 565 endif 566 call assert_equal(6, line('.')) 567 call assert_equal('Xqftestfile1', @%) 568 569 " Jumping to an error from the error window (when only the error window is 570 " present) 571 Xopen | only 572 Xlast 1 573 call assert_equal(5, line('.')) 574 call assert_equal('Xqftestfile1', @%) 575 576 Xexpr "" 577 call assert_fails('Xnext', 'E42:') 578 579 call delete('Xqftestfile1') 580 call delete('Xqftestfile2') 581 582 " Should be able to use next/prev with invalid entries 583 Xexpr "" 584 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 585 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 586 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo'] 587 call assert_equal(5, g:Xgetlist({'size' : 0}).size) 588 Xlast 589 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx) 590 Xfirst 591 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) 592 2Xnext 593 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 594endfunc 595 596func Test_browse() 597 call Xtest_browse('c') 598 call Xtest_browse('l') 599endfunc 600 601func Test_nomem() 602 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) 603 call assert_fails('vimgrep vim runtest.vim', 'E342:') 604 605 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0) 606 call assert_fails('vimgrep vim runtest.vim', 'E342:') 607 608 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0) 609 call assert_fails('cfile runtest.vim', 'E342:') 610 611 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0) 612 call assert_fails('cfile runtest.vim', 'E342:') 613 614 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0) 615 call assert_fails('cfile runtest.vim', 'E342:') 616 617endfunc 618 619func s:test_xhelpgrep(cchar) 620 call s:setup_commands(a:cchar) 621 Xhelpgrep quickfix 622 Xopen 623 if a:cchar == 'c' 624 let title_text = ':helpgrep quickfix' 625 else 626 let title_text = ':lhelpgrep quickfix' 627 endif 628 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) 629 630 " Jumping to a help topic should open the help window 631 only 632 Xnext 633 call assert_true(&buftype == 'help') 634 call assert_true(winnr('$') == 2) 635 " Jumping to the next match should reuse the help window 636 Xnext 637 call assert_true(&buftype == 'help') 638 call assert_true(winnr() == 1) 639 call assert_true(winnr('$') == 2) 640 " Jumping to the next match from the quickfix window should reuse the help 641 " window 642 Xopen 643 Xnext 644 call assert_true(&buftype == 'help') 645 call assert_true(winnr() == 1) 646 call assert_true(winnr('$') == 2) 647 648 " This wipes out the buffer, make sure that doesn't cause trouble. 649 Xclose 650 651 " When the current window is vertically split, jumping to a help match 652 " should open the help window at the top. 653 only | enew 654 let w1 = win_getid() 655 vert new 656 let w2 = win_getid() 657 Xnext 658 let w3 = win_getid() 659 call assert_true(&buftype == 'help') 660 call assert_true(winnr() == 1) 661 " See jump_to_help_window() for details 662 let w2_width = winwidth(w2) 663 if w2_width != &columns && w2_width < 80 664 call assert_equal(['col', [['leaf', w3], 665 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout()) 666 else 667 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]], 668 \ ['leaf', w1]]] , winlayout()) 669 endif 670 671 new | only 672 set buftype=help 673 set modified 674 call assert_fails('Xnext', 'E37:') 675 set nomodified 676 new | only 677 678 if a:cchar == 'l' 679 " When a help window is present, running :lhelpgrep should reuse the 680 " help window and not the current window 681 new | only 682 call g:Xsetlist([], 'f') 683 help index.txt 684 wincmd w 685 lhelpgrep quickfix 686 call assert_equal(1, winnr()) 687 call assert_notequal([], getloclist(1)) 688 call assert_equal([], getloclist(2)) 689 endif 690 691 new | only 692 693 " Search for non existing help string 694 call assert_fails('Xhelpgrep a1b2c3', 'E480:') 695 " Invalid regular expression 696 call assert_fails('Xhelpgrep \@<!', 'E866:') 697endfunc 698 699func Test_helpgrep() 700 call s:test_xhelpgrep('c') 701 helpclose 702 call s:test_xhelpgrep('l') 703endfunc 704 705func Test_errortitle() 706 augroup QfBufWinEnter 707 au! 708 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 709 augroup END 710 copen 711 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}] 712 call setqflist(a) 713 call assert_equal(':setqflist()', g:a) 714 augroup QfBufWinEnter 715 au! 716 augroup END 717 augroup! QfBufWinEnter 718endfunc 719 720func Test_vimgreptitle() 721 augroup QfBufWinEnter 722 au! 723 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 724 augroup END 725 try 726 vimgrep /pattern/j file 727 catch /E480/ 728 endtry 729 copen 730 call assert_equal(': vimgrep /pattern/j file', g:a) 731 augroup QfBufWinEnter 732 au! 733 augroup END 734 augroup! QfBufWinEnter 735endfunc 736 737func XqfTitleTests(cchar) 738 call s:setup_commands(a:cchar) 739 740 Xgetexpr ['file:1:1:message'] 741 let l = g:Xgetlist() 742 if a:cchar == 'c' 743 call setqflist(l, 'r') 744 else 745 call setloclist(0, l, 'r') 746 endif 747 748 Xopen 749 if a:cchar == 'c' 750 let title = ':setqflist()' 751 else 752 let title = ':setloclist()' 753 endif 754 call assert_equal(title, w:quickfix_title) 755 Xclose 756endfunc 757 758" Tests for quickfix window's title 759func Test_qf_title() 760 call XqfTitleTests('c') 761 call XqfTitleTests('l') 762endfunc 763 764" Tests for 'errorformat' 765func Test_efm() 766 let save_efm = &efm 767 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# 768 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 769 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 770 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 771 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC'] 772 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 773 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 774 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY'] 775 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 776 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) 777 let &efm = save_efm 778endfunc 779 780" This will test for problems in quickfix: 781" A. incorrectly copying location lists which caused the location list to show 782" a different name than the file that was actually being displayed. 783" B. not reusing the window for which the location list window is opened but 784" instead creating new windows. 785" C. make sure that the location list window is not reused instead of the 786" window it belongs to. 787" 788" Set up the test environment: 789func ReadTestProtocol(name) 790 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') 791 let word = substitute(base, '\v(.*)\..*', '\1', '') 792 793 setl modifiable 794 setl noreadonly 795 setl noswapfile 796 setl bufhidden=delete 797 %del _ 798 " For problem 2: 799 " 'buftype' has to be set to reproduce the constant opening of new windows 800 setl buftype=nofile 801 802 call setline(1, word) 803 804 setl nomodified 805 setl nomodifiable 806 setl readonly 807 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') 808endfunc 809 810func Test_locationlist() 811 enew 812 813 augroup testgroup 814 au! 815 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>")) 816 augroup END 817 818 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ] 819 820 let qflist = [] 821 for word in words 822 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', }) 823 " NOTE: problem 1: 824 " intentionally not setting 'lnum' so that the quickfix entries are not 825 " valid 826 eval qflist->setloclist(0, ' ') 827 endfor 828 829 " Test A 830 lrewind 831 enew 832 lopen 833 4lnext 834 vert split 835 wincmd L 836 lopen 837 wincmd p 838 lnext 839 let fileName = expand("%") 840 wincmd p 841 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '') 842 let fileName = substitute(fileName, '\\', '/', 'g') 843 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g') 844 call assert_equal("test://bar.txt", fileName) 845 call assert_equal("test://bar.txt", locationListFileName) 846 847 wincmd n | only 848 849 " Test B: 850 lrewind 851 lopen 852 2 853 exe "normal \<CR>" 854 wincmd p 855 3 856 exe "normal \<CR>" 857 wincmd p 858 4 859 exe "normal \<CR>" 860 call assert_equal(2, winnr('$')) 861 wincmd n | only 862 863 " Test C: 864 lrewind 865 lopen 866 " Let's move the location list window to the top to check whether it (the 867 " first window found) will be reused when we try to open new windows: 868 wincmd K 869 2 870 exe "normal \<CR>" 871 wincmd p 872 3 873 exe "normal \<CR>" 874 wincmd p 875 4 876 exe "normal \<CR>" 877 1wincmd w 878 call assert_equal('quickfix', &buftype) 879 2wincmd w 880 let bufferName = expand("%") 881 let bufferName = substitute(bufferName, '\\', '/', 'g') 882 call assert_equal('test://quux.txt', bufferName) 883 884 wincmd n | only 885 886 augroup! testgroup 887endfunc 888 889func Test_locationlist_curwin_was_closed() 890 augroup testgroup 891 au! 892 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>")) 893 augroup END 894 895 func! R(n) 896 quit 897 endfunc 898 899 new 900 let q = [] 901 call add(q, {'filename': 'test_curwin.txt' }) 902 call setloclist(0, q) 903 call assert_fails('lrewind', 'E924:') 904 905 augroup! testgroup 906endfunc 907 908func Test_locationlist_cross_tab_jump() 909 call writefile(['loclistfoo'], 'loclistfoo') 910 call writefile(['loclistbar'], 'loclistbar') 911 set switchbuf=usetab 912 913 edit loclistfoo 914 tabedit loclistbar 915 silent lgrep loclistfoo loclist* 916 call assert_equal(1, tabpagenr()) 917 918 enew | only | tabonly 919 set switchbuf&vim 920 call delete('loclistfoo') 921 call delete('loclistbar') 922endfunc 923 924" More tests for 'errorformat' 925func Test_efm1() 926 if !has('unix') 927 " The 'errorformat' setting is different on non-Unix systems. 928 " This test works only on Unix-like systems. 929 return 930 endif 931 932 let l =<< trim [DATA] 933 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set. 934 "Xtestfile", line 6 col 19; this is an error 935 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c 936 Xtestfile:9: parse error before `asd' 937 make: *** [vim] Error 1 938 in file "Xtestfile" linenr 10: there is an error 939 940 2 returned 941 "Xtestfile", line 11 col 1; this is an error 942 "Xtestfile", line 12 col 2; this is another error 943 "Xtestfile", line 14:10; this is an error in column 10 944 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time 945 "Xtestfile", linenr 16: yet another problem 946 Error in "Xtestfile" at line 17: 947 x should be a dot 948 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 949 ^ 950 Error in "Xtestfile" at line 18: 951 x should be a dot 952 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 953 .............^ 954 Error in "Xtestfile" at line 19: 955 x should be a dot 956 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 957 --------------^ 958 Error in "Xtestfile" at line 20: 959 x should be a dot 960 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 961 ^ 962 963 Does anyone know what is the problem and how to correction it? 964 "Xtestfile", line 21 col 9: What is the title of the quickfix window? 965 "Xtestfile", line 22 col 9: What is the title of the quickfix window? 966 [DATA] 967 968 call writefile(l, 'Xerrorfile1') 969 call writefile(l[:-2], 'Xerrorfile2') 970 971 let m =<< [DATA] 972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2 973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3 974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4 975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5 976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6 977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7 978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8 979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9 980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10 981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11 982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12 983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13 984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14 985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15 986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16 987 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 988 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 989 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 991 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21 992 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22 993[DATA] 994 call writefile(m, 'Xtestfile') 995 996 let save_efm = &efm 997 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m 998 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m 999 1000 exe 'cf Xerrorfile2' 1001 clast 1002 copen 1003 call assert_equal(':cf Xerrorfile2', w:quickfix_title) 1004 wincmd p 1005 1006 exe 'cf Xerrorfile1' 1007 call assert_equal([4, 12], [line('.'), col('.')]) 1008 cn 1009 call assert_equal([6, 19], [line('.'), col('.')]) 1010 cn 1011 call assert_equal([9, 2], [line('.'), col('.')]) 1012 cn 1013 call assert_equal([10, 2], [line('.'), col('.')]) 1014 cn 1015 call assert_equal([11, 1], [line('.'), col('.')]) 1016 cn 1017 call assert_equal([12, 2], [line('.'), col('.')]) 1018 cn 1019 call assert_equal([14, 10], [line('.'), col('.')]) 1020 cn 1021 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')]) 1022 cn 1023 call assert_equal([16, 2], [line('.'), col('.')]) 1024 cn 1025 call assert_equal([17, 6], [line('.'), col('.')]) 1026 cn 1027 call assert_equal([18, 7], [line('.'), col('.')]) 1028 cn 1029 call assert_equal([19, 8], [line('.'), col('.')]) 1030 cn 1031 call assert_equal([20, 9], [line('.'), col('.')]) 1032 clast 1033 cprev 1034 cprev 1035 wincmd w 1036 call assert_equal(':cf Xerrorfile1', w:quickfix_title) 1037 wincmd p 1038 1039 let &efm = save_efm 1040 call delete('Xerrorfile1') 1041 call delete('Xerrorfile2') 1042 call delete('Xtestfile') 1043endfunc 1044 1045" Test for quickfix directory stack support 1046func s:dir_stack_tests(cchar) 1047 call s:setup_commands(a:cchar) 1048 1049 let save_efm=&efm 1050 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 1051 1052 let lines = ["Entering dir 'dir1/a'", 1053 \ 'habits2.txt:1:Nine Healthy Habits', 1054 \ "Entering dir 'b'", 1055 \ 'habits3.txt:2:0 Hours of television', 1056 \ 'habits2.txt:7:5 Small meals', 1057 \ "Entering dir 'dir1/c'", 1058 \ 'habits4.txt:3:1 Hour of exercise', 1059 \ "Leaving dir 'dir1/c'", 1060 \ "Leaving dir 'dir1/a'", 1061 \ 'habits1.txt:4:2 Liters of water', 1062 \ "Entering dir 'dir2'", 1063 \ 'habits5.txt:5:3 Cups of hot green tea', 1064 \ "Leaving dir 'dir2'" 1065 \] 1066 1067 Xexpr "" 1068 for l in lines 1069 Xaddexpr l 1070 endfor 1071 1072 let qf = g:Xgetlist() 1073 1074 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr)) 1075 call assert_equal(1, qf[1].lnum) 1076 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr)) 1077 call assert_equal(2, qf[3].lnum) 1078 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr)) 1079 call assert_equal(7, qf[4].lnum) 1080 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr)) 1081 call assert_equal(3, qf[6].lnum) 1082 call assert_equal('habits1.txt', bufname(qf[9].bufnr)) 1083 call assert_equal(4, qf[9].lnum) 1084 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr)) 1085 call assert_equal(5, qf[11].lnum) 1086 1087 let &efm=save_efm 1088endfunc 1089 1090" Tests for %D and %X errorformat options 1091func Test_efm_dirstack() 1092 " Create the directory stack and files 1093 call mkdir('dir1') 1094 call mkdir('dir1/a') 1095 call mkdir('dir1/a/b') 1096 call mkdir('dir1/c') 1097 call mkdir('dir2') 1098 1099 let lines = ["Nine Healthy Habits", 1100 \ "0 Hours of television", 1101 \ "1 Hour of exercise", 1102 \ "2 Liters of water", 1103 \ "3 Cups of hot green tea", 1104 \ "4 Short mental breaks", 1105 \ "5 Small meals", 1106 \ "6 AM wake up time", 1107 \ "7 Minutes of laughter", 1108 \ "8 Hours of sleep (at least)", 1109 \ "9 PM end of the day and off to bed" 1110 \ ] 1111 call writefile(lines, 'habits1.txt') 1112 call writefile(lines, 'dir1/a/habits2.txt') 1113 call writefile(lines, 'dir1/a/b/habits3.txt') 1114 call writefile(lines, 'dir1/c/habits4.txt') 1115 call writefile(lines, 'dir2/habits5.txt') 1116 1117 call s:dir_stack_tests('c') 1118 call s:dir_stack_tests('l') 1119 1120 call delete('dir1', 'rf') 1121 call delete('dir2', 'rf') 1122 call delete('habits1.txt') 1123endfunc 1124 1125" Test for resync after continuing an ignored message 1126func Xefm_ignore_continuations(cchar) 1127 call s:setup_commands(a:cchar) 1128 1129 let save_efm = &efm 1130 1131 let &efm = 1132 \ '%Eerror %m %l,' . 1133 \ '%-Wignored %m %l,' . 1134 \ '%+Cmore ignored %m %l,' . 1135 \ '%Zignored end' 1136 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4'] 1137 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]') 1138 call assert_equal([['resync', 1, 4, 'E']], l) 1139 1140 let &efm = save_efm 1141endfunc 1142 1143func Test_efm_ignore_continuations() 1144 call Xefm_ignore_continuations('c') 1145 call Xefm_ignore_continuations('l') 1146endfunc 1147 1148" Tests for invalid error format specifies 1149func Xinvalid_efm_Tests(cchar) 1150 call s:setup_commands(a:cchar) 1151 1152 let save_efm = &efm 1153 1154 set efm=%f:%l:%m,%f:%f:%l:%m 1155 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:') 1156 1157 set efm=%f:%l:%m,%f:%l:%r:%m 1158 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:') 1159 1160 set efm=%f:%l:%m,%O:%f:%l:%m 1161 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:') 1162 1163 set efm=%f:%l:%m,%f:%l:%*[^a-z 1164 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:') 1165 1166 set efm=%f:%l:%m,%f:%l:%*c 1167 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:') 1168 1169 set efm=%f:%l:%m,%L%M%N 1170 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:') 1171 1172 set efm=%f:%l:%m,%f:%l:%m:%R 1173 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:') 1174 1175 " Invalid regular expression 1176 set efm=%\\%%k 1177 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:') 1178 1179 set efm= 1180 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:') 1181 1182 set efm=%DEntering\ dir\ abc,%f:%l:%m 1183 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:') 1184 1185 let &efm = save_efm 1186endfunc 1187 1188func Test_invalid_efm() 1189 call Xinvalid_efm_Tests('c') 1190 call Xinvalid_efm_Tests('l') 1191endfunc 1192 1193" TODO: 1194" Add tests for the following formats in 'errorformat' 1195" %r %O 1196func Test_efm2() 1197 let save_efm = &efm 1198 1199 " Test for %s format in efm 1200 set efm=%f:%s 1201 cexpr 'Xtestfile:Line search text' 1202 let l = getqflist() 1203 call assert_equal('^\VLine search text\$', l[0].pattern) 1204 call assert_equal(0, l[0].lnum) 1205 1206 let l = split(execute('clist', ''), "\n") 1207 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l) 1208 1209 " Test for a long line 1210 cexpr 'Xtestfile:' . repeat('a', 1026) 1211 let l = getqflist() 1212 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern) 1213 1214 " Test for %P, %Q and %t format specifiers 1215 let lines =<< trim [DATA] 1216 [Xtestfile1] 1217 (1,17) error: ';' missing 1218 (21,2) warning: variable 'z' not defined 1219 (67,3) error: end of file found before string ended 1220 -- 1221 1222 [Xtestfile2] 1223 -- 1224 1225 [Xtestfile3] 1226 NEW compiler v1.1 1227 (2,2) warning: variable 'x' not defined 1228 (67,3) warning: 's' already defined 1229 -- 1230 [DATA] 1231 1232 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r 1233 " To exercise the push/pop file functionality in quickfix, the test files 1234 " need to be created. 1235 call writefile(['Line1'], 'Xtestfile1') 1236 call writefile(['Line2'], 'Xtestfile2') 1237 call writefile(['Line3'], 'Xtestfile3') 1238 cexpr "" 1239 for l in lines 1240 caddexpr l 1241 endfor 1242 let l = getqflist() 1243 call assert_equal(12, len(l)) 1244 call assert_equal(21, l[2].lnum) 1245 call assert_equal(2, l[2].col) 1246 call assert_equal('w', l[2].type) 1247 call assert_equal('e', l[3].type) 1248 call delete('Xtestfile1') 1249 call delete('Xtestfile2') 1250 call delete('Xtestfile3') 1251 1252 " Test for %P, %Q with non-existing files 1253 cexpr lines 1254 let l = getqflist() 1255 call assert_equal(14, len(l)) 1256 call assert_equal('[Xtestfile1]', l[0].text) 1257 call assert_equal('[Xtestfile2]', l[6].text) 1258 call assert_equal('[Xtestfile3]', l[9].text) 1259 1260 " Tests for %E, %C and %Z format specifiers 1261 let lines =<< trim [DATA] 1262 Error 275 1263 line 42 1264 column 3 1265 ' ' expected after '--' 1266 [DATA] 1267 1268 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m 1269 cgetexpr lines 1270 let l = getqflist() 1271 call assert_equal(275, l[0].nr) 1272 call assert_equal(42, l[0].lnum) 1273 call assert_equal(3, l[0].col) 1274 call assert_equal('E', l[0].type) 1275 call assert_equal("\n' ' expected after '--'", l[0].text) 1276 1277 " Test for %> 1278 let lines =<< trim [DATA] 1279 Error in line 147 of foo.c: 1280 unknown variable 'i' 1281 [DATA] 1282 1283 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m 1284 cgetexpr lines 1285 let l = getqflist() 1286 call assert_equal(147, l[0].lnum) 1287 call assert_equal('E', l[0].type) 1288 call assert_equal("\nunknown variable 'i'", l[0].text) 1289 1290 " Test for %A, %C and other formats 1291 let lines =<< trim [DATA] 1292 ============================================================== 1293 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest) 1294 -------------------------------------------------------------- 1295 Traceback (most recent call last): 1296 File "unittests/dbfacadeTest.py", line 89, in testFoo 1297 self.assertEquals(34, dtid) 1298 File "/usr/lib/python2.2/unittest.py", line 286, in 1299 failUnlessEqual 1300 raise self.failureException, \\ 1301 W:AssertionError: 34 != 33 1302 1303 -------------------------------------------------------------- 1304 Ran 27 tests in 0.063s 1305 [DATA] 1306 1307 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m 1308 cgetexpr lines 1309 let l = getqflist() 1310 call assert_equal(8, len(l)) 1311 call assert_equal(89, l[4].lnum) 1312 call assert_equal(1, l[4].valid) 1313 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) 1314 call assert_equal('W', l[4].type) 1315 1316 " Test for %o 1317 set efm=%f(%o):%l\ %m 1318 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error'] 1319 call writefile(['Line1'], 'Xotestfile') 1320 let l = getqflist() 1321 call assert_equal(1, len(l), string(l)) 1322 call assert_equal('Language.PureScript.Types', l[0].module) 1323 copen 1324 call assert_equal('Language.PureScript.Types|20| Error', getline(1)) 1325 call feedkeys("\<CR>", 'xn') 1326 call assert_equal('Xotestfile', expand('%:t')) 1327 cclose 1328 bd 1329 call delete("Xotestfile") 1330 1331 " Test for a long module name 1332 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message' 1333 let l = getqflist() 1334 call assert_equal(repeat('m', 1024), l[0].module) 1335 call assert_equal(15, l[0].lnum) 1336 call assert_equal('message', l[0].text) 1337 1338 " The following sequence of commands used to crash Vim 1339 set efm=%W%m 1340 cgetexpr ['msg1'] 1341 let l = getqflist() 1342 call assert_equal(1, len(l), string(l)) 1343 call assert_equal('msg1', l[0].text) 1344 set efm=%C%m 1345 lexpr 'msg2' 1346 let l = getloclist(0) 1347 call assert_equal(1, len(l), string(l)) 1348 call assert_equal('msg2', l[0].text) 1349 lopen 1350 call setqflist([], 'r') 1351 caddbuf 1352 let l = getqflist() 1353 call assert_equal(1, len(l), string(l)) 1354 call assert_equal('|| msg2', l[0].text) 1355 1356 " When matching error lines, case should be ignored. Test for this. 1357 set noignorecase 1358 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'}) 1359 call assert_equal(10, l.items[0].lnum) 1360 call assert_equal('Line 20', l.items[0].text) 1361 set ignorecase& 1362 1363 new | only 1364 let &efm = save_efm 1365endfunc 1366 1367" Test for '%t' (error type) field in 'efm' 1368func Test_efm_error_type() 1369 let save_efm = &efm 1370 1371 " error type 1372 set efm=%f:%l:%t:%m 1373 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3", 1374 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"] 1375 let output = split(execute('clist'), "\n") 1376 call assert_equal([ 1377 \ ' 1 Xfile1:10 error: msg1', 1378 \ ' 2 Xfile1:20 warning: msg2', 1379 \ ' 3 Xfile1:30 info: msg3', 1380 \ ' 4 Xfile1:40 note: msg4', 1381 \ ' 5 Xfile1:50 R: msg5'], output) 1382 1383 " error type and a error number 1384 set efm=%f:%l:%t:%n:%m 1385 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3", 1386 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"] 1387 let output = split(execute('clist'), "\n") 1388 call assert_equal([ 1389 \ ' 1 Xfile1:10 error 2: msg1', 1390 \ ' 2 Xfile1:20 warning 4: msg2', 1391 \ ' 3 Xfile1:30 info 6: msg3', 1392 \ ' 4 Xfile1:40 note 8: msg4', 1393 \ ' 5 Xfile1:50 R 3: msg5'], output) 1394 let &efm = save_efm 1395endfunc 1396 1397func XquickfixChangedByAutocmd(cchar) 1398 call s:setup_commands(a:cchar) 1399 if a:cchar == 'c' 1400 let ErrorNr = 'E925' 1401 func! ReadFunc() 1402 colder 1403 cgetexpr [] 1404 endfunc 1405 else 1406 let ErrorNr = 'E926' 1407 func! ReadFunc() 1408 lolder 1409 lgetexpr [] 1410 endfunc 1411 endif 1412 1413 augroup testgroup 1414 au! 1415 autocmd BufReadCmd test_changed.txt call ReadFunc() 1416 augroup END 1417 1418 new | only 1419 let words = [ "a", "b" ] 1420 let qflist = [] 1421 for word in words 1422 call add(qflist, {'filename': 'test_changed.txt'}) 1423 call g:Xsetlist(qflist, ' ') 1424 endfor 1425 call assert_fails('Xrewind', ErrorNr . ':') 1426 1427 augroup! testgroup 1428endfunc 1429 1430func Test_quickfix_was_changed_by_autocmd() 1431 call XquickfixChangedByAutocmd('c') 1432 call XquickfixChangedByAutocmd('l') 1433endfunc 1434 1435func Test_caddbuffer_to_empty() 1436 helpgr quickfix 1437 call setqflist([], 'r') 1438 cad 1439 try 1440 cn 1441 catch 1442 " number of matches is unknown 1443 call assert_true(v:exception =~ 'E553:') 1444 endtry 1445 quit! 1446endfunc 1447 1448func Test_cgetexpr_works() 1449 " this must not crash Vim 1450 cgetexpr [$x] 1451 lgetexpr [$x] 1452endfunc 1453 1454" Tests for the setqflist() and setloclist() functions 1455func SetXlistTests(cchar, bnum) 1456 call s:setup_commands(a:cchar) 1457 1458 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, 1459 \ {'bufnr': a:bnum, 'lnum': 2}]) 1460 let l = g:Xgetlist() 1461 call assert_equal(2, len(l)) 1462 call assert_equal(2, l[1].lnum) 1463 1464 Xnext 1465 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a') 1466 let l = g:Xgetlist() 1467 call assert_equal(3, len(l)) 1468 Xnext 1469 call assert_equal(3, line('.')) 1470 1471 " Appending entries to the list should not change the cursor position 1472 " in the quickfix window 1473 Xwindow 1474 1 1475 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4}, 1476 \ {'bufnr': a:bnum, 'lnum': 5}], 'a') 1477 call assert_equal(1, line('.')) 1478 close 1479 1480 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}, 1481 \ {'bufnr': a:bnum, 'lnum': 4}, 1482 \ {'bufnr': a:bnum, 'lnum': 5}], 'r') 1483 let l = g:Xgetlist() 1484 call assert_equal(3, len(l)) 1485 call assert_equal(5, l[2].lnum) 1486 1487 call g:Xsetlist([]) 1488 let l = g:Xgetlist() 1489 call assert_equal(0, len(l)) 1490 1491 " Tests for setting the 'valid' flag 1492 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}]) 1493 Xwindow 1494 call assert_equal(1, winnr('$')) 1495 let l = g:Xgetlist() 1496 call g:Xsetlist(l) 1497 call assert_equal(0, g:Xgetlist()[0].valid) 1498 " Adding a non-valid entry should not mark the list as having valid entries 1499 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a') 1500 Xwindow 1501 call assert_equal(1, winnr('$')) 1502 1503 " :cnext/:cprev should still work even with invalid entries in the list 1504 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0}, 1505 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}] 1506 call g:Xsetlist(l) 1507 Xnext 1508 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx) 1509 Xprev 1510 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) 1511 " :cnext/:cprev should still work after appending invalid entries to an 1512 " empty list 1513 call g:Xsetlist([]) 1514 call g:Xsetlist(l, 'a') 1515 Xnext 1516 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx) 1517 Xprev 1518 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) 1519 1520 call g:Xsetlist([{'text':'Text1', 'valid':1}]) 1521 Xwindow 1522 call assert_equal(2, winnr('$')) 1523 Xclose 1524 let save_efm = &efm 1525 set efm=%m 1526 Xgetexpr 'TestMessage' 1527 let l = g:Xgetlist() 1528 call g:Xsetlist(l) 1529 call assert_equal(1, g:Xgetlist()[0].valid) 1530 let &efm = save_efm 1531 1532 " Error cases: 1533 " Refer to a non-existing buffer and pass a non-dictionary type 1534 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," . 1535 \ " {'bufnr':999, 'lnum':5}])", 'E92:') 1536 call g:Xsetlist([[1, 2,3]]) 1537 call assert_equal(0, len(g:Xgetlist())) 1538 call assert_fails('call g:Xsetlist([], [])', 'E928:') 1539endfunc 1540 1541func Test_setqflist() 1542 new Xtestfile | only 1543 let bnum = bufnr('%') 1544 call setline(1, range(1,5)) 1545 1546 call SetXlistTests('c', bnum) 1547 call SetXlistTests('l', bnum) 1548 1549 enew! 1550 call delete('Xtestfile') 1551endfunc 1552 1553func Xlist_empty_middle(cchar) 1554 call s:setup_commands(a:cchar) 1555 1556 " create three quickfix lists 1557 let @/ = 'Test_' 1558 Xvimgrep // test_quickfix.vim 1559 let testlen = len(g:Xgetlist()) 1560 call assert_true(testlen > 0) 1561 Xvimgrep empty test_quickfix.vim 1562 call assert_true(len(g:Xgetlist()) > 0) 1563 Xvimgrep matches test_quickfix.vim 1564 let matchlen = len(g:Xgetlist()) 1565 call assert_true(matchlen > 0) 1566 Xolder 1567 " make the middle list empty 1568 call g:Xsetlist([], 'r') 1569 call assert_true(len(g:Xgetlist()) == 0) 1570 Xolder 1571 call assert_equal(testlen, len(g:Xgetlist())) 1572 Xnewer 1573 Xnewer 1574 call assert_equal(matchlen, len(g:Xgetlist())) 1575endfunc 1576 1577func Test_setqflist_empty_middle() 1578 call Xlist_empty_middle('c') 1579 call Xlist_empty_middle('l') 1580endfunc 1581 1582func Xlist_empty_older(cchar) 1583 call s:setup_commands(a:cchar) 1584 1585 " create three quickfix lists 1586 Xvimgrep one test_quickfix.vim 1587 let onelen = len(g:Xgetlist()) 1588 call assert_true(onelen > 0) 1589 Xvimgrep two test_quickfix.vim 1590 let twolen = len(g:Xgetlist()) 1591 call assert_true(twolen > 0) 1592 Xvimgrep three test_quickfix.vim 1593 let threelen = len(g:Xgetlist()) 1594 call assert_true(threelen > 0) 1595 Xolder 2 1596 " make the first list empty, check the others didn't change 1597 call g:Xsetlist([], 'r') 1598 call assert_true(len(g:Xgetlist()) == 0) 1599 Xnewer 1600 call assert_equal(twolen, len(g:Xgetlist())) 1601 Xnewer 1602 call assert_equal(threelen, len(g:Xgetlist())) 1603endfunc 1604 1605func Test_setqflist_empty_older() 1606 call Xlist_empty_older('c') 1607 call Xlist_empty_older('l') 1608endfunc 1609 1610func XquickfixSetListWithAct(cchar) 1611 call s:setup_commands(a:cchar) 1612 1613 let list1 = [{'filename': 'fnameA', 'text': 'A'}, 1614 \ {'filename': 'fnameB', 'text': 'B'}] 1615 let list2 = [{'filename': 'fnameC', 'text': 'C'}, 1616 \ {'filename': 'fnameD', 'text': 'D'}, 1617 \ {'filename': 'fnameE', 'text': 'E'}] 1618 1619 " {action} is unspecified. Same as specifying ' '. 1620 new | only 1621 silent! Xnewer 99 1622 call g:Xsetlist(list1) 1623 call g:Xsetlist(list2) 1624 let li = g:Xgetlist() 1625 call assert_equal(3, len(li)) 1626 call assert_equal('C', li[0]['text']) 1627 call assert_equal('D', li[1]['text']) 1628 call assert_equal('E', li[2]['text']) 1629 silent! Xolder 1630 let li = g:Xgetlist() 1631 call assert_equal(2, len(li)) 1632 call assert_equal('A', li[0]['text']) 1633 call assert_equal('B', li[1]['text']) 1634 1635 " {action} is specified ' '. 1636 new | only 1637 silent! Xnewer 99 1638 call g:Xsetlist(list1) 1639 call g:Xsetlist(list2, ' ') 1640 let li = g:Xgetlist() 1641 call assert_equal(3, len(li)) 1642 call assert_equal('C', li[0]['text']) 1643 call assert_equal('D', li[1]['text']) 1644 call assert_equal('E', li[2]['text']) 1645 silent! Xolder 1646 let li = g:Xgetlist() 1647 call assert_equal(2, len(li)) 1648 call assert_equal('A', li[0]['text']) 1649 call assert_equal('B', li[1]['text']) 1650 1651 " {action} is specified 'a'. 1652 new | only 1653 silent! Xnewer 99 1654 call g:Xsetlist(list1) 1655 call g:Xsetlist(list2, 'a') 1656 let li = g:Xgetlist() 1657 call assert_equal(5, len(li)) 1658 call assert_equal('A', li[0]['text']) 1659 call assert_equal('B', li[1]['text']) 1660 call assert_equal('C', li[2]['text']) 1661 call assert_equal('D', li[3]['text']) 1662 call assert_equal('E', li[4]['text']) 1663 1664 " {action} is specified 'r'. 1665 new | only 1666 silent! Xnewer 99 1667 call g:Xsetlist(list1) 1668 call g:Xsetlist(list2, 'r') 1669 let li = g:Xgetlist() 1670 call assert_equal(3, len(li)) 1671 call assert_equal('C', li[0]['text']) 1672 call assert_equal('D', li[1]['text']) 1673 call assert_equal('E', li[2]['text']) 1674 1675 " Test for wrong value. 1676 new | only 1677 call assert_fails("call g:Xsetlist(0)", 'E714:') 1678 call assert_fails("call g:Xsetlist(list1, '')", 'E927:') 1679 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:') 1680 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:') 1681 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:') 1682endfunc 1683 1684func Test_setqflist_invalid_nr() 1685 " The following command used to crash Vim 1686 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST}) 1687endfunc 1688 1689func Test_setqflist_user_sets_buftype() 1690 call setqflist([{'text': 'foo'}, {'text': 'bar'}]) 1691 set buftype=quickfix 1692 call setqflist([], 'a') 1693 enew 1694endfunc 1695 1696func Test_quickfix_set_list_with_act() 1697 call XquickfixSetListWithAct('c') 1698 call XquickfixSetListWithAct('l') 1699endfunc 1700 1701func XLongLinesTests(cchar) 1702 let l = g:Xgetlist() 1703 1704 call assert_equal(4, len(l)) 1705 call assert_equal(1, l[0].lnum) 1706 call assert_equal(1, l[0].col) 1707 call assert_equal(1975, len(l[0].text)) 1708 call assert_equal(2, l[1].lnum) 1709 call assert_equal(1, l[1].col) 1710 call assert_equal(4070, len(l[1].text)) 1711 call assert_equal(3, l[2].lnum) 1712 call assert_equal(1, l[2].col) 1713 call assert_equal(4070, len(l[2].text)) 1714 call assert_equal(4, l[3].lnum) 1715 call assert_equal(1, l[3].col) 1716 call assert_equal(10, len(l[3].text)) 1717 1718 call g:Xsetlist([], 'r') 1719endfunc 1720 1721func s:long_lines_tests(cchar) 1722 call s:setup_commands(a:cchar) 1723 1724 let testfile = 'samples/quickfix.txt' 1725 1726 " file 1727 exe 'Xgetfile' testfile 1728 call XLongLinesTests(a:cchar) 1729 1730 " list 1731 Xexpr readfile(testfile) 1732 call XLongLinesTests(a:cchar) 1733 1734 " string 1735 Xexpr join(readfile(testfile), "\n") 1736 call XLongLinesTests(a:cchar) 1737 1738 " buffer 1739 exe 'edit' testfile 1740 exe 'Xbuffer' bufnr('%') 1741 call XLongLinesTests(a:cchar) 1742endfunc 1743 1744func Test_long_lines() 1745 call s:long_lines_tests('c') 1746 call s:long_lines_tests('l') 1747endfunc 1748 1749func s:create_test_file(filename) 1750 let l = [] 1751 for i in range(1, 20) 1752 call add(l, 'Line' . i) 1753 endfor 1754 call writefile(l, a:filename) 1755endfunc 1756 1757func Test_switchbuf() 1758 call s:create_test_file('Xqftestfile1') 1759 call s:create_test_file('Xqftestfile2') 1760 call s:create_test_file('Xqftestfile3') 1761 1762 new | only 1763 edit Xqftestfile1 1764 let file1_winid = win_getid() 1765 new Xqftestfile2 1766 let file2_winid = win_getid() 1767 cgetexpr ['Xqftestfile1:5:Line5', 1768 \ 'Xqftestfile1:6:Line6', 1769 \ 'Xqftestfile2:10:Line10', 1770 \ 'Xqftestfile2:11:Line11', 1771 \ 'Xqftestfile3:15:Line15', 1772 \ 'Xqftestfile3:16:Line16'] 1773 1774 new 1775 let winid = win_getid() 1776 cfirst | cnext 1777 call assert_equal(winid, win_getid()) 1778 2cnext 1779 call assert_equal(winid, win_getid()) 1780 2cnext 1781 call assert_equal(winid, win_getid()) 1782 1783 " Test for 'switchbuf' set to search for files in windows in the current 1784 " tabpage and jump to an existing window (if present) 1785 set switchbuf=useopen 1786 enew 1787 cfirst | cnext 1788 call assert_equal(file1_winid, win_getid()) 1789 2cnext 1790 call assert_equal(file2_winid, win_getid()) 1791 2cnext 1792 call assert_equal(file2_winid, win_getid()) 1793 1794 " Test for 'switchbuf' set to search for files in tabpages and jump to an 1795 " existing tabpage (if present) 1796 enew | only 1797 set switchbuf=usetab 1798 tabedit Xqftestfile1 1799 tabedit Xqftestfile2 1800 tabedit Xqftestfile3 1801 tabfirst 1802 cfirst | cnext 1803 call assert_equal(2, tabpagenr()) 1804 2cnext 1805 call assert_equal(3, tabpagenr()) 1806 6cnext 1807 call assert_equal(4, tabpagenr()) 1808 2cpfile 1809 call assert_equal(2, tabpagenr()) 1810 2cnfile 1811 call assert_equal(4, tabpagenr()) 1812 tabfirst | tabonly | enew 1813 1814 " Test for 'switchbuf' set to open a new window for every file 1815 set switchbuf=split 1816 cfirst | cnext 1817 call assert_equal(1, winnr('$')) 1818 cnext | cnext 1819 call assert_equal(2, winnr('$')) 1820 cnext | cnext 1821 call assert_equal(3, winnr('$')) 1822 1823 " Test for 'switchbuf' set to open a new tabpage for every file 1824 set switchbuf=newtab 1825 enew | only 1826 cfirst | cnext 1827 call assert_equal(1, tabpagenr('$')) 1828 cnext | cnext 1829 call assert_equal(2, tabpagenr('$')) 1830 cnext | cnext 1831 call assert_equal(3, tabpagenr('$')) 1832 tabfirst | enew | tabonly | only 1833 1834 set switchbuf=uselast 1835 split 1836 let last_winid = win_getid() 1837 copen 1838 exe "normal 1G\<CR>" 1839 call assert_equal(last_winid, win_getid()) 1840 enew | only 1841 1842 " With an empty 'switchbuf', jumping to a quickfix entry should open the 1843 " file in an existing window (if present) 1844 set switchbuf= 1845 edit Xqftestfile1 1846 let file1_winid = win_getid() 1847 new Xqftestfile2 1848 let file2_winid = win_getid() 1849 copen 1850 exe "normal 1G\<CR>" 1851 call assert_equal(file1_winid, win_getid()) 1852 copen 1853 exe "normal 3G\<CR>" 1854 call assert_equal(file2_winid, win_getid()) 1855 copen | only 1856 exe "normal 5G\<CR>" 1857 call assert_equal(2, winnr('$')) 1858 call assert_equal(1, bufwinnr('Xqftestfile3')) 1859 1860 " If only quickfix window is open in the current tabpage, jumping to an 1861 " entry with 'switchbuf' set to 'usetab' should search in other tabpages. 1862 enew | only 1863 set switchbuf=usetab 1864 tabedit Xqftestfile1 1865 tabedit Xqftestfile2 1866 tabedit Xqftestfile3 1867 tabfirst 1868 copen | only 1869 clast 1870 call assert_equal(4, tabpagenr()) 1871 tabfirst | tabonly | enew | only 1872 1873 " Jumping to a file that is not present in any of the tabpages and the 1874 " current tabpage doesn't have any usable windows, should open it in a new 1875 " window in the current tabpage. 1876 copen | only 1877 cfirst 1878 call assert_equal(1, tabpagenr()) 1879 call assert_equal('Xqftestfile1', @%) 1880 1881 " If opening a file changes 'switchbuf', then the new value should be 1882 " retained. 1883 set modeline&vim 1884 call writefile(["vim: switchbuf=split"], 'Xqftestfile1') 1885 enew | only 1886 set switchbuf&vim 1887 cexpr "Xqftestfile1:1:10" 1888 call assert_equal('split', &switchbuf) 1889 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1') 1890 enew | only 1891 set switchbuf=useopen 1892 cexpr "Xqftestfile1:1:10" 1893 call assert_equal('usetab', &switchbuf) 1894 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1') 1895 enew | only 1896 set switchbuf=useopen 1897 cexpr "Xqftestfile1:1:10" 1898 call assert_equal('', &switchbuf) 1899 1900 call delete('Xqftestfile1') 1901 call delete('Xqftestfile2') 1902 call delete('Xqftestfile3') 1903 set switchbuf&vim 1904 1905 enew | only 1906endfunc 1907 1908func Xadjust_qflnum(cchar) 1909 call s:setup_commands(a:cchar) 1910 1911 enew | only 1912 1913 let fname = 'Xqftestfile' . a:cchar 1914 call s:create_test_file(fname) 1915 exe 'edit ' . fname 1916 1917 Xgetexpr [fname . ':5:Line5', 1918 \ fname . ':10:Line10', 1919 \ fname . ':15:Line15', 1920 \ fname . ':20:Line20'] 1921 1922 6,14delete 1923 call append(6, ['Buffer', 'Window']) 1924 1925 let l = g:Xgetlist() 1926 call assert_equal(5, l[0].lnum) 1927 call assert_equal(6, l[2].lnum) 1928 call assert_equal(13, l[3].lnum) 1929 1930 " If a file doesn't have any quickfix entries, then deleting lines in the 1931 " file should not update the quickfix list 1932 call g:Xsetlist([], 'f') 1933 1,2delete 1934 call assert_equal([], g:Xgetlist()) 1935 1936 enew! 1937 call delete(fname) 1938endfunc 1939 1940func Test_adjust_lnum() 1941 call setloclist(0, []) 1942 call Xadjust_qflnum('c') 1943 call setqflist([]) 1944 call Xadjust_qflnum('l') 1945endfunc 1946 1947" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands 1948func s:test_xgrep(cchar) 1949 call s:setup_commands(a:cchar) 1950 1951 " The following lines are used for the grep test. Don't remove. 1952 " Grep_Test_Text: Match 1 1953 " Grep_Test_Text: Match 2 1954 " GrepAdd_Test_Text: Match 1 1955 " GrepAdd_Test_Text: Match 2 1956 enew! | only 1957 set makeef&vim 1958 silent Xgrep Grep_Test_Text: test_quickfix.vim 1959 call assert_true(len(g:Xgetlist()) == 5) 1960 Xopen 1961 call assert_true(w:quickfix_title =~ '^:grep') 1962 Xclose 1963 enew 1964 set makeef=Temp_File_## 1965 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim 1966 call assert_true(len(g:Xgetlist()) == 9) 1967 1968 " Try with 'grepprg' set to 'internal' 1969 set grepprg=internal 1970 silent Xgrep Grep_Test_Text: test_quickfix.vim 1971 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim 1972 call assert_true(len(g:Xgetlist()) == 9) 1973 set grepprg&vim 1974 1975 call writefile(['Vim'], 'XtestTempFile') 1976 set makeef=XtestTempFile 1977 silent Xgrep Grep_Test_Text: test_quickfix.vim 1978 call assert_equal(5, len(g:Xgetlist())) 1979 call assert_false(filereadable('XtestTempFile')) 1980 set makeef&vim 1981endfunc 1982 1983func Test_grep() 1984 if !has('unix') 1985 " The grepprg may not be set on non-Unix systems 1986 return 1987 endif 1988 1989 call s:test_xgrep('c') 1990 call s:test_xgrep('l') 1991endfunc 1992 1993func Test_two_windows() 1994 " Use one 'errorformat' for two windows. Add an expression to each of them, 1995 " make sure they each keep their own state. 1996 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 1997 call mkdir('Xone/a', 'p') 1998 call mkdir('Xtwo/a', 'p') 1999 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2000 call writefile(lines, 'Xone/a/one.txt') 2001 call writefile(lines, 'Xtwo/a/two.txt') 2002 2003 new one 2004 let one_id = win_getid() 2005 lexpr "" 2006 new two 2007 let two_id = win_getid() 2008 lexpr "" 2009 2010 laddexpr "Entering dir 'Xtwo/a'" 2011 call win_gotoid(one_id) 2012 laddexpr "Entering dir 'Xone/a'" 2013 call win_gotoid(two_id) 2014 laddexpr 'two.txt:5:two two two' 2015 call win_gotoid(one_id) 2016 laddexpr 'one.txt:3:one one one' 2017 2018 let loc_one = getloclist(one_id) 2019 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr)) 2020 call assert_equal(3, loc_one[1].lnum) 2021 2022 let loc_two = getloclist(two_id) 2023 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr)) 2024 call assert_equal(5, loc_two[1].lnum) 2025 2026 call win_gotoid(one_id) 2027 bwipe! 2028 call win_gotoid(two_id) 2029 bwipe! 2030 call delete('Xone', 'rf') 2031 call delete('Xtwo', 'rf') 2032endfunc 2033 2034func XbottomTests(cchar) 2035 call s:setup_commands(a:cchar) 2036 2037 " Calling lbottom without any errors should fail 2038 if a:cchar == 'l' 2039 call assert_fails('lbottom', 'E776:') 2040 endif 2041 2042 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) 2043 Xopen 2044 let wid = win_getid() 2045 call assert_equal(1, line('.')) 2046 wincmd w 2047 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a') 2048 Xbottom 2049 call win_gotoid(wid) 2050 call assert_equal(2, line('.')) 2051 Xclose 2052endfunc 2053 2054" Tests for the :cbottom and :lbottom commands 2055func Test_cbottom() 2056 call XbottomTests('c') 2057 call XbottomTests('l') 2058endfunc 2059 2060func HistoryTest(cchar) 2061 call s:setup_commands(a:cchar) 2062 2063 " clear all lists after the first one, then replace the first one. 2064 call g:Xsetlist([]) 2065 call assert_fails('Xolder 99', 'E380:') 2066 let entry = {'filename': 'foo', 'lnum': 42} 2067 call g:Xsetlist([entry], 'r') 2068 call g:Xsetlist([entry, entry]) 2069 call g:Xsetlist([entry, entry, entry]) 2070 let res = split(execute(a:cchar . 'hist'), "\n") 2071 call assert_equal(3, len(res)) 2072 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()' 2073 call assert_equal(' error list 1 of 3; 1 ' . common, res[0]) 2074 call assert_equal(' error list 2 of 3; 2 ' . common, res[1]) 2075 call assert_equal('> error list 3 of 3; 3 ' . common, res[2]) 2076 2077 " Test for changing the quickfix lists 2078 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr) 2079 exe '1' . a:cchar . 'hist' 2080 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr) 2081 exe '3' . a:cchar . 'hist' 2082 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr) 2083 call assert_fails('-2' . a:cchar . 'hist', 'E16:') 2084 call assert_fails('4' . a:cchar . 'hist', 'E16:') 2085 2086 call g:Xsetlist([], 'f') 2087 let l = split(execute(a:cchar . 'hist'), "\n") 2088 call assert_equal('No entries', l[0]) 2089 if a:cchar == 'c' 2090 call assert_fails('4chist', 'E16:') 2091 else 2092 call assert_fails('4lhist', 'E776:') 2093 endif 2094 2095 " An empty list should still show the stack history 2096 call g:Xsetlist([]) 2097 let res = split(execute(a:cchar . 'hist'), "\n") 2098 call assert_equal('> error list 1 of 1; 0 ' . common, res[0]) 2099 2100 call g:Xsetlist([], 'f') 2101endfunc 2102 2103func Test_history() 2104 call HistoryTest('c') 2105 call HistoryTest('l') 2106endfunc 2107 2108func Test_duplicate_buf() 2109 " make sure we can get the highest buffer number 2110 edit DoesNotExist 2111 edit DoesNotExist2 2112 let last_buffer = bufnr("$") 2113 2114 " make sure only one buffer is created 2115 call writefile(['this one', 'that one'], 'Xgrepthis') 2116 vimgrep one Xgrepthis 2117 vimgrep one Xgrepthis 2118 call assert_equal(last_buffer + 1, bufnr("$")) 2119 2120 call delete('Xgrepthis') 2121endfunc 2122 2123" Quickfix/Location list set/get properties tests 2124func Xproperty_tests(cchar) 2125 call s:setup_commands(a:cchar) 2126 2127 " Error cases 2128 call assert_fails('call g:Xgetlist(99)', 'E715:') 2129 call assert_fails('call g:Xsetlist(99)', 'E714:') 2130 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:') 2131 2132 " Set and get the title 2133 call g:Xsetlist([]) 2134 Xopen 2135 wincmd p 2136 call g:Xsetlist([{'filename':'foo', 'lnum':27}]) 2137 let s = g:Xsetlist([], 'a', {'title' : 'Sample'}) 2138 call assert_equal(0, s) 2139 let d = g:Xgetlist({"title":1}) 2140 call assert_equal('Sample', d.title) 2141 " Try setting title to a non-string value 2142 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']})) 2143 call assert_equal('Sample', g:Xgetlist({"title":1}).title) 2144 2145 Xopen 2146 call assert_equal('Sample', w:quickfix_title) 2147 Xclose 2148 2149 " Tests for action argument 2150 silent! Xolder 999 2151 let qfnr = g:Xgetlist({'all':1}).nr 2152 call g:Xsetlist([], 'r', {'title' : 'N1'}) 2153 call assert_equal('N1', g:Xgetlist({'all':1}).title) 2154 call g:Xsetlist([], ' ', {'title' : 'N2'}) 2155 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr) 2156 2157 let res = g:Xgetlist({'nr': 0}) 2158 call assert_equal(qfnr + 1, res.nr) 2159 call assert_equal(['nr'], keys(res)) 2160 2161 call g:Xsetlist([], ' ', {'title' : 'N3'}) 2162 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) 2163 2164 " Changing the title of an earlier quickfix list 2165 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2}) 2166 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title) 2167 2168 " Changing the title of an invalid quickfix list 2169 call assert_equal(-1, g:Xsetlist([], ' ', 2170 \ {'title' : 'SomeTitle', 'nr' : 99})) 2171 call assert_equal(-1, g:Xsetlist([], ' ', 2172 \ {'title' : 'SomeTitle', 'nr' : 'abc'})) 2173 2174 if a:cchar == 'c' 2175 copen 2176 call assert_equal({'winid':win_getid()}, getqflist({'winid':1})) 2177 cclose 2178 endif 2179 2180 " Invalid arguments 2181 call assert_fails('call g:Xgetlist([])', 'E715') 2182 call assert_fails('call g:Xsetlist([], "a", [])', 'E715') 2183 let s = g:Xsetlist([], 'a', {'abc':1}) 2184 call assert_equal(-1, s) 2185 2186 call assert_equal({}, g:Xgetlist({'abc':1})) 2187 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title) 2188 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title) 2189 2190 if a:cchar == 'l' 2191 call assert_equal({}, getloclist(99, {'title': 1})) 2192 endif 2193 2194 " Context related tests 2195 let s = g:Xsetlist([], 'a', {'context':[1,2,3]}) 2196 call assert_equal(0, s) 2197 call test_garbagecollect_now() 2198 let d = g:Xgetlist({'context':1}) 2199 call assert_equal([1,2,3], d.context) 2200 call g:Xsetlist([], 'a', {'context':{'color':'green'}}) 2201 let d = g:Xgetlist({'context':1}) 2202 call assert_equal({'color':'green'}, d.context) 2203 call g:Xsetlist([], 'a', {'context':"Context info"}) 2204 let d = g:Xgetlist({'context':1}) 2205 call assert_equal("Context info", d.context) 2206 call g:Xsetlist([], 'a', {'context':246}) 2207 let d = g:Xgetlist({'context':1}) 2208 call assert_equal(246, d.context) 2209 " set other Vim data types as context 2210 call g:Xsetlist([], 'a', {'context' : test_null_blob()}) 2211 if has('channel') 2212 call g:Xsetlist([], 'a', {'context' : test_null_channel()}) 2213 endif 2214 if has('job') 2215 call g:Xsetlist([], 'a', {'context' : test_null_job()}) 2216 endif 2217 call g:Xsetlist([], 'a', {'context' : test_null_function()}) 2218 call g:Xsetlist([], 'a', {'context' : test_null_partial()}) 2219 call g:Xsetlist([], 'a', {'context' : ''}) 2220 call test_garbagecollect_now() 2221 if a:cchar == 'l' 2222 " Test for copying context across two different location lists 2223 new | only 2224 let w1_id = win_getid() 2225 let l = [1] 2226 call setloclist(0, [], 'a', {'context':l}) 2227 new 2228 let w2_id = win_getid() 2229 call add(l, 2) 2230 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context) 2231 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 2232 unlet! l 2233 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 2234 only 2235 call setloclist(0, [], 'f') 2236 call assert_equal('', getloclist(0, {'context':1}).context) 2237 endif 2238 2239 " Test for changing the context of previous quickfix lists 2240 call g:Xsetlist([], 'f') 2241 Xexpr "One" 2242 Xexpr "Two" 2243 Xexpr "Three" 2244 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1}) 2245 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2}) 2246 " Also, check for setting the context using quickfix list number zero. 2247 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0}) 2248 call test_garbagecollect_now() 2249 let l = g:Xgetlist({'nr' : 1, 'context' : 1}) 2250 call assert_equal([1], l.context) 2251 let l = g:Xgetlist({'nr' : 2, 'context' : 1}) 2252 call assert_equal([2], l.context) 2253 let l = g:Xgetlist({'nr' : 3, 'context' : 1}) 2254 call assert_equal([3], l.context) 2255 2256 " Test for changing the context through reference and for garbage 2257 " collection of quickfix context 2258 let l = ["red"] 2259 call g:Xsetlist([], ' ', {'context' : l}) 2260 call add(l, "blue") 2261 let x = g:Xgetlist({'context' : 1}) 2262 call add(x.context, "green") 2263 call assert_equal(["red", "blue", "green"], l) 2264 call assert_equal(["red", "blue", "green"], x.context) 2265 unlet l 2266 call test_garbagecollect_now() 2267 let m = g:Xgetlist({'context' : 1}) 2268 call assert_equal(["red", "blue", "green"], m.context) 2269 2270 " Test for setting/getting items 2271 Xexpr "" 2272 let qfprev = g:Xgetlist({'nr':0}) 2273 let s = g:Xsetlist([], ' ', {'title':'Green', 2274 \ 'items' : [{'filename':'F1', 'lnum':10}]}) 2275 call assert_equal(0, s) 2276 let qfcur = g:Xgetlist({'nr':0}) 2277 call assert_true(qfcur.nr == qfprev.nr + 1) 2278 let l = g:Xgetlist({'items':1}) 2279 call assert_equal('F1', bufname(l.items[0].bufnr)) 2280 call assert_equal(10, l.items[0].lnum) 2281 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20}, 2282 \ {'filename':'F2', 'lnum':30}]}) 2283 let l = g:Xgetlist({'items':1}) 2284 call assert_equal('F2', bufname(l.items[2].bufnr)) 2285 call assert_equal(30, l.items[2].lnum) 2286 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]}) 2287 let l = g:Xgetlist({'items':1}) 2288 call assert_equal('F3', bufname(l.items[0].bufnr)) 2289 call assert_equal(40, l.items[0].lnum) 2290 call g:Xsetlist([], 'r', {'items' : []}) 2291 let l = g:Xgetlist({'items':1}) 2292 call assert_equal(0, len(l.items)) 2293 2294 call g:Xsetlist([], 'r', {'title' : 'TestTitle'}) 2295 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 2296 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 2297 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title) 2298 2299 " Test for getting id of window associated with a location list window 2300 if a:cchar == 'l' 2301 only 2302 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid) 2303 let wid = win_getid() 2304 Xopen 2305 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid) 2306 wincmd w 2307 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid) 2308 only 2309 endif 2310 2311 " The following used to crash Vim with address sanitizer 2312 call g:Xsetlist([], 'f') 2313 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) 2314 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) 2315 2316 " Try setting the items using a string 2317 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'})) 2318 2319 " Save and restore the quickfix stack 2320 call g:Xsetlist([], 'f') 2321 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2322 Xexpr "File1:10:Line1" 2323 Xexpr "File2:20:Line2" 2324 Xexpr "File3:30:Line3" 2325 let last_qf = g:Xgetlist({'nr':'$'}).nr 2326 call assert_equal(3, last_qf) 2327 let qstack = [] 2328 for i in range(1, last_qf) 2329 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1})) 2330 endfor 2331 call g:Xsetlist([], 'f') 2332 for i in range(len(qstack)) 2333 call g:Xsetlist([], ' ', qstack[i]) 2334 endfor 2335 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2336 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum) 2337 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum) 2338 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum) 2339 call g:Xsetlist([], 'f') 2340 2341 " Swap two quickfix lists 2342 Xexpr "File1:10:Line10" 2343 Xexpr "File2:20:Line20" 2344 Xexpr "File3:30:Line30" 2345 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']}) 2346 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) 2347 let l1=g:Xgetlist({'nr':1,'all':1}) 2348 let l2=g:Xgetlist({'nr':2,'all':1}) 2349 let save_id = l1.id 2350 let l1.id=l2.id 2351 let l2.id=save_id 2352 call g:Xsetlist([], 'r', l1) 2353 call g:Xsetlist([], 'r', l2) 2354 let newl1=g:Xgetlist({'nr':1,'all':1}) 2355 let newl2=g:Xgetlist({'nr':2,'all':1}) 2356 call assert_equal('Fruits', newl1.title) 2357 call assert_equal(['Fruits'], newl1.context) 2358 call assert_equal('Line20', newl1.items[0].text) 2359 call assert_equal('Colors', newl2.title) 2360 call assert_equal(['Colors'], newl2.context) 2361 call assert_equal('Line10', newl2.items[0].text) 2362 call g:Xsetlist([], 'f') 2363 2364 " Cannot specify both a non-empty list argument and a dict argument 2365 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:') 2366endfunc 2367 2368func Test_qf_property() 2369 call Xproperty_tests('c') 2370 call Xproperty_tests('l') 2371endfunc 2372 2373" Test for setting the current index in the location/quickfix list 2374func Xtest_setqfidx(cchar) 2375 call s:setup_commands(a:cchar) 2376 2377 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3" 2378 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3" 2379 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3" 2380 2381 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2}) 2382 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2}) 2383 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3}) 2384 Xolder 2 2385 Xopen 2386 call assert_equal(3, line('.')) 2387 Xnewer 2388 call assert_equal(2, line('.')) 2389 Xnewer 2390 call assert_equal(2, line('.')) 2391 " Update the current index with the quickfix window open 2392 wincmd w 2393 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3}) 2394 Xopen 2395 call assert_equal(3, line('.')) 2396 Xclose 2397 2398 " Set the current index to the last entry 2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'}) 2400 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2401 " A large value should set the index to the last index 2402 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1}) 2403 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999}) 2404 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2405 " Invalid index values 2406 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1}) 2407 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2408 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0}) 2409 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2410 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'}) 2411 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2412 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:') 2413 2414 call g:Xsetlist([], 'f') 2415 new | only 2416endfunc 2417 2418func Test_setqfidx() 2419 call Xtest_setqfidx('c') 2420 call Xtest_setqfidx('l') 2421endfunc 2422 2423" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands 2424func QfAutoCmdHandler(loc, cmd) 2425 call add(g:acmds, a:loc . a:cmd) 2426endfunc 2427 2428func Test_Autocmd() 2429 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) 2430 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) 2431 2432 let g:acmds = [] 2433 cexpr "F1:10:Line 10" 2434 caddexpr "F1:20:Line 20" 2435 cgetexpr "F1:30:Line 30" 2436 cexpr "" 2437 caddexpr "" 2438 cgetexpr "" 2439 silent! cexpr non_existing_func() 2440 silent! caddexpr non_existing_func() 2441 silent! cgetexpr non_existing_func() 2442 let l = ['precexpr', 2443 \ 'postcexpr', 2444 \ 'precaddexpr', 2445 \ 'postcaddexpr', 2446 \ 'precgetexpr', 2447 \ 'postcgetexpr', 2448 \ 'precexpr', 2449 \ 'postcexpr', 2450 \ 'precaddexpr', 2451 \ 'postcaddexpr', 2452 \ 'precgetexpr', 2453 \ 'postcgetexpr', 2454 \ 'precexpr', 2455 \ 'precaddexpr', 2456 \ 'precgetexpr'] 2457 call assert_equal(l, g:acmds) 2458 2459 let g:acmds = [] 2460 enew! | call append(0, "F2:10:Line 10") 2461 cbuffer! 2462 enew! | call append(0, "F2:20:Line 20") 2463 cgetbuffer 2464 enew! | call append(0, "F2:30:Line 30") 2465 caddbuffer 2466 new 2467 let bnum = bufnr('%') 2468 bunload 2469 exe 'silent! cbuffer! ' . bnum 2470 exe 'silent! cgetbuffer ' . bnum 2471 exe 'silent! caddbuffer ' . bnum 2472 enew! 2473 let l = ['precbuffer', 2474 \ 'postcbuffer', 2475 \ 'precgetbuffer', 2476 \ 'postcgetbuffer', 2477 \ 'precaddbuffer', 2478 \ 'postcaddbuffer', 2479 \ 'precbuffer', 2480 \ 'precgetbuffer', 2481 \ 'precaddbuffer'] 2482 call assert_equal(l, g:acmds) 2483 2484 call writefile(['Xtest:1:Line1'], 'Xtest') 2485 call writefile([], 'Xempty') 2486 let g:acmds = [] 2487 cfile Xtest 2488 caddfile Xtest 2489 cgetfile Xtest 2490 cfile Xempty 2491 caddfile Xempty 2492 cgetfile Xempty 2493 silent! cfile do_not_exist 2494 silent! caddfile do_not_exist 2495 silent! cgetfile do_not_exist 2496 let l = ['precfile', 2497 \ 'postcfile', 2498 \ 'precaddfile', 2499 \ 'postcaddfile', 2500 \ 'precgetfile', 2501 \ 'postcgetfile', 2502 \ 'precfile', 2503 \ 'postcfile', 2504 \ 'precaddfile', 2505 \ 'postcaddfile', 2506 \ 'precgetfile', 2507 \ 'postcgetfile', 2508 \ 'precfile', 2509 \ 'postcfile', 2510 \ 'precaddfile', 2511 \ 'postcaddfile', 2512 \ 'precgetfile', 2513 \ 'postcgetfile'] 2514 call assert_equal(l, g:acmds) 2515 2516 let g:acmds = [] 2517 helpgrep quickfix 2518 silent! helpgrep non_existing_help_topic 2519 vimgrep test Xtest 2520 vimgrepadd test Xtest 2521 silent! vimgrep non_existing_test Xtest 2522 silent! vimgrepadd non_existing_test Xtest 2523 set makeprg= 2524 silent! make 2525 set makeprg& 2526 let l = ['prehelpgrep', 2527 \ 'posthelpgrep', 2528 \ 'prehelpgrep', 2529 \ 'posthelpgrep', 2530 \ 'previmgrep', 2531 \ 'postvimgrep', 2532 \ 'previmgrepadd', 2533 \ 'postvimgrepadd', 2534 \ 'previmgrep', 2535 \ 'postvimgrep', 2536 \ 'previmgrepadd', 2537 \ 'postvimgrepadd', 2538 \ 'premake', 2539 \ 'postmake'] 2540 call assert_equal(l, g:acmds) 2541 2542 if has('unix') 2543 " Run this test only on Unix-like systems. The grepprg may not be set on 2544 " non-Unix systems. 2545 " The following lines are used for the grep test. Don't remove. 2546 " Grep_Autocmd_Text: Match 1 2547 " GrepAdd_Autocmd_Text: Match 2 2548 let g:acmds = [] 2549 silent grep Grep_Autocmd_Text test_quickfix.vim 2550 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2551 silent grep abc123def Xtest 2552 silent grepadd abc123def Xtest 2553 set grepprg=internal 2554 silent grep Grep_Autocmd_Text test_quickfix.vim 2555 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2556 silent lgrep Grep_Autocmd_Text test_quickfix.vim 2557 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim 2558 set grepprg&vim 2559 let l = ['pregrep', 2560 \ 'postgrep', 2561 \ 'pregrepadd', 2562 \ 'postgrepadd', 2563 \ 'pregrep', 2564 \ 'postgrep', 2565 \ 'pregrepadd', 2566 \ 'postgrepadd', 2567 \ 'pregrep', 2568 \ 'postgrep', 2569 \ 'pregrepadd', 2570 \ 'postgrepadd', 2571 \ 'prelgrep', 2572 \ 'postlgrep', 2573 \ 'prelgrepadd', 2574 \ 'postlgrepadd'] 2575 call assert_equal(l, g:acmds) 2576 endif 2577 2578 call delete('Xtest') 2579 call delete('Xempty') 2580 au! QuickFixCmdPre 2581 au! QuickFixCmdPost 2582endfunc 2583 2584func Test_Autocmd_Exception() 2585 set efm=%m 2586 lgetexpr '?' 2587 2588 try 2589 call DoesNotExit() 2590 catch 2591 lgetexpr '1' 2592 finally 2593 lgetexpr '1' 2594 endtry 2595 2596 call assert_equal('1', getloclist(0)[0].text) 2597 2598 set efm&vim 2599endfunc 2600 2601func Test_caddbuffer_wrong() 2602 " This used to cause a memory access in freed memory. 2603 let save_efm = &efm 2604 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2605 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2606 let &efm = save_efm 2607 caddbuffer 2608 bwipe! 2609endfunc 2610 2611func Test_caddexpr_wrong() 2612 " This used to cause a memory access in freed memory. 2613 cbuffer 2614 cbuffer 2615 copen 2616 let save_efm = &efm 2617 set efm=% 2618 call assert_fails('caddexpr ""', 'E376:') 2619 let &efm = save_efm 2620endfunc 2621 2622func Test_dirstack_cleanup() 2623 " This used to cause a memory access in freed memory. 2624 let save_efm = &efm 2625 lexpr '0' 2626 lopen 2627 fun X(c) 2628 let save_efm=&efm 2629 set efm=%D%f 2630 if a:c == 'c' 2631 caddexpr '::' 2632 else 2633 laddexpr ':0:0' 2634 endif 2635 let &efm=save_efm 2636 endfun 2637 call X('c') 2638 call X('l') 2639 call setqflist([], 'r') 2640 caddbuffer 2641 let &efm = save_efm 2642endfunc 2643 2644" Tests for jumping to entries from the location list window and quickfix 2645" window 2646func Test_cwindow_jump() 2647 set efm=%f%%%l%%%m 2648 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2649 lopen | only 2650 lfirst 2651 call assert_true(winnr('$') == 2) 2652 call assert_true(winnr() == 1) 2653 " Location list for the new window should be set 2654 call assert_true(getloclist(0)[2].text == 'Line 30') 2655 2656 " Open a scratch buffer 2657 " Open a new window and create a location list 2658 " Open the location list window and close the other window 2659 " Jump to an entry. 2660 " Should create a new window and jump to the entry. The scratch buffer 2661 " should not be used. 2662 enew | only 2663 set buftype=nofile 2664 below new 2665 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2666 lopen 2667 2wincmd c 2668 lnext 2669 call assert_true(winnr('$') == 3) 2670 call assert_true(winnr() == 2) 2671 2672 " Open two windows with two different location lists 2673 " Open the location list window and close the previous window 2674 " Jump to an entry in the location list window 2675 " Should open the file in the first window and not set the location list. 2676 enew | only 2677 lgetexpr ["F1%5%Line 5"] 2678 below new 2679 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2680 lopen 2681 2wincmd c 2682 lnext 2683 call assert_true(winnr() == 1) 2684 call assert_true(getloclist(0)[0].text == 'Line 5') 2685 2686 enew | only 2687 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2688 copen 2689 cnext 2690 call assert_true(winnr('$') == 2) 2691 call assert_true(winnr() == 1) 2692 2693 " open the quickfix buffer in two windows and jump to an entry. Should open 2694 " the file in the first quickfix window. 2695 enew | only 2696 copen 2697 let bnum = bufnr('') 2698 exe 'sbuffer ' . bnum 2699 wincmd b 2700 cfirst 2701 call assert_equal(2, winnr()) 2702 call assert_equal('F1', @%) 2703 enew | only 2704 exe 'sb' bnum 2705 exe 'botright sb' bnum 2706 wincmd t 2707 clast 2708 call assert_equal(2, winnr()) 2709 call assert_equal('quickfix', getwinvar(1, '&buftype')) 2710 call assert_equal('quickfix', getwinvar(3, '&buftype')) 2711 2712 " Jumping to a file from the location list window should find a usable 2713 " window by wrapping around the window list. 2714 enew | only 2715 call setloclist(0, [], 'f') 2716 new | new 2717 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2718 lopen 2719 1close 2720 call assert_equal(0, getloclist(3, {'id' : 0}).id) 2721 lnext 2722 call assert_equal(3, winnr()) 2723 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id) 2724 2725 enew | only 2726 set efm&vim 2727endfunc 2728 2729func Test_cwindow_highlight() 2730 CheckScreendump 2731 2732 let lines =<< trim END 2733 call setline(1, ['some', 'text', 'with', 'matches']) 2734 write XCwindow 2735 vimgrep e XCwindow 2736 redraw 2737 cwindow 4 2738 END 2739 call writefile(lines, 'XtestCwindow') 2740 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12}) 2741 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {}) 2742 2743 call term_sendkeys(buf, ":cnext\<CR>") 2744 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {}) 2745 2746 " clean up 2747 call StopVimInTerminal(buf) 2748 call delete('XtestCwindow') 2749 call delete('XCwindow') 2750endfunc 2751 2752func XvimgrepTests(cchar) 2753 call s:setup_commands(a:cchar) 2754 2755 call writefile(['Editor:VIM vim', 2756 \ 'Editor:Emacs EmAcS', 2757 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2758 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2759 2760 " Error cases 2761 call assert_fails('Xvimgrep /abc *', 'E682:') 2762 2763 let @/='' 2764 call assert_fails('Xvimgrep // *', 'E35:') 2765 2766 call assert_fails('Xvimgrep abc', 'E683:') 2767 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2768 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2769 2770 Xexpr "" 2771 Xvimgrepadd Notepad Xtestfile1 2772 Xvimgrepadd MacOS Xtestfile2 2773 let l = g:Xgetlist() 2774 call assert_equal(2, len(l)) 2775 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2776 2777 10Xvimgrep #\cvim#g Xtestfile? 2778 let l = g:Xgetlist() 2779 call assert_equal(2, len(l)) 2780 call assert_equal(8, l[0].col) 2781 call assert_equal(12, l[1].col) 2782 2783 1Xvimgrep ?Editor? Xtestfile* 2784 let l = g:Xgetlist() 2785 call assert_equal(1, len(l)) 2786 call assert_equal('Editor:VIM vim', l[0].text) 2787 2788 edit +3 Xtestfile2 2789 Xvimgrep +\cemacs+j Xtestfile1 2790 let l = g:Xgetlist() 2791 call assert_equal('Xtestfile2', @%) 2792 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2793 2794 " Test for unloading a buffer after vimgrep searched the buffer 2795 %bwipe 2796 Xvimgrep /Editor/j Xtestfile* 2797 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded) 2798 call assert_equal([], getbufinfo('Xtestfile2')) 2799 2800 call delete('Xtestfile1') 2801 call delete('Xtestfile2') 2802endfunc 2803 2804" Tests for the :vimgrep command 2805func Test_vimgrep() 2806 call XvimgrepTests('c') 2807 call XvimgrepTests('l') 2808endfunc 2809 2810" Test for incsearch highlighting of the :vimgrep pattern 2811" This test used to cause "E315: ml_get: invalid lnum" errors. 2812func Test_vimgrep_incsearch() 2813 enew 2814 set incsearch 2815 call test_override("char_avail", 1) 2816 2817 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx") 2818 let l = getqflist() 2819 call assert_equal(2, len(l)) 2820 2821 call test_override("ALL", 0) 2822 set noincsearch 2823endfunc 2824 2825" Test vimgrep with the last search pattern not set 2826func Test_vimgrep_with_no_last_search_pat() 2827 let lines =<< trim [SCRIPT] 2828 call assert_fails('vimgrep // *', 'E35:') 2829 call writefile(v:errors, 'Xresult') 2830 qall! 2831 [SCRIPT] 2832 call writefile(lines, 'Xscript') 2833 if RunVim([], [], '--clean -S Xscript') 2834 call assert_equal([], readfile('Xresult')) 2835 endif 2836 call delete('Xscript') 2837 call delete('Xresult') 2838endfunc 2839 2840func Test_vimgrep_existing_swapfile() 2841 call writefile(['match apple with apple'], 'Xapple') 2842 call writefile(['swapfile'], '.Xapple.swp') 2843 let g:foundSwap = 0 2844 let g:ignoreSwapExists = 1 2845 augroup grep 2846 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e' 2847 augroup END 2848 vimgrep apple Xapple 2849 call assert_equal(1, g:foundSwap) 2850 call assert_match('.Xapple.swo', swapname('')) 2851 2852 call delete('Xapple') 2853 call delete('Xapple.swp') 2854 augroup grep 2855 au! SwapExists 2856 augroup END 2857 unlet g:ignoreSwapExists 2858endfunc 2859 2860func XfreeTests(cchar) 2861 call s:setup_commands(a:cchar) 2862 2863 enew | only 2864 2865 " Deleting the quickfix stack should work even When the current list is 2866 " somewhere in the middle of the stack 2867 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2868 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2869 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2870 Xolder 2871 call g:Xsetlist([], 'f') 2872 call assert_equal(0, len(g:Xgetlist())) 2873 2874 " After deleting the stack, adding a new list should create a stack with a 2875 " single list. 2876 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2877 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2878 2879 " Deleting the stack from a quickfix window should update/clear the 2880 " quickfix/location list window. 2881 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2882 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2883 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2884 Xolder 2885 Xwindow 2886 call g:Xsetlist([], 'f') 2887 call assert_equal(2, winnr('$')) 2888 call assert_equal(1, line('$')) 2889 Xclose 2890 2891 " Deleting the stack from a non-quickfix window should update/clear the 2892 " quickfix/location list window. 2893 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2894 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2895 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2896 Xolder 2897 Xwindow 2898 wincmd p 2899 call g:Xsetlist([], 'f') 2900 call assert_equal(0, len(g:Xgetlist())) 2901 wincmd p 2902 call assert_equal(2, winnr('$')) 2903 call assert_equal(1, line('$')) 2904 2905 " After deleting the location list stack, if the location list window is 2906 " opened, then a new location list should be created. So opening the 2907 " location list window again should not create a new window. 2908 if a:cchar == 'l' 2909 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2910 wincmd p 2911 lopen 2912 call assert_equal(2, winnr('$')) 2913 endif 2914 Xclose 2915endfunc 2916 2917" Tests for the quickfix free functionality 2918func Test_qf_free() 2919 call XfreeTests('c') 2920 call XfreeTests('l') 2921endfunc 2922 2923" Test for buffer overflow when parsing lines and adding new entries to 2924" the quickfix list. 2925func Test_bufoverflow() 2926 set efm=%f:%l:%m 2927 cgetexpr ['File1:100:' . repeat('x', 1025)] 2928 2929 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2930 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2931 2932 set efm=%DEntering\ directory\ %f,%f:%l:%m 2933 cgetexpr ['Entering directory ' . repeat('a', 1006), 2934 \ 'File1:10:Hello World'] 2935 set efm&vim 2936endfunc 2937 2938" Tests for getting the quickfix stack size 2939func XsizeTests(cchar) 2940 call s:setup_commands(a:cchar) 2941 2942 call g:Xsetlist([], 'f') 2943 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2944 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title) 2945 call assert_equal(0, g:Xgetlist({'nr':0}).nr) 2946 2947 Xexpr "File1:10:Line1" 2948 Xexpr "File2:20:Line2" 2949 Xexpr "File3:30:Line3" 2950 Xolder | Xolder 2951 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2952 call g:Xsetlist([], 'f') 2953 2954 Xexpr "File1:10:Line1" 2955 Xexpr "File2:20:Line2" 2956 Xexpr "File3:30:Line3" 2957 Xolder | Xolder 2958 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2959 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2960endfunc 2961 2962func Test_Qf_Size() 2963 call XsizeTests('c') 2964 call XsizeTests('l') 2965endfunc 2966 2967func Test_cclose_from_copen() 2968 augroup QF_Test 2969 au! 2970 au FileType qf :call assert_fails(':cclose', 'E788') 2971 augroup END 2972 copen 2973 augroup QF_Test 2974 au! 2975 augroup END 2976 augroup! QF_Test 2977endfunc 2978 2979func Test_cclose_in_autocmd() 2980 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2981 " event will be triggered. 2982 call test_override('starting', 1) 2983 augroup QF_Test 2984 au! 2985 au FileType qf :call assert_fails(':cclose', 'E788') 2986 augroup END 2987 copen 2988 augroup QF_Test 2989 au! 2990 augroup END 2991 augroup! QF_Test 2992 call test_override('starting', 0) 2993endfunc 2994 2995" Check that ":file" without an argument is possible even when "curbuf_lock" 2996" is set. 2997func Test_file_from_copen() 2998 " Works without argument. 2999 augroup QF_Test 3000 au! 3001 au FileType qf file 3002 augroup END 3003 copen 3004 3005 augroup QF_Test 3006 au! 3007 augroup END 3008 cclose 3009 3010 " Fails with argument. 3011 augroup QF_Test 3012 au! 3013 au FileType qf call assert_fails(':file foo', 'E788') 3014 augroup END 3015 copen 3016 augroup QF_Test 3017 au! 3018 augroup END 3019 cclose 3020 3021 augroup! QF_Test 3022endfunc 3023 3024func Test_resize_from_copen() 3025 augroup QF_Test 3026 au! 3027 au FileType qf resize 5 3028 augroup END 3029 try 3030 " This should succeed without any exception. No other buffers are 3031 " involved in the autocmd. 3032 copen 3033 finally 3034 augroup QF_Test 3035 au! 3036 augroup END 3037 augroup! QF_Test 3038 endtry 3039endfunc 3040 3041" Tests for the quickfix buffer b:changedtick variable 3042func Xchangedtick_tests(cchar) 3043 call s:setup_commands(a:cchar) 3044 3045 new | only 3046 3047 Xexpr "" | Xexpr "" | Xexpr "" 3048 3049 Xopen 3050 Xolder 3051 Xolder 3052 Xaddexpr "F1:10:Line10" 3053 Xaddexpr "F2:20:Line20" 3054 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 3055 call g:Xsetlist([], 'f') 3056 call assert_equal(8, getbufvar('%', 'changedtick')) 3057 Xclose 3058endfunc 3059 3060func Test_changedtick() 3061 call Xchangedtick_tests('c') 3062 call Xchangedtick_tests('l') 3063endfunc 3064 3065" Tests for parsing an expression using setqflist() 3066func Xsetexpr_tests(cchar) 3067 call s:setup_commands(a:cchar) 3068 3069 let t = ["File1:10:Line10", "File1:20:Line20"] 3070 call g:Xsetlist([], ' ', {'lines' : t}) 3071 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 3072 3073 let l = g:Xgetlist() 3074 call assert_equal(3, len(l)) 3075 call assert_equal(20, l[1].lnum) 3076 call assert_equal('Line30', l[2].text) 3077 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 3078 let l = g:Xgetlist() 3079 call assert_equal(1, len(l)) 3080 call assert_equal('Line5', l[0].text) 3081 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 3082 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 3083 3084 call g:Xsetlist([], 'f') 3085 " Add entries to multiple lists 3086 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 3087 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 3088 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 3089 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 3090 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 3091 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 3092 3093 " Adding entries using a custom efm 3094 set efm& 3095 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 3096 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 3097 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 3098 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 3099 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 3100 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 3101 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 3102 \ 'lines' : ['F1:10:L10']})) 3103endfunc 3104 3105func Test_setexpr() 3106 call Xsetexpr_tests('c') 3107 call Xsetexpr_tests('l') 3108endfunc 3109 3110" Tests for per quickfix/location list directory stack 3111func Xmultidirstack_tests(cchar) 3112 call s:setup_commands(a:cchar) 3113 3114 call g:Xsetlist([], 'f') 3115 Xexpr "" | Xexpr "" 3116 3117 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 3118 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 3119 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 3120 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 3121 3122 let l1 = g:Xgetlist({'nr':1, 'items':1}) 3123 let l2 = g:Xgetlist({'nr':2, 'items':1}) 3124 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 3125 call assert_equal(3, l1.items[1].lnum) 3126 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 3127 call assert_equal(5, l2.items[1].lnum) 3128endfunc 3129 3130func Test_multidirstack() 3131 call mkdir('Xone/a', 'p') 3132 call mkdir('Xtwo/a', 'p') 3133 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 3134 call writefile(lines, 'Xone/a/one.txt') 3135 call writefile(lines, 'Xtwo/a/two.txt') 3136 let save_efm = &efm 3137 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 3138 3139 call Xmultidirstack_tests('c') 3140 call Xmultidirstack_tests('l') 3141 3142 let &efm = save_efm 3143 call delete('Xone', 'rf') 3144 call delete('Xtwo', 'rf') 3145endfunc 3146 3147" Tests for per quickfix/location list file stack 3148func Xmultifilestack_tests(cchar) 3149 call s:setup_commands(a:cchar) 3150 3151 call g:Xsetlist([], 'f') 3152 Xexpr "" | Xexpr "" 3153 3154 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 3155 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 3156 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 3157 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 3158 3159 let l1 = g:Xgetlist({'nr':1, 'items':1}) 3160 let l2 = g:Xgetlist({'nr':2, 'items':1}) 3161 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 3162 call assert_equal(3, l1.items[1].lnum) 3163 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 3164 call assert_equal(5, l2.items[1].lnum) 3165 3166 " Test for start of a new error line in the same line where a previous 3167 " error line ends with a file stack. 3168 let efm_val = 'Error\ l%l\ in\ %f,' 3169 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r' 3170 let l = g:Xgetlist({'lines' : [ 3171 \ '(one.txt', 3172 \ 'Error l4 in one.txt', 3173 \ ') (two.txt', 3174 \ 'Error l6 in two.txt', 3175 \ ')', 3176 \ 'Error l8 in one.txt' 3177 \ ], 'efm' : efm_val}) 3178 call assert_equal(3, len(l.items)) 3179 call assert_equal('one.txt', bufname(l.items[0].bufnr)) 3180 call assert_equal(4, l.items[0].lnum) 3181 call assert_equal('one.txt', l.items[0].text) 3182 call assert_equal('two.txt', bufname(l.items[1].bufnr)) 3183 call assert_equal(6, l.items[1].lnum) 3184 call assert_equal('two.txt', l.items[1].text) 3185 call assert_equal('one.txt', bufname(l.items[2].bufnr)) 3186 call assert_equal(8, l.items[2].lnum) 3187 call assert_equal('', l.items[2].text) 3188endfunc 3189 3190func Test_multifilestack() 3191 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 3192 call writefile(lines, 'one.txt') 3193 call writefile(lines, 'two.txt') 3194 let save_efm = &efm 3195 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 3196 3197 call Xmultifilestack_tests('c') 3198 call Xmultifilestack_tests('l') 3199 3200 let &efm = save_efm 3201 call delete('one.txt') 3202 call delete('two.txt') 3203endfunc 3204 3205" Tests for per buffer 'efm' setting 3206func Test_perbuf_efm() 3207 call writefile(["File1-10-Line10"], 'one.txt') 3208 call writefile(["File2#20#Line20"], 'two.txt') 3209 set efm=%f#%l#%m 3210 new | only 3211 new 3212 setlocal efm=%f-%l-%m 3213 cfile one.txt 3214 wincmd w 3215 caddfile two.txt 3216 3217 let l = getqflist() 3218 call assert_equal(10, l[0].lnum) 3219 call assert_equal('Line20', l[1].text) 3220 3221 set efm& 3222 new | only 3223 call delete('one.txt') 3224 call delete('two.txt') 3225endfunc 3226 3227" Open multiple help windows using ":lhelpgrep 3228" This test used to crash Vim 3229func Test_Multi_LL_Help() 3230 new | only 3231 lhelpgrep window 3232 lopen 3233 e# 3234 lhelpgrep buffer 3235 call assert_equal(3, winnr('$')) 3236 call assert_true(len(getloclist(1)) != 0) 3237 call assert_true(len(getloclist(2)) != 0) 3238 new | only 3239endfunc 3240 3241" Tests for adding new quickfix lists using setqflist() 3242func XaddQf_tests(cchar) 3243 call s:setup_commands(a:cchar) 3244 3245 " Create a new list using ' ' for action 3246 call g:Xsetlist([], 'f') 3247 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 3248 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3249 call assert_equal(1, l.nr) 3250 call assert_equal('Test1', l.title) 3251 3252 " Create a new list using ' ' for action and '$' for 'nr' 3253 call g:Xsetlist([], 'f') 3254 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 3255 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3256 call assert_equal(1, l.nr) 3257 call assert_equal('Test2', l.title) 3258 3259 " Create a new list using 'a' for action 3260 call g:Xsetlist([], 'f') 3261 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 3262 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3263 call assert_equal(1, l.nr) 3264 call assert_equal('Test3', l.title) 3265 3266 " Create a new list using 'a' for action and '$' for 'nr' 3267 call g:Xsetlist([], 'f') 3268 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 3269 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 3270 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3271 call assert_equal(1, l.nr) 3272 call assert_equal('Test4', l.title) 3273 3274 " Adding a quickfix list should remove all the lists following the current 3275 " list. 3276 Xexpr "" | Xexpr "" | Xexpr "" 3277 silent! 10Xolder 3278 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 3279 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3280 call assert_equal(2, l.nr) 3281 call assert_equal('Test5', l.title) 3282 3283 " Add a quickfix list using '$' as the list number. 3284 let lastqf = g:Xgetlist({'nr':'$'}).nr 3285 silent! 99Xolder 3286 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 3287 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3288 call assert_equal(lastqf + 1, l.nr) 3289 call assert_equal('Test6', l.title) 3290 3291 " Add a quickfix list using 'nr' set to one more than the quickfix 3292 " list size. 3293 let lastqf = g:Xgetlist({'nr':'$'}).nr 3294 silent! 99Xolder 3295 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 3296 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3297 call assert_equal(lastqf + 1, l.nr) 3298 call assert_equal('Test7', l.title) 3299 3300 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 3301 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 3302 silent! 99Xolder 3303 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 3304 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3305 call assert_equal(10, l.nr) 3306 call assert_equal('Test8', l.title) 3307 3308 " Add a quickfix list using 'nr' set to a value greater than 10 3309 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 3310 3311 " Try adding a quickfix list with 'nr' set to a value greater than the 3312 " quickfix list size but less than 10. 3313 call g:Xsetlist([], 'f') 3314 Xexpr "" | Xexpr "" | Xexpr "" 3315 silent! 99Xolder 3316 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 3317 3318 " Add a quickfix list using 'nr' set to a some string or list 3319 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 3320endfunc 3321 3322func Test_add_qf() 3323 call XaddQf_tests('c') 3324 call XaddQf_tests('l') 3325endfunc 3326 3327" Test for getting the quickfix list items from some text without modifying 3328" the quickfix stack 3329func XgetListFromLines(cchar) 3330 call s:setup_commands(a:cchar) 3331 call g:Xsetlist([], 'f') 3332 3333 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 3334 call assert_equal(2, len(l)) 3335 call assert_equal(30, l[1].lnum) 3336 3337 call assert_equal({}, g:Xgetlist({'lines' : 10})) 3338 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 3339 call assert_equal([], g:Xgetlist({'lines' : []}).items) 3340 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 3341 3342 " Parse text using a custom efm 3343 set efm& 3344 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 3345 call assert_equal('Line30', l[0].text) 3346 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 3347 call assert_equal('File3:30:Line30', l[0].text) 3348 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 3349 call assert_equal({}, l) 3350 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 3351 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 3352 3353 " Make sure that the quickfix stack is not modified 3354 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 3355endfunc 3356 3357func Test_get_list_from_lines() 3358 call XgetListFromLines('c') 3359 call XgetListFromLines('l') 3360endfunc 3361 3362" Tests for the quickfix list id 3363func Xqfid_tests(cchar) 3364 call s:setup_commands(a:cchar) 3365 3366 call g:Xsetlist([], 'f') 3367 call assert_equal(0, g:Xgetlist({'id':0}).id) 3368 Xexpr '' 3369 let start_id = g:Xgetlist({'id' : 0}).id 3370 Xexpr '' | Xexpr '' 3371 Xolder 3372 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 3373 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 3374 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 3375 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id) 3376 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 3377 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id) 3378 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id) 3379 3380 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 3381 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 3382 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 3383 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 3384 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 3385 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 3386 3387 let qfid = g:Xgetlist({'id':0, 'nr':0}) 3388 call g:Xsetlist([], 'f') 3389 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id) 3390endfunc 3391 3392func Test_qf_id() 3393 call Xqfid_tests('c') 3394 call Xqfid_tests('l') 3395endfunc 3396 3397func Xqfjump_tests(cchar) 3398 call s:setup_commands(a:cchar) 3399 3400 call writefile(["Line1\tFoo", "Line2"], 'F1') 3401 call writefile(["Line1\tBar", "Line2"], 'F2') 3402 call writefile(["Line1\tBaz", "Line2"], 'F3') 3403 3404 call g:Xsetlist([], 'f') 3405 3406 " Tests for 3407 " Jumping to a line using a pattern 3408 " Jumping to a column greater than the last column in a line 3409 " Jumping to a line greater than the last line in the file 3410 let l = [] 3411 for i in range(1, 7) 3412 call add(l, {}) 3413 endfor 3414 let l[0].filename='F1' 3415 let l[0].pattern='Line1' 3416 let l[1].filename='F2' 3417 let l[1].pattern='Line1' 3418 let l[2].filename='F3' 3419 let l[2].pattern='Line1' 3420 let l[3].filename='F3' 3421 let l[3].lnum=1 3422 let l[3].col=9 3423 let l[3].vcol=1 3424 let l[4].filename='F3' 3425 let l[4].lnum=99 3426 let l[5].filename='F3' 3427 let l[5].lnum=1 3428 let l[5].col=99 3429 let l[5].vcol=1 3430 let l[6].filename='F3' 3431 let l[6].pattern='abcxyz' 3432 3433 call g:Xsetlist([], ' ', {'items' : l}) 3434 Xopen | only 3435 2Xnext 3436 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 3437 call assert_equal('F3', @%) 3438 Xnext 3439 call assert_equal(7, col('.')) 3440 Xnext 3441 call assert_equal(2, line('.')) 3442 Xnext 3443 call assert_equal(9, col('.')) 3444 2 3445 Xnext 3446 call assert_equal(2, line('.')) 3447 3448 if a:cchar == 'l' 3449 " When jumping to a location list entry in the location list window and 3450 " no usable windows are available, then a new window should be opened. 3451 enew! | new | only 3452 call g:Xsetlist([], 'f') 3453 setlocal buftype=nofile 3454 new 3455 call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']}) 3456 Xopen 3457 let winid = win_getid() 3458 wincmd p 3459 close 3460 call win_gotoid(winid) 3461 Xnext 3462 call assert_equal(3, winnr('$')) 3463 call assert_equal(1, winnr()) 3464 call assert_equal(2, line('.')) 3465 3466 " When jumping to an entry in the location list window and the window 3467 " associated with the location list is not present and a window containing 3468 " the file is already present, then that window should be used. 3469 close 3470 belowright new 3471 call g:Xsetlist([], 'f') 3472 edit F3 3473 call win_gotoid(winid) 3474 Xlast 3475 call assert_equal(3, winnr()) 3476 call assert_equal(6, g:Xgetlist({'size' : 1}).size) 3477 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) 3478 endif 3479 3480 " Cleanup 3481 enew! 3482 new | only 3483 3484 call delete('F1') 3485 call delete('F2') 3486 call delete('F3') 3487endfunc 3488 3489func Test_qfjump() 3490 call Xqfjump_tests('c') 3491 call Xqfjump_tests('l') 3492endfunc 3493 3494" Tests for the getqflist() and getloclist() functions when the list is not 3495" present or is empty 3496func Xgetlist_empty_tests(cchar) 3497 call s:setup_commands(a:cchar) 3498 3499 " Empty quickfix stack 3500 call g:Xsetlist([], 'f') 3501 call assert_equal('', g:Xgetlist({'context' : 0}).context) 3502 call assert_equal(0, g:Xgetlist({'id' : 0}).id) 3503 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 3504 call assert_equal([], g:Xgetlist({'items' : 0}).items) 3505 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr) 3506 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 3507 call assert_equal('', g:Xgetlist({'title' : 0}).title) 3508 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 3509 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick) 3510 if a:cchar == 'c' 3511 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 3512 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0, 3513 \ 'title' : '', 'winid' : 0, 'changedtick': 0, 3514 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0})) 3515 else 3516 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 3517 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 3518 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0, 3519 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''}, 3520 \ g:Xgetlist({'all' : 0})) 3521 endif 3522 3523 " Quickfix window with empty stack 3524 silent! Xopen 3525 let qfwinid = (a:cchar == 'c') ? win_getid() : 0 3526 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0 3527 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid) 3528 Xclose 3529 3530 " Empty quickfix list 3531 Xexpr "" 3532 call assert_equal('', g:Xgetlist({'context' : 0}).context) 3533 call assert_notequal(0, g:Xgetlist({'id' : 0}).id) 3534 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 3535 call assert_equal([], g:Xgetlist({'items' : 0}).items) 3536 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr) 3537 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 3538 call assert_notequal('', g:Xgetlist({'title' : 0}).title) 3539 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 3540 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3541 3542 let qfid = g:Xgetlist({'id' : 0}).id 3543 call g:Xsetlist([], 'f') 3544 3545 " Non-existing quickfix identifier 3546 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context) 3547 call assert_equal(0, g:Xgetlist({'id' : qfid}).id) 3548 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx) 3549 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items) 3550 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr) 3551 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) 3552 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) 3553 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) 3554 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick) 3555 if a:cchar == 'c' 3556 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3557 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3558 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '', 3559 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) 3560 else 3561 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3562 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3563 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0, 3564 \ 'quickfixtextfunc' : ''}, 3565 \ g:Xgetlist({'id' : qfid, 'all' : 0})) 3566 endif 3567 3568 " Non-existing quickfix list number 3569 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) 3570 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr) 3571 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx) 3572 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items) 3573 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id) 3574 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) 3575 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) 3576 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) 3577 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick) 3578 if a:cchar == 'c' 3579 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3580 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3581 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr, 3582 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0})) 3583 else 3584 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3585 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3586 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0, 3587 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0})) 3588 endif 3589endfunc 3590 3591func Test_getqflist() 3592 call Xgetlist_empty_tests('c') 3593 call Xgetlist_empty_tests('l') 3594endfunc 3595 3596func Test_getqflist_invalid_nr() 3597 " The following commands used to crash Vim 3598 cexpr "" 3599 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) 3600 3601 " Cleanup 3602 call setqflist([], 'r') 3603endfunc 3604 3605" Tests for the quickfix/location list changedtick 3606func Xqftick_tests(cchar) 3607 call s:setup_commands(a:cchar) 3608 3609 call g:Xsetlist([], 'f') 3610 3611 Xexpr "F1:10:Line10" 3612 let qfid = g:Xgetlist({'id' : 0}).id 3613 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3614 Xaddexpr "F2:20:Line20\nF2:21:Line21" 3615 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3616 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]}) 3617 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick) 3618 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]}) 3619 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick) 3620 call g:Xsetlist([], 'a', {'title' : 'New Title'}) 3621 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick) 3622 3623 enew! 3624 call append(0, ["F5:50:L50", "F6:60:L60"]) 3625 Xaddbuffer 3626 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick) 3627 enew! 3628 3629 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}}) 3630 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick) 3631 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3632 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a') 3633 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick) 3634 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3635 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ') 3636 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3637 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3638 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r') 3639 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3640 3641 call writefile(["F8:80:L80", "F8:81:L81"], "Xone") 3642 Xfile Xone 3643 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3644 Xaddfile Xone 3645 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3646 3647 " Test case for updating a non-current quickfix list 3648 call g:Xsetlist([], 'f') 3649 Xexpr "F1:1:L1" 3650 Xexpr "F2:2:L2" 3651 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]}) 3652 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3653 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick) 3654 3655 call delete("Xone") 3656endfunc 3657 3658func Test_qf_tick() 3659 call Xqftick_tests('c') 3660 call Xqftick_tests('l') 3661endfunc 3662 3663" Test helpgrep with lang specifier 3664func Xtest_helpgrep_with_lang_specifier(cchar) 3665 call s:setup_commands(a:cchar) 3666 Xhelpgrep Vim@en 3667 call assert_equal('help', &filetype) 3668 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr) 3669 new | only 3670endfunc 3671 3672func Test_helpgrep_with_lang_specifier() 3673 call Xtest_helpgrep_with_lang_specifier('c') 3674 call Xtest_helpgrep_with_lang_specifier('l') 3675endfunc 3676 3677" The following test used to crash Vim. 3678" Open the location list window and close the regular window associated with 3679" the location list. When the garbage collection runs now, it incorrectly 3680" marks the location list context as not in use and frees the context. 3681func Test_ll_window_ctx() 3682 call setloclist(0, [], 'f') 3683 call setloclist(0, [], 'a', {'context' : []}) 3684 lopen | only 3685 call test_garbagecollect_now() 3686 echo getloclist(0, {'context' : 1}).context 3687 enew | only 3688endfunc 3689 3690" The following test used to crash vim 3691func Test_lfile_crash() 3692 sp Xtest 3693 au QuickFixCmdPre * bw 3694 call assert_fails('lfile', 'E40') 3695 au! QuickFixCmdPre 3696endfunc 3697 3698" The following test used to crash vim 3699func Test_lbuffer_crash() 3700 sv Xtest 3701 augroup QF_Test 3702 au! 3703 au * * bw 3704 augroup END 3705 lbuffer 3706 augroup QF_Test 3707 au! 3708 augroup END 3709endfunc 3710 3711" The following test used to crash vim 3712func Test_lexpr_crash() 3713 augroup QF_Test 3714 au! 3715 au * * call setloclist(0, [], 'f') 3716 augroup END 3717 lexpr "" 3718 augroup QF_Test 3719 au! 3720 augroup END 3721 3722 enew | only 3723 augroup QF_Test 3724 au! 3725 au BufNew * call setloclist(0, [], 'f') 3726 augroup END 3727 lexpr 'x:1:x' 3728 augroup QF_Test 3729 au! 3730 augroup END 3731 3732 enew | only 3733 lexpr '' 3734 lopen 3735 augroup QF_Test 3736 au! 3737 au FileType * call setloclist(0, [], 'f') 3738 augroup END 3739 lexpr '' 3740 augroup QF_Test 3741 au! 3742 augroup END 3743endfunc 3744 3745" The following test used to crash Vim 3746func Test_lvimgrep_crash() 3747 sv Xtest 3748 augroup QF_Test 3749 au! 3750 au * * call setloclist(0, [], 'f') 3751 augroup END 3752 lvimgrep quickfix test_quickfix.vim 3753 augroup QF_Test 3754 au! 3755 augroup END 3756 3757 new | only 3758 augroup QF_Test 3759 au! 3760 au BufEnter * call setloclist(0, [], 'r') 3761 augroup END 3762 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:') 3763 augroup QF_Test 3764 au! 3765 augroup END 3766 3767 enew | only 3768endfunc 3769 3770func Test_lvimgrep_crash2() 3771 au BufNewFile x sfind 3772 call assert_fails('lvimgrep x x', 'E471:') 3773 call assert_fails('lvimgrep x x x', 'E471:') 3774 3775 au! BufNewFile 3776endfunc 3777 3778" Test for the position of the quickfix and location list window 3779func Test_qfwin_pos() 3780 " Open two windows 3781 new | only 3782 new 3783 cexpr ['F1:10:L10'] 3784 copen 3785 " Quickfix window should be the bottom most window 3786 call assert_equal(3, winnr()) 3787 close 3788 " Open at the very top 3789 wincmd t 3790 topleft copen 3791 call assert_equal(1, winnr()) 3792 close 3793 " open left of the current window 3794 wincmd t 3795 below new 3796 leftabove copen 3797 call assert_equal(2, winnr()) 3798 close 3799 " open right of the current window 3800 rightbelow copen 3801 call assert_equal(3, winnr()) 3802 close 3803endfunc 3804 3805" Tests for quickfix/location lists changed by autocommands when 3806" :vimgrep/:lvimgrep commands are running. 3807func Test_vimgrep_autocmd() 3808 call setqflist([], 'f') 3809 call writefile(['stars'], 'Xtest1.txt') 3810 call writefile(['stars'], 'Xtest2.txt') 3811 3812 " Test 1: 3813 " When searching for a pattern using :vimgrep, if the quickfix list is 3814 " changed by an autocmd, the results should be added to the correct quickfix 3815 " list. 3816 autocmd BufRead Xtest2.txt cexpr '' | cexpr '' 3817 silent vimgrep stars Xtest*.txt 3818 call assert_equal(1, getqflist({'nr' : 0}).nr) 3819 call assert_equal(3, getqflist({'nr' : '$'}).nr) 3820 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr)) 3821 au! BufRead Xtest2.txt 3822 3823 " Test 2: 3824 " When searching for a pattern using :vimgrep, if the quickfix list is 3825 " freed, then a error should be given. 3826 silent! %bwipe! 3827 call setqflist([], 'f') 3828 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor 3829 call assert_fails('vimgrep stars Xtest*.txt', 'E925:') 3830 au! BufRead Xtest2.txt 3831 3832 " Test 3: 3833 " When searching for a pattern using :lvimgrep, if the location list is 3834 " freed, then the command should error out. 3835 silent! %bwipe! 3836 let g:save_winid = win_getid() 3837 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f') 3838 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:') 3839 au! BufRead Xtest2.txt 3840 3841 call delete('Xtest1.txt') 3842 call delete('Xtest2.txt') 3843 call setqflist([], 'f') 3844endfunc 3845 3846" Test for an autocmd changing the current directory when running vimgrep 3847func Xvimgrep_autocmd_cd(cchar) 3848 call s:setup_commands(a:cchar) 3849 3850 %bwipe 3851 let save_cwd = getcwd() 3852 3853 augroup QF_Test 3854 au! 3855 autocmd BufRead * silent cd %:p:h 3856 augroup END 3857 3858 10Xvimgrep /vim/ Xdir/** 3859 let l = g:Xgetlist() 3860 call assert_equal('f1.txt', bufname(l[0].bufnr)) 3861 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t')) 3862 3863 augroup QF_Test 3864 au! 3865 augroup END 3866 3867 exe 'cd ' . save_cwd 3868endfunc 3869 3870func Test_vimgrep_autocmd_cd() 3871 call mkdir('Xdir/a', 'p') 3872 call mkdir('Xdir/b', 'p') 3873 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt') 3874 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt') 3875 call Xvimgrep_autocmd_cd('c') 3876 call Xvimgrep_autocmd_cd('l') 3877 %bwipe 3878 call delete('Xdir', 'rf') 3879endfunc 3880 3881" The following test used to crash Vim 3882func Test_lhelpgrep_autocmd() 3883 lhelpgrep quickfix 3884 autocmd QuickFixCmdPost * call setloclist(0, [], 'f') 3885 lhelpgrep buffer 3886 call assert_equal('help', &filetype) 3887 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr) 3888 lhelpgrep tabpage 3889 call assert_equal('help', &filetype) 3890 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr) 3891 au! QuickFixCmdPost 3892 3893 new | only 3894 augroup QF_Test 3895 au! 3896 au BufEnter * call setqflist([], 'f') 3897 augroup END 3898 call assert_fails('helpgrep quickfix', 'E925:') 3899 augroup QF_Test 3900 au! BufEnter 3901 augroup END 3902 3903 new | only 3904 augroup QF_Test 3905 au! 3906 au BufEnter * call setqflist([], 'r') 3907 augroup END 3908 call assert_fails('helpgrep quickfix', 'E925:') 3909 augroup QF_Test 3910 au! BufEnter 3911 augroup END 3912 3913 new | only 3914 augroup QF_Test 3915 au! 3916 au BufEnter * call setloclist(0, [], 'r') 3917 augroup END 3918 call assert_fails('lhelpgrep quickfix', 'E926:') 3919 augroup QF_Test 3920 au! BufEnter 3921 augroup END 3922 3923 new | only 3924endfunc 3925 3926" Test for shortening/simplifying the file name when opening the 3927" quickfix window or when displaying the quickfix list 3928func Test_shorten_fname() 3929 if !has('unix') 3930 return 3931 endif 3932 %bwipe 3933 " Create a quickfix list with a absolute path filename 3934 let fname = getcwd() . '/test_quickfix.vim' 3935 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3936 call assert_equal(fname, bufname('test_quickfix.vim')) 3937 " Opening the quickfix window should simplify the file path 3938 cwindow 3939 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3940 cclose 3941 %bwipe 3942 " Create a quickfix list with a absolute path filename 3943 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3944 call assert_equal(fname, bufname('test_quickfix.vim')) 3945 " Displaying the quickfix list should simplify the file path 3946 silent! clist 3947 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3948endfunc 3949 3950" Quickfix title tests 3951" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands. 3952" Otherwise due to indentation, the title is set with spaces at the beginning 3953" of the command. 3954func Test_qftitle() 3955 call writefile(["F1:1:Line1"], 'Xerr') 3956 3957 " :cexpr 3958 exe "cexpr readfile('Xerr')" 3959 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title) 3960 3961 " :cgetexpr 3962 exe "cgetexpr readfile('Xerr')" 3963 call assert_equal(":cgetexpr readfile('Xerr')", 3964 \ getqflist({'title' : 1}).title) 3965 3966 " :caddexpr 3967 call setqflist([], 'f') 3968 exe "caddexpr readfile('Xerr')" 3969 call assert_equal(":caddexpr readfile('Xerr')", 3970 \ getqflist({'title' : 1}).title) 3971 3972 " :cbuffer 3973 new Xerr 3974 exe "cbuffer" 3975 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title) 3976 3977 " :cgetbuffer 3978 edit Xerr 3979 exe "cgetbuffer" 3980 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title) 3981 3982 " :caddbuffer 3983 call setqflist([], 'f') 3984 edit Xerr 3985 exe "caddbuffer" 3986 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title) 3987 3988 " :cfile 3989 exe "cfile Xerr" 3990 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title) 3991 3992 " :cgetfile 3993 exe "cgetfile Xerr" 3994 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title) 3995 3996 " :caddfile 3997 call setqflist([], 'f') 3998 exe "caddfile Xerr" 3999 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title) 4000 4001 " :grep 4002 set grepprg=internal 4003 exe "grep F1 Xerr" 4004 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title) 4005 4006 " :grepadd 4007 call setqflist([], 'f') 4008 exe "grepadd F1 Xerr" 4009 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title) 4010 set grepprg&vim 4011 4012 " :vimgrep 4013 exe "vimgrep F1 Xerr" 4014 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title) 4015 4016 " :vimgrepadd 4017 call setqflist([], 'f') 4018 exe "vimgrepadd F1 Xerr" 4019 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title) 4020 4021 call setqflist(['F1:10:L10'], ' ') 4022 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4023 4024 call setqflist([], 'f') 4025 call setqflist(['F1:10:L10'], 'a') 4026 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4027 4028 call setqflist([], 'f') 4029 call setqflist(['F1:10:L10'], 'r') 4030 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4031 4032 close 4033 call delete('Xerr') 4034 4035 call setqflist([], ' ', {'title' : 'Errors'}) 4036 copen 4037 call assert_equal('Errors', w:quickfix_title) 4038 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]}) 4039 call assert_equal('Errors', w:quickfix_title) 4040 cclose 4041endfunc 4042 4043func Test_lbuffer_with_bwipe() 4044 new 4045 new 4046 augroup nasty 4047 au * * bwipe 4048 augroup END 4049 lbuffer 4050 augroup nasty 4051 au! 4052 augroup END 4053endfunc 4054 4055" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is 4056" running 4057func Xexpr_acmd_freelist(cchar) 4058 call s:setup_commands(a:cchar) 4059 4060 " This was using freed memory. 4061 augroup nasty 4062 au * * call g:Xsetlist([], 'f') 4063 augroup END 4064 Xexpr "x" 4065 augroup nasty 4066 au! 4067 augroup END 4068endfunc 4069 4070func Test_cexpr_acmd_freelist() 4071 call Xexpr_acmd_freelist('c') 4072 call Xexpr_acmd_freelist('l') 4073endfunc 4074 4075" Test for commands that create a new quickfix/location list and jump to the 4076" first error automatically. 4077func Xjumpto_first_error_test(cchar) 4078 call s:setup_commands(a:cchar) 4079 4080 call s:create_test_file('Xtestfile1') 4081 call s:create_test_file('Xtestfile2') 4082 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4'] 4083 4084 " Test for cexpr/lexpr 4085 enew 4086 Xexpr l 4087 call assert_equal('Xtestfile1', @%) 4088 call assert_equal(2, line('.')) 4089 4090 " Test for cfile/lfile 4091 enew 4092 call writefile(l, 'Xerr') 4093 Xfile Xerr 4094 call assert_equal('Xtestfile1', @%) 4095 call assert_equal(2, line('.')) 4096 4097 " Test for cbuffer/lbuffer 4098 edit Xerr 4099 Xbuffer 4100 call assert_equal('Xtestfile1', @%) 4101 call assert_equal(2, line('.')) 4102 4103 call delete('Xerr') 4104 call delete('Xtestfile1') 4105 call delete('Xtestfile2') 4106endfunc 4107 4108func Test_jumpto_first_error() 4109 call Xjumpto_first_error_test('c') 4110 call Xjumpto_first_error_test('l') 4111endfunc 4112 4113" Test for a quickfix autocmd changing the quickfix/location list before 4114" jumping to the first error in the new list. 4115func Xautocmd_changelist(cchar) 4116 call s:setup_commands(a:cchar) 4117 4118 " Test for cfile/lfile 4119 call s:create_test_file('Xtestfile1') 4120 call s:create_test_file('Xtestfile2') 4121 Xexpr 'Xtestfile1:2:Line2' 4122 autocmd QuickFixCmdPost * Xolder 4123 call writefile(['Xtestfile2:4:Line4'], 'Xerr') 4124 Xfile Xerr 4125 call assert_equal('Xtestfile2', @%) 4126 call assert_equal(4, line('.')) 4127 autocmd! QuickFixCmdPost 4128 4129 " Test for cbuffer/lbuffer 4130 call g:Xsetlist([], 'f') 4131 Xexpr 'Xtestfile1:2:Line2' 4132 autocmd QuickFixCmdPost * Xolder 4133 call writefile(['Xtestfile2:4:Line4'], 'Xerr') 4134 edit Xerr 4135 Xbuffer 4136 call assert_equal('Xtestfile2', @%) 4137 call assert_equal(4, line('.')) 4138 autocmd! QuickFixCmdPost 4139 4140 " Test for cexpr/lexpr 4141 call g:Xsetlist([], 'f') 4142 Xexpr 'Xtestfile1:2:Line2' 4143 autocmd QuickFixCmdPost * Xolder 4144 Xexpr 'Xtestfile2:4:Line4' 4145 call assert_equal('Xtestfile2', @%) 4146 call assert_equal(4, line('.')) 4147 autocmd! QuickFixCmdPost 4148 4149 " The grepprg may not be set on non-Unix systems 4150 if has('unix') 4151 " Test for grep/lgrep 4152 call g:Xsetlist([], 'f') 4153 Xexpr 'Xtestfile1:2:Line2' 4154 autocmd QuickFixCmdPost * Xolder 4155 silent Xgrep Line5 Xtestfile2 4156 call assert_equal('Xtestfile2', @%) 4157 call assert_equal(5, line('.')) 4158 autocmd! QuickFixCmdPost 4159 endif 4160 4161 " Test for vimgrep/lvimgrep 4162 call g:Xsetlist([], 'f') 4163 Xexpr 'Xtestfile1:2:Line2' 4164 autocmd QuickFixCmdPost * Xolder 4165 silent Xvimgrep Line5 Xtestfile2 4166 call assert_equal('Xtestfile2', @%) 4167 call assert_equal(5, line('.')) 4168 autocmd! QuickFixCmdPost 4169 4170 " Test for autocommands clearing the quickfix list before jumping to the 4171 " first error. This should not result in an error 4172 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r') 4173 let v:errmsg = '' 4174 " Test for cfile/lfile 4175 Xfile Xerr 4176 call assert_true(v:errmsg !~# 'E42:') 4177 " Test for cbuffer/lbuffer 4178 edit Xerr 4179 Xbuffer 4180 call assert_true(v:errmsg !~# 'E42:') 4181 " Test for cexpr/lexpr 4182 Xexpr 'Xtestfile2:4:Line4' 4183 call assert_true(v:errmsg !~# 'E42:') 4184 " Test for grep/lgrep 4185 " The grepprg may not be set on non-Unix systems 4186 if has('unix') 4187 silent Xgrep Line5 Xtestfile2 4188 call assert_true(v:errmsg !~# 'E42:') 4189 endif 4190 " Test for vimgrep/lvimgrep 4191 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:') 4192 autocmd! QuickFixCmdPost 4193 4194 call delete('Xerr') 4195 call delete('Xtestfile1') 4196 call delete('Xtestfile2') 4197endfunc 4198 4199func Test_autocmd_changelist() 4200 call Xautocmd_changelist('c') 4201 call Xautocmd_changelist('l') 4202endfunc 4203 4204" Tests for the ':filter /pat/ clist' command 4205func Test_filter_clist() 4206 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15'] 4207 call assert_equal([' 2 Xfile2:15 col 15: Line 15'], 4208 \ split(execute('filter /Line 15/ clist'), "\n")) 4209 call assert_equal([' 1 Xfile1:10 col 10: Line 10'], 4210 \ split(execute('filter /Xfile1/ clist'), "\n")) 4211 call assert_equal([], split(execute('filter /abc/ clist'), "\n")) 4212 4213 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'}, 4214 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ') 4215 call assert_equal([' 2 pqr:pat2: '], 4216 \ split(execute('filter /pqr/ clist'), "\n")) 4217 call assert_equal([' 1 abc:pat1: '], 4218 \ split(execute('filter /pat1/ clist'), "\n")) 4219endfunc 4220 4221" Tests for the "CTRL-W <CR>" command. 4222func Xview_result_split_tests(cchar) 4223 call s:setup_commands(a:cchar) 4224 4225 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list. 4226 call g:Xsetlist([]) 4227 Xopen 4228 let l:win_count = winnr('$') 4229 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42') 4230 call assert_equal(l:win_count, winnr('$')) 4231 Xclose 4232endfunc 4233 4234func Test_view_result_split() 4235 call Xview_result_split_tests('c') 4236 call Xview_result_split_tests('l') 4237endfunc 4238 4239" Test that :cc sets curswant 4240func Test_curswant() 4241 helpgrep quickfix 4242 normal! llll 4243 1cc 4244 call assert_equal(getcurpos()[4], virtcol('.')) 4245 cclose | helpclose 4246endfunc 4247 4248" Test for opening a file from the quickfix window using CTRL-W <Enter> 4249" doesn't leave an empty buffer around. 4250func Test_splitview() 4251 call s:create_test_file('Xtestfile1') 4252 call s:create_test_file('Xtestfile2') 4253 new | only 4254 let last_bufnr = bufnr('Test_sv_1', 1) 4255 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4'] 4256 cgetexpr l 4257 copen 4258 let numbufs = len(getbufinfo()) 4259 exe "normal \<C-W>\<CR>" 4260 copen 4261 exe "normal j\<C-W>\<CR>" 4262 " Make sure new empty buffers are not created 4263 call assert_equal(numbufs, len(getbufinfo())) 4264 " Creating a new buffer should use the next available buffer number 4265 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1)) 4266 bwipe Test_sv_1 4267 bwipe Test_sv_2 4268 new | only 4269 4270 " When split opening files from location list window, make sure that two 4271 " windows doesn't refer to the same location list 4272 lgetexpr l 4273 let locid = getloclist(0, {'id' : 0}).id 4274 lopen 4275 exe "normal \<C-W>\<CR>" 4276 call assert_notequal(locid, getloclist(0, {'id' : 0}).id) 4277 call assert_equal(0, getloclist(0, {'winid' : 0}).winid) 4278 new | only 4279 4280 " When split opening files from a helpgrep location list window, a new help 4281 " window should be opened with a copy of the location list. 4282 lhelpgrep window 4283 let locid = getloclist(0, {'id' : 0}).id 4284 lwindow 4285 exe "normal j\<C-W>\<CR>" 4286 call assert_notequal(locid, getloclist(0, {'id' : 0}).id) 4287 call assert_equal(0, getloclist(0, {'winid' : 0}).winid) 4288 new | only 4289 4290 " Using :split or :vsplit from a quickfix window should behave like a :new 4291 " or a :vnew command 4292 copen 4293 split 4294 call assert_equal(3, winnr('$')) 4295 let l = getwininfo() 4296 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix]) 4297 close 4298 copen 4299 vsplit 4300 let l = getwininfo() 4301 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix]) 4302 new | only 4303 4304 call delete('Xtestfile1') 4305 call delete('Xtestfile2') 4306endfunc 4307 4308" Test for parsing entries using visual screen column 4309func Test_viscol() 4310 enew 4311 call writefile(["Col1\tCol2\tCol3"], 'Xfile1') 4312 edit Xfile1 4313 4314 " Use byte offset for column number 4315 set efm& 4316 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ" 4317 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4318 cnext 4319 call assert_equal([9, 12], [col('.'), virtcol('.')]) 4320 cnext 4321 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4322 4323 " Use screen column offset for column number 4324 set efm=%f:%l:%v:%m 4325 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ" 4326 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4327 cnext 4328 call assert_equal([9, 12], [col('.'), virtcol('.')]) 4329 cnext 4330 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4331 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ" 4332 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4333 cnext 4334 call assert_equal([10, 16], [col('.'), virtcol('.')]) 4335 cnext 4336 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4337 4338 enew 4339 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1') 4340 4341 " Use byte offset for column number 4342 set efm& 4343 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ" 4344 call assert_equal([8, 10], [col('.'), virtcol('.')]) 4345 cnext 4346 call assert_equal([11, 17], [col('.'), virtcol('.')]) 4347 cnext 4348 call assert_equal([16, 25], [col('.'), virtcol('.')]) 4349 4350 " Use screen column offset for column number 4351 set efm=%f:%l:%v:%m 4352 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ" 4353 call assert_equal([8, 10], [col('.'), virtcol('.')]) 4354 cnext 4355 call assert_equal([11, 17], [col('.'), virtcol('.')]) 4356 cnext 4357 call assert_equal([16, 25], [col('.'), virtcol('.')]) 4358 4359 enew | only 4360 set efm& 4361 call delete('Xfile1') 4362endfunc 4363 4364" Test for the quickfix window buffer 4365func Xqfbuf_test(cchar) 4366 call s:setup_commands(a:cchar) 4367 4368 " Quickfix buffer should be reused across closing and opening a quickfix 4369 " window 4370 Xexpr "F1:10:Line10" 4371 Xopen 4372 let qfbnum = bufnr('') 4373 Xclose 4374 " Even after the quickfix window is closed, the buffer should be loaded 4375 call assert_true(bufloaded(qfbnum)) 4376 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr) 4377 Xopen 4378 " Buffer should be reused when opening the window again 4379 call assert_equal(qfbnum, bufnr('')) 4380 Xclose 4381 4382 if a:cchar == 'l' 4383 %bwipe 4384 " For a location list, when both the file window and the location list 4385 " window for the list are closed, then the buffer should be freed. 4386 new | only 4387 lexpr "F1:10:Line10" 4388 let wid = win_getid() 4389 lopen 4390 let qfbnum = bufnr('') 4391 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls')) 4392 close 4393 " When the location list window is closed, the buffer name should not 4394 " change to 'Quickfix List' 4395 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!')) 4396 call assert_true(bufloaded(qfbnum)) 4397 4398 " After deleting a location list buffer using ":bdelete", opening the 4399 " location list window should mark the buffer as a location list buffer. 4400 exe "bdelete " . qfbnum 4401 lopen 4402 call assert_equal("quickfix", &buftype) 4403 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist) 4404 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid) 4405 call assert_false(&swapfile) 4406 lclose 4407 4408 " When the location list is cleared for the window, the buffer should be 4409 " removed 4410 call setloclist(0, [], 'f') 4411 call assert_false(bufexists(qfbnum)) 4412 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr) 4413 4414 " When the location list is freed with the location list window open, the 4415 " location list buffer should not be lost. It should be reused when the 4416 " location list is again populated. 4417 lexpr "F1:10:Line10" 4418 lopen 4419 let wid = win_getid() 4420 let qfbnum = bufnr('') 4421 wincmd p 4422 call setloclist(0, [], 'f') 4423 lexpr "F1:10:Line10" 4424 lopen 4425 call assert_equal(wid, win_getid()) 4426 call assert_equal(qfbnum, bufnr('')) 4427 lclose 4428 4429 " When the window with the location list is closed, the buffer should be 4430 " removed 4431 new | only 4432 call assert_false(bufexists(qfbnum)) 4433 endif 4434endfunc 4435 4436func Test_qfbuf() 4437 call Xqfbuf_test('c') 4438 call Xqfbuf_test('l') 4439endfunc 4440 4441" If there is an autocmd to use only one window, then opening the location 4442" list window used to crash Vim. 4443func Test_winonly_autocmd() 4444 call s:create_test_file('Xtest1') 4445 " Autocmd to show only one Vim window at a time 4446 autocmd WinEnter * only 4447 new 4448 " Load the location list 4449 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15" 4450 let loclistid = getloclist(0, {'id' : 0}).id 4451 " Open the location list window. Only this window will be shown and the file 4452 " window is closed. 4453 lopen 4454 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id) 4455 " Jump to an entry in the location list and make sure that the cursor is 4456 " positioned correctly. 4457 ll 3 4458 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id) 4459 call assert_equal('Xtest1', @%) 4460 call assert_equal(15, line('.')) 4461 " Cleanup 4462 autocmd! WinEnter 4463 new | only 4464 call delete('Xtest1') 4465endfunc 4466 4467" Test to make sure that an empty quickfix buffer is not reused for loading 4468" a normal buffer. 4469func Test_empty_qfbuf() 4470 enew | only 4471 call writefile(["Test"], 'Xfile1') 4472 call setqflist([], 'f') 4473 copen | only 4474 let qfbuf = bufnr('') 4475 edit Xfile1 4476 call assert_notequal(qfbuf, bufnr('')) 4477 enew 4478 call delete('Xfile1') 4479endfunc 4480 4481" Test for the :cbelow, :cabove, :lbelow and :labove commands. 4482" And for the :cafter, :cbefore, :lafter and :lbefore commands. 4483func Xtest_below(cchar) 4484 call s:setup_commands(a:cchar) 4485 4486 " No quickfix/location list 4487 call assert_fails('Xbelow', 'E42:') 4488 call assert_fails('Xabove', 'E42:') 4489 call assert_fails('Xbefore', 'E42:') 4490 call assert_fails('Xafter', 'E42:') 4491 4492 " Empty quickfix/location list 4493 call g:Xsetlist([]) 4494 call assert_fails('Xbelow', 'E42:') 4495 call assert_fails('Xabove', 'E42:') 4496 call assert_fails('Xbefore', 'E42:') 4497 call assert_fails('Xafter', 'E42:') 4498 4499 call s:create_test_file('X1') 4500 call s:create_test_file('X2') 4501 call s:create_test_file('X3') 4502 call s:create_test_file('X4') 4503 4504 " Invalid entries 4505 edit X1 4506 call g:Xsetlist(["E1", "E2"]) 4507 call assert_fails('Xbelow', 'E42:') 4508 call assert_fails('Xabove', 'E42:') 4509 call assert_fails('3Xbelow', 'E42:') 4510 call assert_fails('4Xabove', 'E42:') 4511 call assert_fails('Xbefore', 'E42:') 4512 call assert_fails('Xafter', 'E42:') 4513 call assert_fails('3Xbefore', 'E42:') 4514 call assert_fails('4Xafter', 'E42:') 4515 4516 " Test the commands with various arguments 4517 Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"] 4518 edit +7 X2 4519 Xabove 4520 call assert_equal(['X2', 5], [@%, line('.')]) 4521 call assert_fails('Xabove', 'E553:') 4522 normal 7G 4523 Xbefore 4524 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4525 call assert_fails('Xbefore', 'E553:') 4526 4527 normal 2j 4528 Xbelow 4529 call assert_equal(['X2', 10], [@%, line('.')]) 4530 normal 7G 4531 Xafter 4532 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4533 4534 " Last error in this file 4535 Xbelow 99 4536 call assert_equal(['X2', 15], [@%, line('.')]) 4537 call assert_fails('Xbelow', 'E553:') 4538 normal gg 4539 Xafter 99 4540 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')]) 4541 call assert_fails('Xafter', 'E553:') 4542 4543 " First error in this file 4544 Xabove 99 4545 call assert_equal(['X2', 5], [@%, line('.')]) 4546 call assert_fails('Xabove', 'E553:') 4547 normal G 4548 Xbefore 99 4549 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4550 call assert_fails('Xbefore', 'E553:') 4551 4552 normal gg 4553 Xbelow 2 4554 call assert_equal(['X2', 10], [@%, line('.')]) 4555 normal gg 4556 Xafter 2 4557 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4558 4559 normal G 4560 Xabove 2 4561 call assert_equal(['X2', 10], [@%, line('.')]) 4562 normal G 4563 Xbefore 2 4564 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4565 4566 edit X4 4567 call assert_fails('Xabove', 'E42:') 4568 call assert_fails('Xbelow', 'E42:') 4569 call assert_fails('Xbefore', 'E42:') 4570 call assert_fails('Xafter', 'E42:') 4571 if a:cchar == 'l' 4572 " If a buffer has location list entries from some other window but not 4573 " from the current window, then the commands should fail. 4574 edit X1 | split | call setloclist(0, [], 'f') 4575 call assert_fails('Xabove', 'E776:') 4576 call assert_fails('Xbelow', 'E776:') 4577 call assert_fails('Xbefore', 'E776:') 4578 call assert_fails('Xafter', 'E776:') 4579 close 4580 endif 4581 4582 " Test for lines with multiple quickfix entries 4583 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3", 4584 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3", 4585 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"] 4586 edit +1 X2 4587 Xbelow 2 4588 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) 4589 normal 1G 4590 Xafter 2 4591 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4592 4593 normal gg 4594 Xbelow 99 4595 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) 4596 normal gg 4597 Xafter 99 4598 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')]) 4599 4600 normal G 4601 Xabove 2 4602 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) 4603 normal G 4604 Xbefore 2 4605 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) 4606 4607 normal G 4608 Xabove 99 4609 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4610 normal G 4611 Xbefore 99 4612 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4613 4614 normal 10G 4615 Xabove 4616 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4617 normal 10G$ 4618 2Xbefore 4619 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')]) 4620 4621 normal 10G 4622 Xbelow 4623 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) 4624 normal 9G 4625 5Xafter 4626 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) 4627 4628 " Invalid range 4629 if a:cchar == 'c' 4630 call assert_fails('-2cbelow', 'E16:') 4631 call assert_fails('-2cafter', 'E16:') 4632 else 4633 call assert_fails('-2lbelow', 'E16:') 4634 call assert_fails('-2lafter', 'E16:') 4635 endif 4636 4637 call delete('X1') 4638 call delete('X2') 4639 call delete('X3') 4640 call delete('X4') 4641endfunc 4642 4643func Test_cbelow() 4644 call Xtest_below('c') 4645 call Xtest_below('l') 4646endfunc 4647 4648func Test_quickfix_count() 4649 let commands = [ 4650 \ 'cNext', 4651 \ 'cNfile', 4652 \ 'cabove', 4653 \ 'cbelow', 4654 \ 'cfirst', 4655 \ 'clast', 4656 \ 'cnewer', 4657 \ 'cnext', 4658 \ 'cnfile', 4659 \ 'colder', 4660 \ 'cprevious', 4661 \ 'crewind', 4662 \ 4663 \ 'lNext', 4664 \ 'lNfile', 4665 \ 'labove', 4666 \ 'lbelow', 4667 \ 'lfirst', 4668 \ 'llast', 4669 \ 'lnewer', 4670 \ 'lnext', 4671 \ 'lnfile', 4672 \ 'lolder', 4673 \ 'lprevious', 4674 \ 'lrewind', 4675 \ ] 4676 for cmd in commands 4677 call assert_fails('-1' .. cmd, 'E16:') 4678 call assert_fails('.' .. cmd, 'E16:') 4679 call assert_fails('%' .. cmd, 'E16:') 4680 call assert_fails('$' .. cmd, 'E16:') 4681 endfor 4682endfunc 4683 4684" Test for aborting quickfix commands using QuickFixCmdPre 4685func Xtest_qfcmd_abort(cchar) 4686 call s:setup_commands(a:cchar) 4687 4688 call g:Xsetlist([], 'f') 4689 4690 " cexpr/lexpr 4691 let e = '' 4692 try 4693 Xexpr ["F1:10:Line10", "F2:20:Line20"] 4694 catch /.*/ 4695 let e = v:exception 4696 endtry 4697 call assert_equal('AbortCmd', e) 4698 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4699 4700 " cfile/lfile 4701 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1') 4702 let e = '' 4703 try 4704 Xfile Xfile1 4705 catch /.*/ 4706 let e = v:exception 4707 endtry 4708 call assert_equal('AbortCmd', e) 4709 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4710 call delete('Xfile1') 4711 4712 " cgetbuffer/lgetbuffer 4713 enew! 4714 call append(0, ["F1:10:Line10", "F2:20:Line20"]) 4715 let e = '' 4716 try 4717 Xgetbuffer 4718 catch /.*/ 4719 let e = v:exception 4720 endtry 4721 call assert_equal('AbortCmd', e) 4722 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4723 enew! 4724 4725 " vimgrep/lvimgrep 4726 let e = '' 4727 try 4728 Xvimgrep /func/ test_quickfix.vim 4729 catch /.*/ 4730 let e = v:exception 4731 endtry 4732 call assert_equal('AbortCmd', e) 4733 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4734 4735 " helpgrep/lhelpgrep 4736 let e = '' 4737 try 4738 Xhelpgrep quickfix 4739 catch /.*/ 4740 let e = v:exception 4741 endtry 4742 call assert_equal('AbortCmd', e) 4743 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4744 4745 " grep/lgrep 4746 if has('unix') 4747 let e = '' 4748 try 4749 silent Xgrep func test_quickfix.vim 4750 catch /.*/ 4751 let e = v:exception 4752 endtry 4753 call assert_equal('AbortCmd', e) 4754 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4755 endif 4756endfunc 4757 4758func Test_qfcmd_abort() 4759 augroup QF_Test 4760 au! 4761 autocmd QuickFixCmdPre * throw "AbortCmd" 4762 augroup END 4763 4764 call Xtest_qfcmd_abort('c') 4765 call Xtest_qfcmd_abort('l') 4766 4767 augroup QF_Test 4768 au! 4769 augroup END 4770endfunc 4771 4772" Test for using a file in one of the parent directories. 4773func Test_search_in_dirstack() 4774 call mkdir('Xtestdir/a/b/c', 'p') 4775 let save_cwd = getcwd() 4776 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1') 4777 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2') 4778 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3') 4779 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4') 4780 4781 let lines = "Entering dir Xtestdir\n" . 4782 \ "Entering dir a\n" . 4783 \ "Entering dir b\n" . 4784 \ "Xfile2:2:X2_L2\n" . 4785 \ "Leaving dir a\n" . 4786 \ "Xfile1:2:X1_L2\n" . 4787 \ "Xfile3:1:X3_L1\n" . 4788 \ "Entering dir c\n" . 4789 \ "Xfile4:2:X4_L2\n" . 4790 \ "Leaving dir c\n" 4791 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m 4792 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1 4793 call assert_equal(11, getqflist({'size' : 0}).size) 4794 call assert_equal(4, getqflist({'idx' : 0}).idx) 4795 call assert_equal('X2_L2', getline('.')) 4796 call assert_equal(1, next) 4797 cnext 4798 call assert_equal(6, getqflist({'idx' : 0}).idx) 4799 call assert_equal('X1_L2', getline('.')) 4800 cnext 4801 call assert_equal(7, getqflist({'idx' : 0}).idx) 4802 call assert_equal(1, line('$')) 4803 call assert_equal('', getline(1)) 4804 cnext 4805 call assert_equal(9, getqflist({'idx' : 0}).idx) 4806 call assert_equal(1, line('$')) 4807 call assert_equal('', getline(1)) 4808 4809 set efm& 4810 exe 'cd ' . save_cwd 4811 call delete('Xtestdir', 'rf') 4812endfunc 4813 4814" Test for :cquit 4815func Test_cquit() 4816 " Exit Vim with a non-zero value 4817 if RunVim([], ["cquit 7"], '') 4818 call assert_equal(7, v:shell_error) 4819 endif 4820 4821 if RunVim([], ["50cquit"], '') 4822 call assert_equal(50, v:shell_error) 4823 endif 4824 4825 " Exit Vim with default value 4826 if RunVim([], ["cquit"], '') 4827 call assert_equal(1, v:shell_error) 4828 endif 4829 4830 " Exit Vim with zero value 4831 if RunVim([], ["cquit 0"], '') 4832 call assert_equal(0, v:shell_error) 4833 endif 4834 4835 " Exit Vim with negative value 4836 call assert_fails('-3cquit', 'E16:') 4837endfunc 4838 4839" Test for getting a specific item from a quickfix list 4840func Xtest_getqflist_by_idx(cchar) 4841 call s:setup_commands(a:cchar) 4842 " Empty list 4843 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items) 4844 Xexpr ['F1:10:L10', 'F1:20:L20'] 4845 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items 4846 call assert_equal(bufnr('F1'), l[0].bufnr) 4847 call assert_equal(20, l[0].lnum) 4848 call assert_equal('L20', l[0].text) 4849 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items) 4850 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items) 4851 %bwipe! 4852endfunc 4853 4854func Test_getqflist_by_idx() 4855 call Xtest_getqflist_by_idx('c') 4856 call Xtest_getqflist_by_idx('l') 4857endfunc 4858 4859" Test for the 'quickfixtextfunc' setting 4860func Tqfexpr(info) 4861 if a:info.quickfix 4862 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items 4863 else 4864 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items 4865 endif 4866 4867 let l = [] 4868 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1) 4869 let e = qfl[idx] 4870 let s = '' 4871 if e.bufnr != 0 4872 let bname = bufname(e.bufnr) 4873 let s ..= fnamemodify(bname, ':.') 4874 endif 4875 let s ..= '-' 4876 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-' 4877 let s ..= e.text 4878 call add(l, s) 4879 endfor 4880 4881 return l 4882endfunc 4883 4884func Xtest_qftextfunc(cchar) 4885 call s:setup_commands(a:cchar) 4886 4887 set efm=%f:%l:%c:%m 4888 set quickfixtextfunc=Tqfexpr 4889 call assert_equal('Tqfexpr', &quickfixtextfunc) 4890 call assert_equal('', 4891 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4892 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4893 Xwindow 4894 call assert_equal('F1-L10C2-green', getline(1)) 4895 call assert_equal('F1-L20C4-blue', getline(2)) 4896 Xclose 4897 set quickfixtextfunc&vim 4898 Xwindow 4899 call assert_equal('F1|10 col 2| green', getline(1)) 4900 call assert_equal('F1|20 col 4| blue', getline(2)) 4901 Xclose 4902 set efm& 4903 set quickfixtextfunc& 4904 4905 " Test for per list 'quickfixtextfunc' setting 4906 func PerQfText(info) 4907 if a:info.quickfix 4908 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items 4909 else 4910 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items 4911 endif 4912 if empty(qfl) 4913 return [] 4914 endif 4915 let l = [] 4916 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1) 4917 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col) 4918 endfor 4919 return l 4920 endfunc 4921 set quickfixtextfunc=Tqfexpr 4922 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"}) 4923 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue'] 4924 Xwindow 4925 call assert_equal('Line 10, Col 2', getline(1)) 4926 call assert_equal('Line 20, Col 4', getline(2)) 4927 Xclose 4928 call assert_equal(function('PerQfText'), 4929 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4930 " Add entries to the list when the quickfix buffer is hidden 4931 Xaddexpr ['F1:30:6:red'] 4932 Xwindow 4933 call assert_equal('Line 30, Col 6', getline(3)) 4934 Xclose 4935 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''}) 4936 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4937 set quickfixtextfunc& 4938 delfunc PerQfText 4939 4940 " Non-existing function 4941 set quickfixtextfunc=Tabc 4942 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') 4943 call assert_fails("Xwindow", 'E117:') 4944 Xclose 4945 set quickfixtextfunc& 4946 4947 " set option to a non-function 4948 set quickfixtextfunc=[10,\ 20] 4949 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') 4950 call assert_fails("Xwindow", 'E117:') 4951 Xclose 4952 set quickfixtextfunc& 4953 4954 " set option to a function with different set of arguments 4955 func Xqftext(a, b, c) 4956 return a:a .. a:b .. a:c 4957 endfunc 4958 set quickfixtextfunc=Xqftext 4959 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:') 4960 call assert_fails("Xwindow", 'E119:') 4961 Xclose 4962 4963 " set option to a function that returns a list with non-strings 4964 func Xqftext2(d) 4965 return ['one', [], 'two'] 4966 endfunc 4967 set quickfixtextfunc=Xqftext2 4968 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']", 4969 \ 'E730:') 4970 call assert_fails('Xwindow', 'E730:') 4971 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'], 4972 \ getline(1, '$')) 4973 Xclose 4974 4975 set quickfixtextfunc& 4976 delfunc Xqftext 4977 delfunc Xqftext2 4978 4979 " set the global option to a lambda function 4980 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')} 4981 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4982 Xwindow 4983 call assert_equal(['green', 'blue'], getline(1, '$')) 4984 Xclose 4985 call assert_equal("{d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 'v:val.text')}", &quickfixtextfunc) 4986 set quickfixtextfunc& 4987 4988 " use a lambda function that returns an empty list 4989 set quickfixtextfunc={d\ ->\ []} 4990 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4991 Xwindow 4992 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'], 4993 \ getline(1, '$')) 4994 Xclose 4995 set quickfixtextfunc& 4996 4997 " use a lambda function that returns a list with empty strings 4998 set quickfixtextfunc={d\ ->\ ['',\ '']} 4999 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 5000 Xwindow 5001 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'], 5002 \ getline(1, '$')) 5003 Xclose 5004 set quickfixtextfunc& 5005 5006 " set the per-quickfix list text function to a lambda function 5007 call g:Xsetlist([], ' ', 5008 \ {'quickfixtextfunc' : 5009 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 5010 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}}) 5011 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue'] 5012 Xwindow 5013 call assert_equal('Line 10, Col 2', getline(1)) 5014 call assert_equal('Line 20, Col 4', getline(2)) 5015 Xclose 5016 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)) 5017 call g:Xsetlist([], 'f') 5018endfunc 5019 5020func Test_qftextfunc() 5021 call Xtest_qftextfunc('c') 5022 call Xtest_qftextfunc('l') 5023endfunc 5024 5025" Running :lhelpgrep command more than once in a help window, doesn't jump to 5026" the help topic 5027func Test_lhelpgrep_from_help_window() 5028 call mkdir('Xtestdir/doc', 'p') 5029 call writefile(['window'], 'Xtestdir/doc/a.txt') 5030 call writefile(['buffer'], 'Xtestdir/doc/b.txt') 5031 let save_rtp = &rtp 5032 let &rtp = 'Xtestdir' 5033 lhelpgrep window 5034 lhelpgrep buffer 5035 call assert_equal('b.txt', fnamemodify(@%, ":p:t")) 5036 lhelpgrep window 5037 call assert_equal('a.txt', fnamemodify(@%, ":p:t")) 5038 let &rtp = save_rtp 5039 call delete('Xtestdir', 'rf') 5040 new | only! 5041endfunc 5042 5043" vim: shiftwidth=2 sts=2 expandtab 5044