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