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