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