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