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