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