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