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