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