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