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