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