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 \@<!', 'E866:') 697endfunc 698 699func Test_helpgrep() 700 call s:test_xhelpgrep('c') 701 helpclose 702 call s:test_xhelpgrep('l') 703endfunc 704 705func Test_errortitle() 706 augroup QfBufWinEnter 707 au! 708 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 709 augroup END 710 copen 711 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}] 712 call setqflist(a) 713 call assert_equal(':setqflist()', g:a) 714 augroup QfBufWinEnter 715 au! 716 augroup END 717 augroup! QfBufWinEnter 718endfunc 719 720func Test_vimgreptitle() 721 augroup QfBufWinEnter 722 au! 723 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 724 augroup END 725 try 726 vimgrep /pattern/j file 727 catch /E480/ 728 endtry 729 copen 730 call assert_equal(': vimgrep /pattern/j file', g:a) 731 augroup QfBufWinEnter 732 au! 733 augroup END 734 augroup! QfBufWinEnter 735endfunc 736 737func XqfTitleTests(cchar) 738 call s:setup_commands(a:cchar) 739 740 Xgetexpr ['file:1:1:message'] 741 let l = g:Xgetlist() 742 if a:cchar == 'c' 743 call setqflist(l, 'r') 744 else 745 call setloclist(0, l, 'r') 746 endif 747 748 Xopen 749 if a:cchar == 'c' 750 let title = ':setqflist()' 751 else 752 let title = ':setloclist()' 753 endif 754 call assert_equal(title, w:quickfix_title) 755 Xclose 756endfunc 757 758" Tests for quickfix window's title 759func Test_qf_title() 760 call XqfTitleTests('c') 761 call XqfTitleTests('l') 762endfunc 763 764" Tests for 'errorformat' 765func Test_efm() 766 let save_efm = &efm 767 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# 768 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 769 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 770 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 771 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC'] 772 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 773 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 774 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY'] 775 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 776 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) 777 let &efm = save_efm 778endfunc 779 780" This will test for problems in quickfix: 781" A. incorrectly copying location lists which caused the location list to show 782" a different name than the file that was actually being displayed. 783" B. not reusing the window for which the location list window is opened but 784" instead creating new windows. 785" C. make sure that the location list window is not reused instead of the 786" window it belongs to. 787" 788" Set up the test environment: 789func ReadTestProtocol(name) 790 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') 791 let word = substitute(base, '\v(.*)\..*', '\1', '') 792 793 setl modifiable 794 setl noreadonly 795 setl noswapfile 796 setl bufhidden=delete 797 %del _ 798 " For problem 2: 799 " 'buftype' has to be set to reproduce the constant opening of new windows 800 setl buftype=nofile 801 802 call setline(1, word) 803 804 setl nomodified 805 setl nomodifiable 806 setl readonly 807 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') 808endfunc 809 810func Test_locationlist() 811 enew 812 813 augroup testgroup 814 au! 815 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>")) 816 augroup END 817 818 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ] 819 820 let qflist = [] 821 for word in words 822 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', }) 823 " NOTE: problem 1: 824 " intentionally not setting 'lnum' so that the quickfix entries are not 825 " valid 826 eval qflist->setloclist(0, ' ') 827 endfor 828 829 " Test A 830 lrewind 831 enew 832 lopen 833 4lnext 834 vert split 835 wincmd L 836 lopen 837 wincmd p 838 lnext 839 let fileName = expand("%") 840 wincmd p 841 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '') 842 let fileName = substitute(fileName, '\\', '/', 'g') 843 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g') 844 call assert_equal("test://bar.txt", fileName) 845 call assert_equal("test://bar.txt", locationListFileName) 846 847 wincmd n | only 848 849 " Test B: 850 lrewind 851 lopen 852 2 853 exe "normal \<CR>" 854 wincmd p 855 3 856 exe "normal \<CR>" 857 wincmd p 858 4 859 exe "normal \<CR>" 860 call assert_equal(2, winnr('$')) 861 wincmd n | only 862 863 " Test C: 864 lrewind 865 lopen 866 " Let's move the location list window to the top to check whether it (the 867 " first window found) will be reused when we try to open new windows: 868 wincmd K 869 2 870 exe "normal \<CR>" 871 wincmd p 872 3 873 exe "normal \<CR>" 874 wincmd p 875 4 876 exe "normal \<CR>" 877 1wincmd w 878 call assert_equal('quickfix', &buftype) 879 2wincmd w 880 let bufferName = expand("%") 881 let bufferName = substitute(bufferName, '\\', '/', 'g') 882 call assert_equal('test://quux.txt', bufferName) 883 884 wincmd n | only 885 886 augroup! testgroup 887endfunc 888 889func Test_locationlist_curwin_was_closed() 890 augroup testgroup 891 au! 892 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>")) 893 augroup END 894 895 func! R(n) 896 quit 897 endfunc 898 899 new 900 let q = [] 901 call add(q, {'filename': 'test_curwin.txt' }) 902 call setloclist(0, q) 903 call assert_fails('lrewind', 'E924:') 904 905 augroup! testgroup 906endfunc 907 908func Test_locationlist_cross_tab_jump() 909 call writefile(['loclistfoo'], 'loclistfoo') 910 call writefile(['loclistbar'], 'loclistbar') 911 set switchbuf=usetab 912 913 edit loclistfoo 914 tabedit loclistbar 915 silent lgrep loclistfoo loclist* 916 call assert_equal(1, tabpagenr()) 917 918 enew | only | tabonly 919 set switchbuf&vim 920 call delete('loclistfoo') 921 call delete('loclistbar') 922endfunc 923 924" More tests for 'errorformat' 925func Test_efm1() 926 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') 2363 2364 " Cannot specify both a non-empty list argument and a dict argument 2365 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:') 2366endfunc 2367 2368func Test_qf_property() 2369 call Xproperty_tests('c') 2370 call Xproperty_tests('l') 2371endfunc 2372 2373" Test for setting the current index in the location/quickfix list 2374func Xtest_setqfidx(cchar) 2375 call s:setup_commands(a:cchar) 2376 2377 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3" 2378 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3" 2379 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3" 2380 2381 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2}) 2382 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2}) 2383 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3}) 2384 Xolder 2 2385 Xopen 2386 call assert_equal(3, line('.')) 2387 Xnewer 2388 call assert_equal(2, line('.')) 2389 Xnewer 2390 call assert_equal(2, line('.')) 2391 " Update the current index with the quickfix window open 2392 wincmd w 2393 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3}) 2394 Xopen 2395 call assert_equal(3, line('.')) 2396 Xclose 2397 2398 " Set the current index to the last entry 2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'}) 2400 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2401 " A large value should set the index to the last index 2402 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1}) 2403 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999}) 2404 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2405 " Invalid index values 2406 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1}) 2407 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2408 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0}) 2409 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2410 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'}) 2411 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx) 2412 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:') 2413 2414 call g:Xsetlist([], 'f') 2415 new | only 2416endfunc 2417 2418func Test_setqfidx() 2419 call Xtest_setqfidx('c') 2420 call Xtest_setqfidx('l') 2421endfunc 2422 2423" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands 2424func QfAutoCmdHandler(loc, cmd) 2425 call add(g:acmds, a:loc . a:cmd) 2426endfunc 2427 2428func Test_Autocmd() 2429 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) 2430 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) 2431 2432 let g:acmds = [] 2433 cexpr "F1:10:Line 10" 2434 caddexpr "F1:20:Line 20" 2435 cgetexpr "F1:30:Line 30" 2436 cexpr "" 2437 caddexpr "" 2438 cgetexpr "" 2439 silent! cexpr non_existing_func() 2440 silent! caddexpr non_existing_func() 2441 silent! cgetexpr non_existing_func() 2442 let l = ['precexpr', 2443 \ 'postcexpr', 2444 \ 'precaddexpr', 2445 \ 'postcaddexpr', 2446 \ 'precgetexpr', 2447 \ 'postcgetexpr', 2448 \ 'precexpr', 2449 \ 'postcexpr', 2450 \ 'precaddexpr', 2451 \ 'postcaddexpr', 2452 \ 'precgetexpr', 2453 \ 'postcgetexpr', 2454 \ 'precexpr', 2455 \ 'precaddexpr', 2456 \ 'precgetexpr'] 2457 call assert_equal(l, g:acmds) 2458 2459 let g:acmds = [] 2460 enew! | call append(0, "F2:10:Line 10") 2461 cbuffer! 2462 enew! | call append(0, "F2:20:Line 20") 2463 cgetbuffer 2464 enew! | call append(0, "F2:30:Line 30") 2465 caddbuffer 2466 new 2467 let bnum = bufnr('%') 2468 bunload 2469 exe 'silent! cbuffer! ' . bnum 2470 exe 'silent! cgetbuffer ' . bnum 2471 exe 'silent! caddbuffer ' . bnum 2472 enew! 2473 let l = ['precbuffer', 2474 \ 'postcbuffer', 2475 \ 'precgetbuffer', 2476 \ 'postcgetbuffer', 2477 \ 'precaddbuffer', 2478 \ 'postcaddbuffer', 2479 \ 'precbuffer', 2480 \ 'precgetbuffer', 2481 \ 'precaddbuffer'] 2482 call assert_equal(l, g:acmds) 2483 2484 call writefile(['Xtest:1:Line1'], 'Xtest') 2485 call writefile([], 'Xempty') 2486 let g:acmds = [] 2487 cfile Xtest 2488 caddfile Xtest 2489 cgetfile Xtest 2490 cfile Xempty 2491 caddfile Xempty 2492 cgetfile Xempty 2493 silent! cfile do_not_exist 2494 silent! caddfile do_not_exist 2495 silent! cgetfile do_not_exist 2496 let l = ['precfile', 2497 \ 'postcfile', 2498 \ 'precaddfile', 2499 \ 'postcaddfile', 2500 \ 'precgetfile', 2501 \ 'postcgetfile', 2502 \ 'precfile', 2503 \ 'postcfile', 2504 \ 'precaddfile', 2505 \ 'postcaddfile', 2506 \ 'precgetfile', 2507 \ 'postcgetfile', 2508 \ 'precfile', 2509 \ 'postcfile', 2510 \ 'precaddfile', 2511 \ 'postcaddfile', 2512 \ 'precgetfile', 2513 \ 'postcgetfile'] 2514 call assert_equal(l, g:acmds) 2515 2516 let g:acmds = [] 2517 helpgrep quickfix 2518 silent! helpgrep non_existing_help_topic 2519 vimgrep test Xtest 2520 vimgrepadd test Xtest 2521 silent! vimgrep non_existing_test Xtest 2522 silent! vimgrepadd non_existing_test Xtest 2523 set makeprg= 2524 silent! make 2525 set makeprg& 2526 let l = ['prehelpgrep', 2527 \ 'posthelpgrep', 2528 \ 'prehelpgrep', 2529 \ 'posthelpgrep', 2530 \ 'previmgrep', 2531 \ 'postvimgrep', 2532 \ 'previmgrepadd', 2533 \ 'postvimgrepadd', 2534 \ 'previmgrep', 2535 \ 'postvimgrep', 2536 \ 'previmgrepadd', 2537 \ 'postvimgrepadd', 2538 \ 'premake', 2539 \ 'postmake'] 2540 call assert_equal(l, g:acmds) 2541 2542 if has('unix') 2543 " Run this test only on Unix-like systems. The grepprg may not be set on 2544 " non-Unix systems. 2545 " The following lines are used for the grep test. Don't remove. 2546 " Grep_Autocmd_Text: Match 1 2547 " GrepAdd_Autocmd_Text: Match 2 2548 let g:acmds = [] 2549 silent grep Grep_Autocmd_Text test_quickfix.vim 2550 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2551 silent grep abc123def Xtest 2552 silent grepadd abc123def Xtest 2553 set grepprg=internal 2554 silent grep Grep_Autocmd_Text test_quickfix.vim 2555 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2556 silent lgrep Grep_Autocmd_Text test_quickfix.vim 2557 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim 2558 set grepprg&vim 2559 let l = ['pregrep', 2560 \ 'postgrep', 2561 \ 'pregrepadd', 2562 \ 'postgrepadd', 2563 \ 'pregrep', 2564 \ 'postgrep', 2565 \ 'pregrepadd', 2566 \ 'postgrepadd', 2567 \ 'pregrep', 2568 \ 'postgrep', 2569 \ 'pregrepadd', 2570 \ 'postgrepadd', 2571 \ 'prelgrep', 2572 \ 'postlgrep', 2573 \ 'prelgrepadd', 2574 \ 'postlgrepadd'] 2575 call assert_equal(l, g:acmds) 2576 endif 2577 2578 call delete('Xtest') 2579 call delete('Xempty') 2580 au! QuickFixCmdPre 2581 au! QuickFixCmdPost 2582endfunc 2583 2584func Test_Autocmd_Exception() 2585 set efm=%m 2586 lgetexpr '?' 2587 2588 try 2589 call DoesNotExit() 2590 catch 2591 lgetexpr '1' 2592 finally 2593 lgetexpr '1' 2594 endtry 2595 2596 call assert_equal('1', getloclist(0)[0].text) 2597 2598 set efm&vim 2599endfunc 2600 2601func Test_caddbuffer_wrong() 2602 " This used to cause a memory access in freed memory. 2603 let save_efm = &efm 2604 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2605 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2606 let &efm = save_efm 2607 caddbuffer 2608 bwipe! 2609endfunc 2610 2611func Test_caddexpr_wrong() 2612 " This used to cause a memory access in freed memory. 2613 cbuffer 2614 cbuffer 2615 copen 2616 let save_efm = &efm 2617 set efm=% 2618 call assert_fails('caddexpr ""', 'E376:') 2619 let &efm = save_efm 2620endfunc 2621 2622func Test_dirstack_cleanup() 2623 " This used to cause a memory access in freed memory. 2624 let save_efm = &efm 2625 lexpr '0' 2626 lopen 2627 fun X(c) 2628 let save_efm=&efm 2629 set efm=%D%f 2630 if a:c == 'c' 2631 caddexpr '::' 2632 else 2633 laddexpr ':0:0' 2634 endif 2635 let &efm=save_efm 2636 endfun 2637 call X('c') 2638 call X('l') 2639 call setqflist([], 'r') 2640 caddbuffer 2641 let &efm = save_efm 2642endfunc 2643 2644" Tests for jumping to entries from the location list window and quickfix 2645" window 2646func Test_cwindow_jump() 2647 set efm=%f%%%l%%%m 2648 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2649 lopen | only 2650 lfirst 2651 call assert_true(winnr('$') == 2) 2652 call assert_true(winnr() == 1) 2653 " Location list for the new window should be set 2654 call assert_true(getloclist(0)[2].text == 'Line 30') 2655 2656 " Open a scratch buffer 2657 " Open a new window and create a location list 2658 " Open the location list window and close the other window 2659 " Jump to an entry. 2660 " Should create a new window and jump to the entry. The scratch buffer 2661 " should not be used. 2662 enew | only 2663 set buftype=nofile 2664 below new 2665 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2666 lopen 2667 2wincmd c 2668 lnext 2669 call assert_true(winnr('$') == 3) 2670 call assert_true(winnr() == 2) 2671 2672 " Open two windows with two different location lists 2673 " Open the location list window and close the previous window 2674 " Jump to an entry in the location list window 2675 " Should open the file in the first window and not set the location list. 2676 enew | only 2677 lgetexpr ["F1%5%Line 5"] 2678 below new 2679 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2680 lopen 2681 2wincmd c 2682 lnext 2683 call assert_true(winnr() == 1) 2684 call assert_true(getloclist(0)[0].text == 'Line 5') 2685 2686 enew | only 2687 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2688 copen 2689 cnext 2690 call assert_true(winnr('$') == 2) 2691 call assert_true(winnr() == 1) 2692 2693 " open the quickfix buffer in two windows and jump to an entry. Should open 2694 " the file in the first quickfix window. 2695 enew | only 2696 copen 2697 let bnum = bufnr('') 2698 exe 'sbuffer ' . bnum 2699 wincmd b 2700 cfirst 2701 call assert_equal(2, winnr()) 2702 call assert_equal('F1', @%) 2703 enew | only 2704 exe 'sb' bnum 2705 exe 'botright sb' bnum 2706 wincmd t 2707 clast 2708 call assert_equal(2, winnr()) 2709 call assert_equal('quickfix', getwinvar(1, '&buftype')) 2710 call assert_equal('quickfix', getwinvar(3, '&buftype')) 2711 2712 " Jumping to a file from the location list window should find a usable 2713 " window by wrapping around the window list. 2714 enew | only 2715 call setloclist(0, [], 'f') 2716 new | new 2717 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2718 lopen 2719 1close 2720 call assert_equal(0, getloclist(3, {'id' : 0}).id) 2721 lnext 2722 call assert_equal(3, winnr()) 2723 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id) 2724 2725 enew | only 2726 set efm&vim 2727endfunc 2728 2729func Test_cwindow_highlight() 2730 CheckScreendump 2731 2732 let lines =<< trim END 2733 call setline(1, ['some', 'text', 'with', 'matches']) 2734 write XCwindow 2735 vimgrep e XCwindow 2736 redraw 2737 cwindow 4 2738 END 2739 call writefile(lines, 'XtestCwindow') 2740 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12}) 2741 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {}) 2742 2743 call term_sendkeys(buf, ":cnext\<CR>") 2744 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {}) 2745 2746 " clean up 2747 call StopVimInTerminal(buf) 2748 call delete('XtestCwindow') 2749 call delete('XCwindow') 2750endfunc 2751 2752func XvimgrepTests(cchar) 2753 call s:setup_commands(a:cchar) 2754 2755 call writefile(['Editor:VIM vim', 2756 \ 'Editor:Emacs EmAcS', 2757 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2758 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2759 2760 " Error cases 2761 call assert_fails('Xvimgrep /abc *', 'E682:') 2762 2763 let @/='' 2764 call assert_fails('Xvimgrep // *', 'E35:') 2765 2766 call assert_fails('Xvimgrep abc', 'E683:') 2767 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2768 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2769 2770 Xexpr "" 2771 Xvimgrepadd Notepad Xtestfile1 2772 Xvimgrepadd MacOS Xtestfile2 2773 let l = g:Xgetlist() 2774 call assert_equal(2, len(l)) 2775 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2776 2777 10Xvimgrep #\cvim#g Xtestfile? 2778 let l = g:Xgetlist() 2779 call assert_equal(2, len(l)) 2780 call assert_equal(8, l[0].col) 2781 call assert_equal(12, l[1].col) 2782 2783 1Xvimgrep ?Editor? Xtestfile* 2784 let l = g:Xgetlist() 2785 call assert_equal(1, len(l)) 2786 call assert_equal('Editor:VIM vim', l[0].text) 2787 2788 edit +3 Xtestfile2 2789 Xvimgrep +\cemacs+j Xtestfile1 2790 let l = g:Xgetlist() 2791 call assert_equal('Xtestfile2', @%) 2792 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2793 2794 " Test for unloading a buffer after vimgrep searched the buffer 2795 %bwipe 2796 Xvimgrep /Editor/j Xtestfile* 2797 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded) 2798 call assert_equal([], getbufinfo('Xtestfile2')) 2799 2800 call delete('Xtestfile1') 2801 call delete('Xtestfile2') 2802endfunc 2803 2804" Tests for the :vimgrep command 2805func Test_vimgrep() 2806 call XvimgrepTests('c') 2807 call XvimgrepTests('l') 2808endfunc 2809 2810" Test for incsearch highlighting of the :vimgrep pattern 2811" This test used to cause "E315: ml_get: invalid lnum" errors. 2812func Test_vimgrep_incsearch() 2813 enew 2814 set incsearch 2815 call test_override("char_avail", 1) 2816 2817 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx") 2818 let l = getqflist() 2819 call assert_equal(2, len(l)) 2820 2821 call test_override("ALL", 0) 2822 set noincsearch 2823endfunc 2824 2825" Test vimgrep with the last search pattern not set 2826func Test_vimgrep_with_no_last_search_pat() 2827 let lines =<< trim [SCRIPT] 2828 call assert_fails('vimgrep // *', 'E35:') 2829 call writefile(v:errors, 'Xresult') 2830 qall! 2831 [SCRIPT] 2832 call writefile(lines, 'Xscript') 2833 if RunVim([], [], '--clean -S Xscript') 2834 call assert_equal([], readfile('Xresult')) 2835 endif 2836 call delete('Xscript') 2837 call delete('Xresult') 2838endfunc 2839 2840func XfreeTests(cchar) 2841 call s:setup_commands(a:cchar) 2842 2843 enew | only 2844 2845 " Deleting the quickfix stack should work even When the current list is 2846 " somewhere in the middle of the stack 2847 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2848 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2849 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2850 Xolder 2851 call g:Xsetlist([], 'f') 2852 call assert_equal(0, len(g:Xgetlist())) 2853 2854 " After deleting the stack, adding a new list should create a stack with a 2855 " single list. 2856 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2857 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2858 2859 " Deleting the stack from a quickfix window should update/clear the 2860 " quickfix/location list window. 2861 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2862 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2863 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2864 Xolder 2865 Xwindow 2866 call g:Xsetlist([], 'f') 2867 call assert_equal(2, winnr('$')) 2868 call assert_equal(1, line('$')) 2869 Xclose 2870 2871 " Deleting the stack from a non-quickfix window should update/clear the 2872 " quickfix/location list window. 2873 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2874 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2875 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2876 Xolder 2877 Xwindow 2878 wincmd p 2879 call g:Xsetlist([], 'f') 2880 call assert_equal(0, len(g:Xgetlist())) 2881 wincmd p 2882 call assert_equal(2, winnr('$')) 2883 call assert_equal(1, line('$')) 2884 2885 " After deleting the location list stack, if the location list window is 2886 " opened, then a new location list should be created. So opening the 2887 " location list window again should not create a new window. 2888 if a:cchar == 'l' 2889 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2890 wincmd p 2891 lopen 2892 call assert_equal(2, winnr('$')) 2893 endif 2894 Xclose 2895endfunc 2896 2897" Tests for the quickfix free functionality 2898func Test_qf_free() 2899 call XfreeTests('c') 2900 call XfreeTests('l') 2901endfunc 2902 2903" Test for buffer overflow when parsing lines and adding new entries to 2904" the quickfix list. 2905func Test_bufoverflow() 2906 set efm=%f:%l:%m 2907 cgetexpr ['File1:100:' . repeat('x', 1025)] 2908 2909 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2910 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2911 2912 set efm=%DEntering\ directory\ %f,%f:%l:%m 2913 cgetexpr ['Entering directory ' . repeat('a', 1006), 2914 \ 'File1:10:Hello World'] 2915 set efm&vim 2916endfunc 2917 2918" Tests for getting the quickfix stack size 2919func XsizeTests(cchar) 2920 call s:setup_commands(a:cchar) 2921 2922 call g:Xsetlist([], 'f') 2923 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2924 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title) 2925 call assert_equal(0, g:Xgetlist({'nr':0}).nr) 2926 2927 Xexpr "File1:10:Line1" 2928 Xexpr "File2:20:Line2" 2929 Xexpr "File3:30:Line3" 2930 Xolder | Xolder 2931 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2932 call g:Xsetlist([], 'f') 2933 2934 Xexpr "File1:10:Line1" 2935 Xexpr "File2:20:Line2" 2936 Xexpr "File3:30:Line3" 2937 Xolder | Xolder 2938 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2939 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2940endfunc 2941 2942func Test_Qf_Size() 2943 call XsizeTests('c') 2944 call XsizeTests('l') 2945endfunc 2946 2947func Test_cclose_from_copen() 2948 augroup QF_Test 2949 au! 2950 au FileType qf :call assert_fails(':cclose', 'E788') 2951 augroup END 2952 copen 2953 augroup QF_Test 2954 au! 2955 augroup END 2956 augroup! QF_Test 2957endfunc 2958 2959func Test_cclose_in_autocmd() 2960 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2961 " event will be triggered. 2962 call test_override('starting', 1) 2963 augroup QF_Test 2964 au! 2965 au FileType qf :call assert_fails(':cclose', 'E788') 2966 augroup END 2967 copen 2968 augroup QF_Test 2969 au! 2970 augroup END 2971 augroup! QF_Test 2972 call test_override('starting', 0) 2973endfunc 2974 2975" Check that ":file" without an argument is possible even when "curbuf_lock" 2976" is set. 2977func Test_file_from_copen() 2978 " Works without argument. 2979 augroup QF_Test 2980 au! 2981 au FileType qf file 2982 augroup END 2983 copen 2984 2985 augroup QF_Test 2986 au! 2987 augroup END 2988 cclose 2989 2990 " Fails with argument. 2991 augroup QF_Test 2992 au! 2993 au FileType qf call assert_fails(':file foo', 'E788') 2994 augroup END 2995 copen 2996 augroup QF_Test 2997 au! 2998 augroup END 2999 cclose 3000 3001 augroup! QF_Test 3002endfunc 3003 3004func Test_resize_from_copen() 3005 augroup QF_Test 3006 au! 3007 au FileType qf resize 5 3008 augroup END 3009 try 3010 " This should succeed without any exception. No other buffers are 3011 " involved in the autocmd. 3012 copen 3013 finally 3014 augroup QF_Test 3015 au! 3016 augroup END 3017 augroup! QF_Test 3018 endtry 3019endfunc 3020 3021" Tests for the quickfix buffer b:changedtick variable 3022func Xchangedtick_tests(cchar) 3023 call s:setup_commands(a:cchar) 3024 3025 new | only 3026 3027 Xexpr "" | Xexpr "" | Xexpr "" 3028 3029 Xopen 3030 Xolder 3031 Xolder 3032 Xaddexpr "F1:10:Line10" 3033 Xaddexpr "F2:20:Line20" 3034 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 3035 call g:Xsetlist([], 'f') 3036 call assert_equal(8, getbufvar('%', 'changedtick')) 3037 Xclose 3038endfunc 3039 3040func Test_changedtick() 3041 call Xchangedtick_tests('c') 3042 call Xchangedtick_tests('l') 3043endfunc 3044 3045" Tests for parsing an expression using setqflist() 3046func Xsetexpr_tests(cchar) 3047 call s:setup_commands(a:cchar) 3048 3049 let t = ["File1:10:Line10", "File1:20:Line20"] 3050 call g:Xsetlist([], ' ', {'lines' : t}) 3051 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 3052 3053 let l = g:Xgetlist() 3054 call assert_equal(3, len(l)) 3055 call assert_equal(20, l[1].lnum) 3056 call assert_equal('Line30', l[2].text) 3057 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 3058 let l = g:Xgetlist() 3059 call assert_equal(1, len(l)) 3060 call assert_equal('Line5', l[0].text) 3061 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 3062 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 3063 3064 call g:Xsetlist([], 'f') 3065 " Add entries to multiple lists 3066 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 3067 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 3068 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 3069 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 3070 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 3071 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 3072 3073 " Adding entries using a custom efm 3074 set efm& 3075 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 3076 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 3077 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 3078 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 3079 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 3080 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 3081 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 3082 \ 'lines' : ['F1:10:L10']})) 3083endfunc 3084 3085func Test_setexpr() 3086 call Xsetexpr_tests('c') 3087 call Xsetexpr_tests('l') 3088endfunc 3089 3090" Tests for per quickfix/location list directory stack 3091func Xmultidirstack_tests(cchar) 3092 call s:setup_commands(a:cchar) 3093 3094 call g:Xsetlist([], 'f') 3095 Xexpr "" | Xexpr "" 3096 3097 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 3098 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 3099 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 3100 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 3101 3102 let l1 = g:Xgetlist({'nr':1, 'items':1}) 3103 let l2 = g:Xgetlist({'nr':2, 'items':1}) 3104 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 3105 call assert_equal(3, l1.items[1].lnum) 3106 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 3107 call assert_equal(5, l2.items[1].lnum) 3108endfunc 3109 3110func Test_multidirstack() 3111 call mkdir('Xone/a', 'p') 3112 call mkdir('Xtwo/a', 'p') 3113 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 3114 call writefile(lines, 'Xone/a/one.txt') 3115 call writefile(lines, 'Xtwo/a/two.txt') 3116 let save_efm = &efm 3117 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 3118 3119 call Xmultidirstack_tests('c') 3120 call Xmultidirstack_tests('l') 3121 3122 let &efm = save_efm 3123 call delete('Xone', 'rf') 3124 call delete('Xtwo', 'rf') 3125endfunc 3126 3127" Tests for per quickfix/location list file stack 3128func Xmultifilestack_tests(cchar) 3129 call s:setup_commands(a:cchar) 3130 3131 call g:Xsetlist([], 'f') 3132 Xexpr "" | Xexpr "" 3133 3134 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 3135 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 3136 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 3137 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 3138 3139 let l1 = g:Xgetlist({'nr':1, 'items':1}) 3140 let l2 = g:Xgetlist({'nr':2, 'items':1}) 3141 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 3142 call assert_equal(3, l1.items[1].lnum) 3143 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 3144 call assert_equal(5, l2.items[1].lnum) 3145 3146 " Test for start of a new error line in the same line where a previous 3147 " error line ends with a file stack. 3148 let efm_val = 'Error\ l%l\ in\ %f,' 3149 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r' 3150 let l = g:Xgetlist({'lines' : [ 3151 \ '(one.txt', 3152 \ 'Error l4 in one.txt', 3153 \ ') (two.txt', 3154 \ 'Error l6 in two.txt', 3155 \ ')', 3156 \ 'Error l8 in one.txt' 3157 \ ], 'efm' : efm_val}) 3158 call assert_equal(3, len(l.items)) 3159 call assert_equal('one.txt', bufname(l.items[0].bufnr)) 3160 call assert_equal(4, l.items[0].lnum) 3161 call assert_equal('one.txt', l.items[0].text) 3162 call assert_equal('two.txt', bufname(l.items[1].bufnr)) 3163 call assert_equal(6, l.items[1].lnum) 3164 call assert_equal('two.txt', l.items[1].text) 3165 call assert_equal('one.txt', bufname(l.items[2].bufnr)) 3166 call assert_equal(8, l.items[2].lnum) 3167 call assert_equal('', l.items[2].text) 3168endfunc 3169 3170func Test_multifilestack() 3171 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 3172 call writefile(lines, 'one.txt') 3173 call writefile(lines, 'two.txt') 3174 let save_efm = &efm 3175 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 3176 3177 call Xmultifilestack_tests('c') 3178 call Xmultifilestack_tests('l') 3179 3180 let &efm = save_efm 3181 call delete('one.txt') 3182 call delete('two.txt') 3183endfunc 3184 3185" Tests for per buffer 'efm' setting 3186func Test_perbuf_efm() 3187 call writefile(["File1-10-Line10"], 'one.txt') 3188 call writefile(["File2#20#Line20"], 'two.txt') 3189 set efm=%f#%l#%m 3190 new | only 3191 new 3192 setlocal efm=%f-%l-%m 3193 cfile one.txt 3194 wincmd w 3195 caddfile two.txt 3196 3197 let l = getqflist() 3198 call assert_equal(10, l[0].lnum) 3199 call assert_equal('Line20', l[1].text) 3200 3201 set efm& 3202 new | only 3203 call delete('one.txt') 3204 call delete('two.txt') 3205endfunc 3206 3207" Open multiple help windows using ":lhelpgrep 3208" This test used to crash Vim 3209func Test_Multi_LL_Help() 3210 new | only 3211 lhelpgrep window 3212 lopen 3213 e# 3214 lhelpgrep buffer 3215 call assert_equal(3, winnr('$')) 3216 call assert_true(len(getloclist(1)) != 0) 3217 call assert_true(len(getloclist(2)) != 0) 3218 new | only 3219endfunc 3220 3221" Tests for adding new quickfix lists using setqflist() 3222func XaddQf_tests(cchar) 3223 call s:setup_commands(a:cchar) 3224 3225 " Create a new list using ' ' for action 3226 call g:Xsetlist([], 'f') 3227 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 3228 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3229 call assert_equal(1, l.nr) 3230 call assert_equal('Test1', l.title) 3231 3232 " Create a new list using ' ' for action and '$' for 'nr' 3233 call g:Xsetlist([], 'f') 3234 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 3235 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3236 call assert_equal(1, l.nr) 3237 call assert_equal('Test2', l.title) 3238 3239 " Create a new list using 'a' for action 3240 call g:Xsetlist([], 'f') 3241 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 3242 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3243 call assert_equal(1, l.nr) 3244 call assert_equal('Test3', l.title) 3245 3246 " Create a new list using 'a' for action and '$' for 'nr' 3247 call g:Xsetlist([], 'f') 3248 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 3249 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 3250 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3251 call assert_equal(1, l.nr) 3252 call assert_equal('Test4', l.title) 3253 3254 " Adding a quickfix list should remove all the lists following the current 3255 " list. 3256 Xexpr "" | Xexpr "" | Xexpr "" 3257 silent! 10Xolder 3258 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 3259 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3260 call assert_equal(2, l.nr) 3261 call assert_equal('Test5', l.title) 3262 3263 " Add a quickfix list using '$' as the list number. 3264 let lastqf = g:Xgetlist({'nr':'$'}).nr 3265 silent! 99Xolder 3266 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 3267 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3268 call assert_equal(lastqf + 1, l.nr) 3269 call assert_equal('Test6', l.title) 3270 3271 " Add a quickfix list using 'nr' set to one more than the quickfix 3272 " list size. 3273 let lastqf = g:Xgetlist({'nr':'$'}).nr 3274 silent! 99Xolder 3275 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 3276 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3277 call assert_equal(lastqf + 1, l.nr) 3278 call assert_equal('Test7', l.title) 3279 3280 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 3281 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 3282 silent! 99Xolder 3283 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 3284 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 3285 call assert_equal(10, l.nr) 3286 call assert_equal('Test8', l.title) 3287 3288 " Add a quickfix list using 'nr' set to a value greater than 10 3289 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 3290 3291 " Try adding a quickfix list with 'nr' set to a value greater than the 3292 " quickfix list size but less than 10. 3293 call g:Xsetlist([], 'f') 3294 Xexpr "" | Xexpr "" | Xexpr "" 3295 silent! 99Xolder 3296 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 3297 3298 " Add a quickfix list using 'nr' set to a some string or list 3299 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 3300endfunc 3301 3302func Test_add_qf() 3303 call XaddQf_tests('c') 3304 call XaddQf_tests('l') 3305endfunc 3306 3307" Test for getting the quickfix list items from some text without modifying 3308" the quickfix stack 3309func XgetListFromLines(cchar) 3310 call s:setup_commands(a:cchar) 3311 call g:Xsetlist([], 'f') 3312 3313 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 3314 call assert_equal(2, len(l)) 3315 call assert_equal(30, l[1].lnum) 3316 3317 call assert_equal({}, g:Xgetlist({'lines' : 10})) 3318 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 3319 call assert_equal([], g:Xgetlist({'lines' : []}).items) 3320 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 3321 3322 " Parse text using a custom efm 3323 set efm& 3324 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 3325 call assert_equal('Line30', l[0].text) 3326 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 3327 call assert_equal('File3:30:Line30', l[0].text) 3328 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 3329 call assert_equal({}, l) 3330 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 3331 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 3332 3333 " Make sure that the quickfix stack is not modified 3334 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 3335endfunc 3336 3337func Test_get_list_from_lines() 3338 call XgetListFromLines('c') 3339 call XgetListFromLines('l') 3340endfunc 3341 3342" Tests for the quickfix list id 3343func Xqfid_tests(cchar) 3344 call s:setup_commands(a:cchar) 3345 3346 call g:Xsetlist([], 'f') 3347 call assert_equal(0, g:Xgetlist({'id':0}).id) 3348 Xexpr '' 3349 let start_id = g:Xgetlist({'id' : 0}).id 3350 Xexpr '' | Xexpr '' 3351 Xolder 3352 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 3353 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 3354 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 3355 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id) 3356 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 3357 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id) 3358 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id) 3359 3360 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 3361 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 3362 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 3363 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 3364 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 3365 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 3366 3367 let qfid = g:Xgetlist({'id':0, 'nr':0}) 3368 call g:Xsetlist([], 'f') 3369 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id) 3370endfunc 3371 3372func Test_qf_id() 3373 call Xqfid_tests('c') 3374 call Xqfid_tests('l') 3375endfunc 3376 3377func Xqfjump_tests(cchar) 3378 call s:setup_commands(a:cchar) 3379 3380 call writefile(["Line1\tFoo", "Line2"], 'F1') 3381 call writefile(["Line1\tBar", "Line2"], 'F2') 3382 call writefile(["Line1\tBaz", "Line2"], 'F3') 3383 3384 call g:Xsetlist([], 'f') 3385 3386 " Tests for 3387 " Jumping to a line using a pattern 3388 " Jumping to a column greater than the last column in a line 3389 " Jumping to a line greater than the last line in the file 3390 let l = [] 3391 for i in range(1, 7) 3392 call add(l, {}) 3393 endfor 3394 let l[0].filename='F1' 3395 let l[0].pattern='Line1' 3396 let l[1].filename='F2' 3397 let l[1].pattern='Line1' 3398 let l[2].filename='F3' 3399 let l[2].pattern='Line1' 3400 let l[3].filename='F3' 3401 let l[3].lnum=1 3402 let l[3].col=9 3403 let l[3].vcol=1 3404 let l[4].filename='F3' 3405 let l[4].lnum=99 3406 let l[5].filename='F3' 3407 let l[5].lnum=1 3408 let l[5].col=99 3409 let l[5].vcol=1 3410 let l[6].filename='F3' 3411 let l[6].pattern='abcxyz' 3412 3413 call g:Xsetlist([], ' ', {'items' : l}) 3414 Xopen | only 3415 2Xnext 3416 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 3417 call assert_equal('F3', @%) 3418 Xnext 3419 call assert_equal(7, col('.')) 3420 Xnext 3421 call assert_equal(2, line('.')) 3422 Xnext 3423 call assert_equal(9, col('.')) 3424 2 3425 Xnext 3426 call assert_equal(2, line('.')) 3427 3428 if a:cchar == 'l' 3429 " When jumping to a location list entry in the location list window and 3430 " no usable windows are available, then a new window should be opened. 3431 enew! | new | only 3432 call g:Xsetlist([], 'f') 3433 setlocal buftype=nofile 3434 new 3435 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']}) 3436 Xopen 3437 let winid = win_getid() 3438 wincmd p 3439 close 3440 call win_gotoid(winid) 3441 Xnext 3442 call assert_equal(3, winnr('$')) 3443 call assert_equal(1, winnr()) 3444 call assert_equal(2, line('.')) 3445 3446 " When jumping to an entry in the location list window and the window 3447 " associated with the location list is not present and a window containing 3448 " the file is already present, then that window should be used. 3449 close 3450 belowright new 3451 call g:Xsetlist([], 'f') 3452 edit F3 3453 call win_gotoid(winid) 3454 Xlast 3455 call assert_equal(3, winnr()) 3456 call assert_equal(6, g:Xgetlist({'size' : 1}).size) 3457 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) 3458 endif 3459 3460 " Cleanup 3461 enew! 3462 new | only 3463 3464 call delete('F1') 3465 call delete('F2') 3466 call delete('F3') 3467endfunc 3468 3469func Test_qfjump() 3470 call Xqfjump_tests('c') 3471 call Xqfjump_tests('l') 3472endfunc 3473 3474" Tests for the getqflist() and getloclist() functions when the list is not 3475" present or is empty 3476func Xgetlist_empty_tests(cchar) 3477 call s:setup_commands(a:cchar) 3478 3479 " Empty quickfix stack 3480 call g:Xsetlist([], 'f') 3481 call assert_equal('', g:Xgetlist({'context' : 0}).context) 3482 call assert_equal(0, g:Xgetlist({'id' : 0}).id) 3483 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 3484 call assert_equal([], g:Xgetlist({'items' : 0}).items) 3485 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr) 3486 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 3487 call assert_equal('', g:Xgetlist({'title' : 0}).title) 3488 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 3489 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick) 3490 if a:cchar == 'c' 3491 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 3492 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0, 3493 \ 'title' : '', 'winid' : 0, 'changedtick': 0, 3494 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0})) 3495 else 3496 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 3497 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 3498 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0, 3499 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''}, 3500 \ g:Xgetlist({'all' : 0})) 3501 endif 3502 3503 " Quickfix window with empty stack 3504 silent! Xopen 3505 let qfwinid = (a:cchar == 'c') ? win_getid() : 0 3506 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0 3507 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid) 3508 Xclose 3509 3510 " Empty quickfix list 3511 Xexpr "" 3512 call assert_equal('', g:Xgetlist({'context' : 0}).context) 3513 call assert_notequal(0, g:Xgetlist({'id' : 0}).id) 3514 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 3515 call assert_equal([], g:Xgetlist({'items' : 0}).items) 3516 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr) 3517 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 3518 call assert_notequal('', g:Xgetlist({'title' : 0}).title) 3519 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 3520 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3521 3522 let qfid = g:Xgetlist({'id' : 0}).id 3523 call g:Xsetlist([], 'f') 3524 3525 " Non-existing quickfix identifier 3526 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context) 3527 call assert_equal(0, g:Xgetlist({'id' : qfid}).id) 3528 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx) 3529 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items) 3530 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr) 3531 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) 3532 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) 3533 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) 3534 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick) 3535 if a:cchar == 'c' 3536 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3537 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3538 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '', 3539 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) 3540 else 3541 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3542 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3543 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0, 3544 \ 'quickfixtextfunc' : ''}, 3545 \ g:Xgetlist({'id' : qfid, 'all' : 0})) 3546 endif 3547 3548 " Non-existing quickfix list number 3549 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) 3550 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr) 3551 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx) 3552 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items) 3553 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id) 3554 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) 3555 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) 3556 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) 3557 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick) 3558 if a:cchar == 'c' 3559 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3560 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3561 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr, 3562 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0})) 3563 else 3564 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 3565 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 3566 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0, 3567 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0})) 3568 endif 3569endfunc 3570 3571func Test_getqflist() 3572 call Xgetlist_empty_tests('c') 3573 call Xgetlist_empty_tests('l') 3574endfunc 3575 3576func Test_getqflist_invalid_nr() 3577 " The following commands used to crash Vim 3578 cexpr "" 3579 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) 3580 3581 " Cleanup 3582 call setqflist([], 'r') 3583endfunc 3584 3585" Tests for the quickfix/location list changedtick 3586func Xqftick_tests(cchar) 3587 call s:setup_commands(a:cchar) 3588 3589 call g:Xsetlist([], 'f') 3590 3591 Xexpr "F1:10:Line10" 3592 let qfid = g:Xgetlist({'id' : 0}).id 3593 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3594 Xaddexpr "F2:20:Line20\nF2:21:Line21" 3595 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3596 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]}) 3597 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick) 3598 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]}) 3599 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick) 3600 call g:Xsetlist([], 'a', {'title' : 'New Title'}) 3601 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick) 3602 3603 enew! 3604 call append(0, ["F5:50:L50", "F6:60:L60"]) 3605 Xaddbuffer 3606 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick) 3607 enew! 3608 3609 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}}) 3610 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick) 3611 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3612 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a') 3613 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick) 3614 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3615 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ') 3616 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3617 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3618 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r') 3619 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3620 3621 call writefile(["F8:80:L80", "F8:81:L81"], "Xone") 3622 Xfile Xone 3623 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3624 Xaddfile Xone 3625 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3626 3627 " Test case for updating a non-current quickfix list 3628 call g:Xsetlist([], 'f') 3629 Xexpr "F1:1:L1" 3630 Xexpr "F2:2:L2" 3631 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]}) 3632 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3633 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick) 3634 3635 call delete("Xone") 3636endfunc 3637 3638func Test_qf_tick() 3639 call Xqftick_tests('c') 3640 call Xqftick_tests('l') 3641endfunc 3642 3643" Test helpgrep with lang specifier 3644func Xtest_helpgrep_with_lang_specifier(cchar) 3645 call s:setup_commands(a:cchar) 3646 Xhelpgrep Vim@en 3647 call assert_equal('help', &filetype) 3648 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr) 3649 new | only 3650endfunc 3651 3652func Test_helpgrep_with_lang_specifier() 3653 call Xtest_helpgrep_with_lang_specifier('c') 3654 call Xtest_helpgrep_with_lang_specifier('l') 3655endfunc 3656 3657" The following test used to crash Vim. 3658" Open the location list window and close the regular window associated with 3659" the location list. When the garbage collection runs now, it incorrectly 3660" marks the location list context as not in use and frees the context. 3661func Test_ll_window_ctx() 3662 call setloclist(0, [], 'f') 3663 call setloclist(0, [], 'a', {'context' : []}) 3664 lopen | only 3665 call test_garbagecollect_now() 3666 echo getloclist(0, {'context' : 1}).context 3667 enew | only 3668endfunc 3669 3670" The following test used to crash vim 3671func Test_lfile_crash() 3672 sp Xtest 3673 au QuickFixCmdPre * bw 3674 call assert_fails('lfile', 'E40') 3675 au! QuickFixCmdPre 3676endfunc 3677 3678" The following test used to crash vim 3679func Test_lbuffer_crash() 3680 sv Xtest 3681 augroup QF_Test 3682 au! 3683 au * * bw 3684 augroup END 3685 lbuffer 3686 augroup QF_Test 3687 au! 3688 augroup END 3689endfunc 3690 3691" The following test used to crash vim 3692func Test_lexpr_crash() 3693 augroup QF_Test 3694 au! 3695 au * * call setloclist(0, [], 'f') 3696 augroup END 3697 lexpr "" 3698 augroup QF_Test 3699 au! 3700 augroup END 3701 3702 enew | only 3703 augroup QF_Test 3704 au! 3705 au BufNew * call setloclist(0, [], 'f') 3706 augroup END 3707 lexpr 'x:1:x' 3708 augroup QF_Test 3709 au! 3710 augroup END 3711 3712 enew | only 3713 lexpr '' 3714 lopen 3715 augroup QF_Test 3716 au! 3717 au FileType * call setloclist(0, [], 'f') 3718 augroup END 3719 lexpr '' 3720 augroup QF_Test 3721 au! 3722 augroup END 3723endfunc 3724 3725" The following test used to crash Vim 3726func Test_lvimgrep_crash() 3727 sv Xtest 3728 augroup QF_Test 3729 au! 3730 au * * call setloclist(0, [], 'f') 3731 augroup END 3732 lvimgrep quickfix test_quickfix.vim 3733 augroup QF_Test 3734 au! 3735 augroup END 3736 3737 new | only 3738 augroup QF_Test 3739 au! 3740 au BufEnter * call setloclist(0, [], 'r') 3741 augroup END 3742 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:') 3743 augroup QF_Test 3744 au! 3745 augroup END 3746 3747 enew | only 3748endfunc 3749 3750func Test_lvimgrep_crash2() 3751 au BufNewFile x sfind 3752 call assert_fails('lvimgrep x x', 'E471:') 3753 call assert_fails('lvimgrep x x x', 'E471:') 3754 3755 au! BufNewFile 3756endfunc 3757 3758" Test for the position of the quickfix and location list window 3759func Test_qfwin_pos() 3760 " Open two windows 3761 new | only 3762 new 3763 cexpr ['F1:10:L10'] 3764 copen 3765 " Quickfix window should be the bottom most window 3766 call assert_equal(3, winnr()) 3767 close 3768 " Open at the very top 3769 wincmd t 3770 topleft copen 3771 call assert_equal(1, winnr()) 3772 close 3773 " open left of the current window 3774 wincmd t 3775 below new 3776 leftabove copen 3777 call assert_equal(2, winnr()) 3778 close 3779 " open right of the current window 3780 rightbelow copen 3781 call assert_equal(3, winnr()) 3782 close 3783endfunc 3784 3785" Tests for quickfix/location lists changed by autocommands when 3786" :vimgrep/:lvimgrep commands are running. 3787func Test_vimgrep_autocmd() 3788 call setqflist([], 'f') 3789 call writefile(['stars'], 'Xtest1.txt') 3790 call writefile(['stars'], 'Xtest2.txt') 3791 3792 " Test 1: 3793 " When searching for a pattern using :vimgrep, if the quickfix list is 3794 " changed by an autocmd, the results should be added to the correct quickfix 3795 " list. 3796 autocmd BufRead Xtest2.txt cexpr '' | cexpr '' 3797 silent vimgrep stars Xtest*.txt 3798 call assert_equal(1, getqflist({'nr' : 0}).nr) 3799 call assert_equal(3, getqflist({'nr' : '$'}).nr) 3800 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr)) 3801 au! BufRead Xtest2.txt 3802 3803 " Test 2: 3804 " When searching for a pattern using :vimgrep, if the quickfix list is 3805 " freed, then a error should be given. 3806 silent! %bwipe! 3807 call setqflist([], 'f') 3808 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor 3809 call assert_fails('vimgrep stars Xtest*.txt', 'E925:') 3810 au! BufRead Xtest2.txt 3811 3812 " Test 3: 3813 " When searching for a pattern using :lvimgrep, if the location list is 3814 " freed, then the command should error out. 3815 silent! %bwipe! 3816 let g:save_winid = win_getid() 3817 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f') 3818 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:') 3819 au! BufRead Xtest2.txt 3820 3821 call delete('Xtest1.txt') 3822 call delete('Xtest2.txt') 3823 call setqflist([], 'f') 3824endfunc 3825 3826" Test for an autocmd changing the current directory when running vimgrep 3827func Xvimgrep_autocmd_cd(cchar) 3828 call s:setup_commands(a:cchar) 3829 3830 %bwipe 3831 let save_cwd = getcwd() 3832 3833 augroup QF_Test 3834 au! 3835 autocmd BufRead * silent cd %:p:h 3836 augroup END 3837 3838 10Xvimgrep /vim/ Xdir/** 3839 let l = g:Xgetlist() 3840 call assert_equal('f1.txt', bufname(l[0].bufnr)) 3841 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t')) 3842 3843 augroup QF_Test 3844 au! 3845 augroup END 3846 3847 exe 'cd ' . save_cwd 3848endfunc 3849 3850func Test_vimgrep_autocmd_cd() 3851 call mkdir('Xdir/a', 'p') 3852 call mkdir('Xdir/b', 'p') 3853 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt') 3854 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt') 3855 call Xvimgrep_autocmd_cd('c') 3856 call Xvimgrep_autocmd_cd('l') 3857 %bwipe 3858 call delete('Xdir', 'rf') 3859endfunc 3860 3861" The following test used to crash Vim 3862func Test_lhelpgrep_autocmd() 3863 lhelpgrep quickfix 3864 autocmd QuickFixCmdPost * call setloclist(0, [], 'f') 3865 lhelpgrep buffer 3866 call assert_equal('help', &filetype) 3867 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr) 3868 lhelpgrep tabpage 3869 call assert_equal('help', &filetype) 3870 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr) 3871 au! QuickFixCmdPost 3872 3873 new | only 3874 augroup QF_Test 3875 au! 3876 au BufEnter * call setqflist([], 'f') 3877 augroup END 3878 call assert_fails('helpgrep quickfix', 'E925:') 3879 augroup QF_Test 3880 au! BufEnter 3881 augroup END 3882 3883 new | only 3884 augroup QF_Test 3885 au! 3886 au BufEnter * call setqflist([], 'r') 3887 augroup END 3888 call assert_fails('helpgrep quickfix', 'E925:') 3889 augroup QF_Test 3890 au! BufEnter 3891 augroup END 3892 3893 new | only 3894 augroup QF_Test 3895 au! 3896 au BufEnter * call setloclist(0, [], 'r') 3897 augroup END 3898 call assert_fails('lhelpgrep quickfix', 'E926:') 3899 augroup QF_Test 3900 au! BufEnter 3901 augroup END 3902 3903 new | only 3904endfunc 3905 3906" Test for shortening/simplifying the file name when opening the 3907" quickfix window or when displaying the quickfix list 3908func Test_shorten_fname() 3909 if !has('unix') 3910 return 3911 endif 3912 %bwipe 3913 " Create a quickfix list with a absolute path filename 3914 let fname = getcwd() . '/test_quickfix.vim' 3915 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3916 call assert_equal(fname, bufname('test_quickfix.vim')) 3917 " Opening the quickfix window should simplify the file path 3918 cwindow 3919 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3920 cclose 3921 %bwipe 3922 " Create a quickfix list with a absolute path filename 3923 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3924 call assert_equal(fname, bufname('test_quickfix.vim')) 3925 " Displaying the quickfix list should simplify the file path 3926 silent! clist 3927 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3928endfunc 3929 3930" Quickfix title tests 3931" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands. 3932" Otherwise due to indentation, the title is set with spaces at the beginning 3933" of the command. 3934func Test_qftitle() 3935 call writefile(["F1:1:Line1"], 'Xerr') 3936 3937 " :cexpr 3938 exe "cexpr readfile('Xerr')" 3939 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title) 3940 3941 " :cgetexpr 3942 exe "cgetexpr readfile('Xerr')" 3943 call assert_equal(":cgetexpr readfile('Xerr')", 3944 \ getqflist({'title' : 1}).title) 3945 3946 " :caddexpr 3947 call setqflist([], 'f') 3948 exe "caddexpr readfile('Xerr')" 3949 call assert_equal(":caddexpr readfile('Xerr')", 3950 \ getqflist({'title' : 1}).title) 3951 3952 " :cbuffer 3953 new Xerr 3954 exe "cbuffer" 3955 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title) 3956 3957 " :cgetbuffer 3958 edit Xerr 3959 exe "cgetbuffer" 3960 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title) 3961 3962 " :caddbuffer 3963 call setqflist([], 'f') 3964 edit Xerr 3965 exe "caddbuffer" 3966 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title) 3967 3968 " :cfile 3969 exe "cfile Xerr" 3970 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title) 3971 3972 " :cgetfile 3973 exe "cgetfile Xerr" 3974 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title) 3975 3976 " :caddfile 3977 call setqflist([], 'f') 3978 exe "caddfile Xerr" 3979 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title) 3980 3981 " :grep 3982 set grepprg=internal 3983 exe "grep F1 Xerr" 3984 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title) 3985 3986 " :grepadd 3987 call setqflist([], 'f') 3988 exe "grepadd F1 Xerr" 3989 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title) 3990 set grepprg&vim 3991 3992 " :vimgrep 3993 exe "vimgrep F1 Xerr" 3994 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title) 3995 3996 " :vimgrepadd 3997 call setqflist([], 'f') 3998 exe "vimgrepadd F1 Xerr" 3999 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title) 4000 4001 call setqflist(['F1:10:L10'], ' ') 4002 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4003 4004 call setqflist([], 'f') 4005 call setqflist(['F1:10:L10'], 'a') 4006 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4007 4008 call setqflist([], 'f') 4009 call setqflist(['F1:10:L10'], 'r') 4010 call assert_equal(':setqflist()', getqflist({'title' : 1}).title) 4011 4012 close 4013 call delete('Xerr') 4014 4015 call setqflist([], ' ', {'title' : 'Errors'}) 4016 copen 4017 call assert_equal('Errors', w:quickfix_title) 4018 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]}) 4019 call assert_equal('Errors', w:quickfix_title) 4020 cclose 4021endfunc 4022 4023func Test_lbuffer_with_bwipe() 4024 new 4025 new 4026 augroup nasty 4027 au * * bwipe 4028 augroup END 4029 lbuffer 4030 augroup nasty 4031 au! 4032 augroup END 4033endfunc 4034 4035" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is 4036" running 4037func Xexpr_acmd_freelist(cchar) 4038 call s:setup_commands(a:cchar) 4039 4040 " This was using freed memory. 4041 augroup nasty 4042 au * * call g:Xsetlist([], 'f') 4043 augroup END 4044 Xexpr "x" 4045 augroup nasty 4046 au! 4047 augroup END 4048endfunc 4049 4050func Test_cexpr_acmd_freelist() 4051 call Xexpr_acmd_freelist('c') 4052 call Xexpr_acmd_freelist('l') 4053endfunc 4054 4055" Test for commands that create a new quickfix/location list and jump to the 4056" first error automatically. 4057func Xjumpto_first_error_test(cchar) 4058 call s:setup_commands(a:cchar) 4059 4060 call s:create_test_file('Xtestfile1') 4061 call s:create_test_file('Xtestfile2') 4062 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4'] 4063 4064 " Test for cexpr/lexpr 4065 enew 4066 Xexpr l 4067 call assert_equal('Xtestfile1', @%) 4068 call assert_equal(2, line('.')) 4069 4070 " Test for cfile/lfile 4071 enew 4072 call writefile(l, 'Xerr') 4073 Xfile Xerr 4074 call assert_equal('Xtestfile1', @%) 4075 call assert_equal(2, line('.')) 4076 4077 " Test for cbuffer/lbuffer 4078 edit Xerr 4079 Xbuffer 4080 call assert_equal('Xtestfile1', @%) 4081 call assert_equal(2, line('.')) 4082 4083 call delete('Xerr') 4084 call delete('Xtestfile1') 4085 call delete('Xtestfile2') 4086endfunc 4087 4088func Test_jumpto_first_error() 4089 call Xjumpto_first_error_test('c') 4090 call Xjumpto_first_error_test('l') 4091endfunc 4092 4093" Test for a quickfix autocmd changing the quickfix/location list before 4094" jumping to the first error in the new list. 4095func Xautocmd_changelist(cchar) 4096 call s:setup_commands(a:cchar) 4097 4098 " Test for cfile/lfile 4099 call s:create_test_file('Xtestfile1') 4100 call s:create_test_file('Xtestfile2') 4101 Xexpr 'Xtestfile1:2:Line2' 4102 autocmd QuickFixCmdPost * Xolder 4103 call writefile(['Xtestfile2:4:Line4'], 'Xerr') 4104 Xfile Xerr 4105 call assert_equal('Xtestfile2', @%) 4106 call assert_equal(4, line('.')) 4107 autocmd! QuickFixCmdPost 4108 4109 " Test for cbuffer/lbuffer 4110 call g:Xsetlist([], 'f') 4111 Xexpr 'Xtestfile1:2:Line2' 4112 autocmd QuickFixCmdPost * Xolder 4113 call writefile(['Xtestfile2:4:Line4'], 'Xerr') 4114 edit Xerr 4115 Xbuffer 4116 call assert_equal('Xtestfile2', @%) 4117 call assert_equal(4, line('.')) 4118 autocmd! QuickFixCmdPost 4119 4120 " Test for cexpr/lexpr 4121 call g:Xsetlist([], 'f') 4122 Xexpr 'Xtestfile1:2:Line2' 4123 autocmd QuickFixCmdPost * Xolder 4124 Xexpr 'Xtestfile2:4:Line4' 4125 call assert_equal('Xtestfile2', @%) 4126 call assert_equal(4, line('.')) 4127 autocmd! QuickFixCmdPost 4128 4129 " The grepprg may not be set on non-Unix systems 4130 if has('unix') 4131 " Test for grep/lgrep 4132 call g:Xsetlist([], 'f') 4133 Xexpr 'Xtestfile1:2:Line2' 4134 autocmd QuickFixCmdPost * Xolder 4135 silent Xgrep Line5 Xtestfile2 4136 call assert_equal('Xtestfile2', @%) 4137 call assert_equal(5, line('.')) 4138 autocmd! QuickFixCmdPost 4139 endif 4140 4141 " Test for vimgrep/lvimgrep 4142 call g:Xsetlist([], 'f') 4143 Xexpr 'Xtestfile1:2:Line2' 4144 autocmd QuickFixCmdPost * Xolder 4145 silent Xvimgrep Line5 Xtestfile2 4146 call assert_equal('Xtestfile2', @%) 4147 call assert_equal(5, line('.')) 4148 autocmd! QuickFixCmdPost 4149 4150 " Test for autocommands clearing the quickfix list before jumping to the 4151 " first error. This should not result in an error 4152 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r') 4153 let v:errmsg = '' 4154 " Test for cfile/lfile 4155 Xfile Xerr 4156 call assert_true(v:errmsg !~# 'E42:') 4157 " Test for cbuffer/lbuffer 4158 edit Xerr 4159 Xbuffer 4160 call assert_true(v:errmsg !~# 'E42:') 4161 " Test for cexpr/lexpr 4162 Xexpr 'Xtestfile2:4:Line4' 4163 call assert_true(v:errmsg !~# 'E42:') 4164 " Test for grep/lgrep 4165 " The grepprg may not be set on non-Unix systems 4166 if has('unix') 4167 silent Xgrep Line5 Xtestfile2 4168 call assert_true(v:errmsg !~# 'E42:') 4169 endif 4170 " Test for vimgrep/lvimgrep 4171 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:') 4172 autocmd! QuickFixCmdPost 4173 4174 call delete('Xerr') 4175 call delete('Xtestfile1') 4176 call delete('Xtestfile2') 4177endfunc 4178 4179func Test_autocmd_changelist() 4180 call Xautocmd_changelist('c') 4181 call Xautocmd_changelist('l') 4182endfunc 4183 4184" Tests for the ':filter /pat/ clist' command 4185func Test_filter_clist() 4186 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15'] 4187 call assert_equal([' 2 Xfile2:15 col 15: Line 15'], 4188 \ split(execute('filter /Line 15/ clist'), "\n")) 4189 call assert_equal([' 1 Xfile1:10 col 10: Line 10'], 4190 \ split(execute('filter /Xfile1/ clist'), "\n")) 4191 call assert_equal([], split(execute('filter /abc/ clist'), "\n")) 4192 4193 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'}, 4194 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ') 4195 call assert_equal([' 2 pqr:pat2: '], 4196 \ split(execute('filter /pqr/ clist'), "\n")) 4197 call assert_equal([' 1 abc:pat1: '], 4198 \ split(execute('filter /pat1/ clist'), "\n")) 4199endfunc 4200 4201" Tests for the "CTRL-W <CR>" command. 4202func Xview_result_split_tests(cchar) 4203 call s:setup_commands(a:cchar) 4204 4205 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list. 4206 call g:Xsetlist([]) 4207 Xopen 4208 let l:win_count = winnr('$') 4209 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42') 4210 call assert_equal(l:win_count, winnr('$')) 4211 Xclose 4212endfunc 4213 4214func Test_view_result_split() 4215 call Xview_result_split_tests('c') 4216 call Xview_result_split_tests('l') 4217endfunc 4218 4219" Test that :cc sets curswant 4220func Test_curswant() 4221 helpgrep quickfix 4222 normal! llll 4223 1cc 4224 call assert_equal(getcurpos()[4], virtcol('.')) 4225 cclose | helpclose 4226endfunc 4227 4228" Test for opening a file from the quickfix window using CTRL-W <Enter> 4229" doesn't leave an empty buffer around. 4230func Test_splitview() 4231 call s:create_test_file('Xtestfile1') 4232 call s:create_test_file('Xtestfile2') 4233 new | only 4234 let last_bufnr = bufnr('Test_sv_1', 1) 4235 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4'] 4236 cgetexpr l 4237 copen 4238 let numbufs = len(getbufinfo()) 4239 exe "normal \<C-W>\<CR>" 4240 copen 4241 exe "normal j\<C-W>\<CR>" 4242 " Make sure new empty buffers are not created 4243 call assert_equal(numbufs, len(getbufinfo())) 4244 " Creating a new buffer should use the next available buffer number 4245 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1)) 4246 bwipe Test_sv_1 4247 bwipe Test_sv_2 4248 new | only 4249 4250 " When split opening files from location list window, make sure that two 4251 " windows doesn't refer to the same location list 4252 lgetexpr l 4253 let locid = getloclist(0, {'id' : 0}).id 4254 lopen 4255 exe "normal \<C-W>\<CR>" 4256 call assert_notequal(locid, getloclist(0, {'id' : 0}).id) 4257 call assert_equal(0, getloclist(0, {'winid' : 0}).winid) 4258 new | only 4259 4260 " When split opening files from a helpgrep location list window, a new help 4261 " window should be opened with a copy of the location list. 4262 lhelpgrep window 4263 let locid = getloclist(0, {'id' : 0}).id 4264 lwindow 4265 exe "normal j\<C-W>\<CR>" 4266 call assert_notequal(locid, getloclist(0, {'id' : 0}).id) 4267 call assert_equal(0, getloclist(0, {'winid' : 0}).winid) 4268 new | only 4269 4270 " Using :split or :vsplit from a quickfix window should behave like a :new 4271 " or a :vnew command 4272 copen 4273 split 4274 call assert_equal(3, winnr('$')) 4275 let l = getwininfo() 4276 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix]) 4277 close 4278 copen 4279 vsplit 4280 let l = getwininfo() 4281 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix]) 4282 new | only 4283 4284 call delete('Xtestfile1') 4285 call delete('Xtestfile2') 4286endfunc 4287 4288" Test for parsing entries using visual screen column 4289func Test_viscol() 4290 enew 4291 call writefile(["Col1\tCol2\tCol3"], 'Xfile1') 4292 edit Xfile1 4293 4294 " Use byte offset for column number 4295 set efm& 4296 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ" 4297 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4298 cnext 4299 call assert_equal([9, 12], [col('.'), virtcol('.')]) 4300 cnext 4301 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4302 4303 " Use screen column offset for column number 4304 set efm=%f:%l:%v:%m 4305 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ" 4306 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4307 cnext 4308 call assert_equal([9, 12], [col('.'), virtcol('.')]) 4309 cnext 4310 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4311 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ" 4312 call assert_equal([5, 8], [col('.'), virtcol('.')]) 4313 cnext 4314 call assert_equal([10, 16], [col('.'), virtcol('.')]) 4315 cnext 4316 call assert_equal([14, 20], [col('.'), virtcol('.')]) 4317 4318 enew 4319 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1') 4320 4321 " Use byte offset for column number 4322 set efm& 4323 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ" 4324 call assert_equal([8, 10], [col('.'), virtcol('.')]) 4325 cnext 4326 call assert_equal([11, 17], [col('.'), virtcol('.')]) 4327 cnext 4328 call assert_equal([16, 25], [col('.'), virtcol('.')]) 4329 4330 " Use screen column offset for column number 4331 set efm=%f:%l:%v:%m 4332 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ" 4333 call assert_equal([8, 10], [col('.'), virtcol('.')]) 4334 cnext 4335 call assert_equal([11, 17], [col('.'), virtcol('.')]) 4336 cnext 4337 call assert_equal([16, 25], [col('.'), virtcol('.')]) 4338 4339 enew | only 4340 set efm& 4341 call delete('Xfile1') 4342endfunc 4343 4344" Test for the quickfix window buffer 4345func Xqfbuf_test(cchar) 4346 call s:setup_commands(a:cchar) 4347 4348 " Quickfix buffer should be reused across closing and opening a quickfix 4349 " window 4350 Xexpr "F1:10:Line10" 4351 Xopen 4352 let qfbnum = bufnr('') 4353 Xclose 4354 " Even after the quickfix window is closed, the buffer should be loaded 4355 call assert_true(bufloaded(qfbnum)) 4356 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr) 4357 Xopen 4358 " Buffer should be reused when opening the window again 4359 call assert_equal(qfbnum, bufnr('')) 4360 Xclose 4361 4362 if a:cchar == 'l' 4363 %bwipe 4364 " For a location list, when both the file window and the location list 4365 " window for the list are closed, then the buffer should be freed. 4366 new | only 4367 lexpr "F1:10:Line10" 4368 let wid = win_getid() 4369 lopen 4370 let qfbnum = bufnr('') 4371 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls')) 4372 close 4373 " When the location list window is closed, the buffer name should not 4374 " change to 'Quickfix List' 4375 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!')) 4376 call assert_true(bufloaded(qfbnum)) 4377 4378 " After deleting a location list buffer using ":bdelete", opening the 4379 " location list window should mark the buffer as a location list buffer. 4380 exe "bdelete " . qfbnum 4381 lopen 4382 call assert_equal("quickfix", &buftype) 4383 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist) 4384 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid) 4385 call assert_false(&swapfile) 4386 lclose 4387 4388 " When the location list is cleared for the window, the buffer should be 4389 " removed 4390 call setloclist(0, [], 'f') 4391 call assert_false(bufexists(qfbnum)) 4392 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr) 4393 4394 " When the location list is freed with the location list window open, the 4395 " location list buffer should not be lost. It should be reused when the 4396 " location list is again populated. 4397 lexpr "F1:10:Line10" 4398 lopen 4399 let wid = win_getid() 4400 let qfbnum = bufnr('') 4401 wincmd p 4402 call setloclist(0, [], 'f') 4403 lexpr "F1:10:Line10" 4404 lopen 4405 call assert_equal(wid, win_getid()) 4406 call assert_equal(qfbnum, bufnr('')) 4407 lclose 4408 4409 " When the window with the location list is closed, the buffer should be 4410 " removed 4411 new | only 4412 call assert_false(bufexists(qfbnum)) 4413 endif 4414endfunc 4415 4416func Test_qfbuf() 4417 call Xqfbuf_test('c') 4418 call Xqfbuf_test('l') 4419endfunc 4420 4421" If there is an autocmd to use only one window, then opening the location 4422" list window used to crash Vim. 4423func Test_winonly_autocmd() 4424 call s:create_test_file('Xtest1') 4425 " Autocmd to show only one Vim window at a time 4426 autocmd WinEnter * only 4427 new 4428 " Load the location list 4429 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15" 4430 let loclistid = getloclist(0, {'id' : 0}).id 4431 " Open the location list window. Only this window will be shown and the file 4432 " window is closed. 4433 lopen 4434 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id) 4435 " Jump to an entry in the location list and make sure that the cursor is 4436 " positioned correctly. 4437 ll 3 4438 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id) 4439 call assert_equal('Xtest1', @%) 4440 call assert_equal(15, line('.')) 4441 " Cleanup 4442 autocmd! WinEnter 4443 new | only 4444 call delete('Xtest1') 4445endfunc 4446 4447" Test to make sure that an empty quickfix buffer is not reused for loading 4448" a normal buffer. 4449func Test_empty_qfbuf() 4450 enew | only 4451 call writefile(["Test"], 'Xfile1') 4452 call setqflist([], 'f') 4453 copen | only 4454 let qfbuf = bufnr('') 4455 edit Xfile1 4456 call assert_notequal(qfbuf, bufnr('')) 4457 enew 4458 call delete('Xfile1') 4459endfunc 4460 4461" Test for the :cbelow, :cabove, :lbelow and :labove commands. 4462" And for the :cafter, :cbefore, :lafter and :lbefore commands. 4463func Xtest_below(cchar) 4464 call s:setup_commands(a:cchar) 4465 4466 " No quickfix/location list 4467 call assert_fails('Xbelow', 'E42:') 4468 call assert_fails('Xabove', 'E42:') 4469 call assert_fails('Xbefore', 'E42:') 4470 call assert_fails('Xafter', 'E42:') 4471 4472 " Empty quickfix/location list 4473 call g:Xsetlist([]) 4474 call assert_fails('Xbelow', 'E42:') 4475 call assert_fails('Xabove', 'E42:') 4476 call assert_fails('Xbefore', 'E42:') 4477 call assert_fails('Xafter', 'E42:') 4478 4479 call s:create_test_file('X1') 4480 call s:create_test_file('X2') 4481 call s:create_test_file('X3') 4482 call s:create_test_file('X4') 4483 4484 " Invalid entries 4485 edit X1 4486 call g:Xsetlist(["E1", "E2"]) 4487 call assert_fails('Xbelow', 'E42:') 4488 call assert_fails('Xabove', 'E42:') 4489 call assert_fails('3Xbelow', 'E42:') 4490 call assert_fails('4Xabove', 'E42:') 4491 call assert_fails('Xbefore', 'E42:') 4492 call assert_fails('Xafter', 'E42:') 4493 call assert_fails('3Xbefore', 'E42:') 4494 call assert_fails('4Xafter', 'E42:') 4495 4496 " Test the commands with various arguments 4497 Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"] 4498 edit +7 X2 4499 Xabove 4500 call assert_equal(['X2', 5], [@%, line('.')]) 4501 call assert_fails('Xabove', 'E553:') 4502 normal 7G 4503 Xbefore 4504 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4505 call assert_fails('Xbefore', 'E553:') 4506 4507 normal 2j 4508 Xbelow 4509 call assert_equal(['X2', 10], [@%, line('.')]) 4510 normal 7G 4511 Xafter 4512 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4513 4514 " Last error in this file 4515 Xbelow 99 4516 call assert_equal(['X2', 15], [@%, line('.')]) 4517 call assert_fails('Xbelow', 'E553:') 4518 normal gg 4519 Xafter 99 4520 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')]) 4521 call assert_fails('Xafter', 'E553:') 4522 4523 " First error in this file 4524 Xabove 99 4525 call assert_equal(['X2', 5], [@%, line('.')]) 4526 call assert_fails('Xabove', 'E553:') 4527 normal G 4528 Xbefore 99 4529 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4530 call assert_fails('Xbefore', 'E553:') 4531 4532 normal gg 4533 Xbelow 2 4534 call assert_equal(['X2', 10], [@%, line('.')]) 4535 normal gg 4536 Xafter 2 4537 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4538 4539 normal G 4540 Xabove 2 4541 call assert_equal(['X2', 10], [@%, line('.')]) 4542 normal G 4543 Xbefore 2 4544 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) 4545 4546 edit X4 4547 call assert_fails('Xabove', 'E42:') 4548 call assert_fails('Xbelow', 'E42:') 4549 call assert_fails('Xbefore', 'E42:') 4550 call assert_fails('Xafter', 'E42:') 4551 if a:cchar == 'l' 4552 " If a buffer has location list entries from some other window but not 4553 " from the current window, then the commands should fail. 4554 edit X1 | split | call setloclist(0, [], 'f') 4555 call assert_fails('Xabove', 'E776:') 4556 call assert_fails('Xbelow', 'E776:') 4557 call assert_fails('Xbefore', 'E776:') 4558 call assert_fails('Xafter', 'E776:') 4559 close 4560 endif 4561 4562 " Test for lines with multiple quickfix entries 4563 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3", 4564 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3", 4565 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"] 4566 edit +1 X2 4567 Xbelow 2 4568 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) 4569 normal 1G 4570 Xafter 2 4571 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) 4572 4573 normal gg 4574 Xbelow 99 4575 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) 4576 normal gg 4577 Xafter 99 4578 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')]) 4579 4580 normal G 4581 Xabove 2 4582 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) 4583 normal G 4584 Xbefore 2 4585 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) 4586 4587 normal G 4588 Xabove 99 4589 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4590 normal G 4591 Xbefore 99 4592 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4593 4594 normal 10G 4595 Xabove 4596 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) 4597 normal 10G$ 4598 2Xbefore 4599 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')]) 4600 4601 normal 10G 4602 Xbelow 4603 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) 4604 normal 9G 4605 5Xafter 4606 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) 4607 4608 " Invalid range 4609 if a:cchar == 'c' 4610 call assert_fails('-2cbelow', 'E16:') 4611 call assert_fails('-2cafter', 'E16:') 4612 else 4613 call assert_fails('-2lbelow', 'E16:') 4614 call assert_fails('-2lafter', 'E16:') 4615 endif 4616 4617 call delete('X1') 4618 call delete('X2') 4619 call delete('X3') 4620 call delete('X4') 4621endfunc 4622 4623func Test_cbelow() 4624 call Xtest_below('c') 4625 call Xtest_below('l') 4626endfunc 4627 4628func Test_quickfix_count() 4629 let commands = [ 4630 \ 'cNext', 4631 \ 'cNfile', 4632 \ 'cabove', 4633 \ 'cbelow', 4634 \ 'cfirst', 4635 \ 'clast', 4636 \ 'cnewer', 4637 \ 'cnext', 4638 \ 'cnfile', 4639 \ 'colder', 4640 \ 'cprevious', 4641 \ 'crewind', 4642 \ 4643 \ 'lNext', 4644 \ 'lNfile', 4645 \ 'labove', 4646 \ 'lbelow', 4647 \ 'lfirst', 4648 \ 'llast', 4649 \ 'lnewer', 4650 \ 'lnext', 4651 \ 'lnfile', 4652 \ 'lolder', 4653 \ 'lprevious', 4654 \ 'lrewind', 4655 \ ] 4656 for cmd in commands 4657 call assert_fails('-1' .. cmd, 'E16:') 4658 call assert_fails('.' .. cmd, 'E16:') 4659 call assert_fails('%' .. cmd, 'E16:') 4660 call assert_fails('$' .. cmd, 'E16:') 4661 endfor 4662endfunc 4663 4664" Test for aborting quickfix commands using QuickFixCmdPre 4665func Xtest_qfcmd_abort(cchar) 4666 call s:setup_commands(a:cchar) 4667 4668 call g:Xsetlist([], 'f') 4669 4670 " cexpr/lexpr 4671 let e = '' 4672 try 4673 Xexpr ["F1:10:Line10", "F2:20:Line20"] 4674 catch /.*/ 4675 let e = v:exception 4676 endtry 4677 call assert_equal('AbortCmd', e) 4678 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4679 4680 " cfile/lfile 4681 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1') 4682 let e = '' 4683 try 4684 Xfile Xfile1 4685 catch /.*/ 4686 let e = v:exception 4687 endtry 4688 call assert_equal('AbortCmd', e) 4689 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4690 call delete('Xfile1') 4691 4692 " cgetbuffer/lgetbuffer 4693 enew! 4694 call append(0, ["F1:10:Line10", "F2:20:Line20"]) 4695 let e = '' 4696 try 4697 Xgetbuffer 4698 catch /.*/ 4699 let e = v:exception 4700 endtry 4701 call assert_equal('AbortCmd', e) 4702 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4703 enew! 4704 4705 " vimgrep/lvimgrep 4706 let e = '' 4707 try 4708 Xvimgrep /func/ test_quickfix.vim 4709 catch /.*/ 4710 let e = v:exception 4711 endtry 4712 call assert_equal('AbortCmd', e) 4713 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4714 4715 " helpgrep/lhelpgrep 4716 let e = '' 4717 try 4718 Xhelpgrep quickfix 4719 catch /.*/ 4720 let e = v:exception 4721 endtry 4722 call assert_equal('AbortCmd', e) 4723 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4724 4725 " grep/lgrep 4726 if has('unix') 4727 let e = '' 4728 try 4729 silent Xgrep func test_quickfix.vim 4730 catch /.*/ 4731 let e = v:exception 4732 endtry 4733 call assert_equal('AbortCmd', e) 4734 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 4735 endif 4736endfunc 4737 4738func Test_qfcmd_abort() 4739 augroup QF_Test 4740 au! 4741 autocmd QuickFixCmdPre * throw "AbortCmd" 4742 augroup END 4743 4744 call Xtest_qfcmd_abort('c') 4745 call Xtest_qfcmd_abort('l') 4746 4747 augroup QF_Test 4748 au! 4749 augroup END 4750endfunc 4751 4752" Test for using a file in one of the parent directories. 4753func Test_search_in_dirstack() 4754 call mkdir('Xtestdir/a/b/c', 'p') 4755 let save_cwd = getcwd() 4756 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1') 4757 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2') 4758 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3') 4759 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4') 4760 4761 let lines = "Entering dir Xtestdir\n" . 4762 \ "Entering dir a\n" . 4763 \ "Entering dir b\n" . 4764 \ "Xfile2:2:X2_L2\n" . 4765 \ "Leaving dir a\n" . 4766 \ "Xfile1:2:X1_L2\n" . 4767 \ "Xfile3:1:X3_L1\n" . 4768 \ "Entering dir c\n" . 4769 \ "Xfile4:2:X4_L2\n" . 4770 \ "Leaving dir c\n" 4771 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m 4772 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1 4773 call assert_equal(11, getqflist({'size' : 0}).size) 4774 call assert_equal(4, getqflist({'idx' : 0}).idx) 4775 call assert_equal('X2_L2', getline('.')) 4776 call assert_equal(1, next) 4777 cnext 4778 call assert_equal(6, getqflist({'idx' : 0}).idx) 4779 call assert_equal('X1_L2', getline('.')) 4780 cnext 4781 call assert_equal(7, getqflist({'idx' : 0}).idx) 4782 call assert_equal(1, line('$')) 4783 call assert_equal('', getline(1)) 4784 cnext 4785 call assert_equal(9, getqflist({'idx' : 0}).idx) 4786 call assert_equal(1, line('$')) 4787 call assert_equal('', getline(1)) 4788 4789 set efm& 4790 exe 'cd ' . save_cwd 4791 call delete('Xtestdir', 'rf') 4792endfunc 4793 4794" Test for :cquit 4795func Test_cquit() 4796 " Exit Vim with a non-zero value 4797 if RunVim([], ["cquit 7"], '') 4798 call assert_equal(7, v:shell_error) 4799 endif 4800 4801 if RunVim([], ["50cquit"], '') 4802 call assert_equal(50, v:shell_error) 4803 endif 4804 4805 " Exit Vim with default value 4806 if RunVim([], ["cquit"], '') 4807 call assert_equal(1, v:shell_error) 4808 endif 4809 4810 " Exit Vim with zero value 4811 if RunVim([], ["cquit 0"], '') 4812 call assert_equal(0, v:shell_error) 4813 endif 4814 4815 " Exit Vim with negative value 4816 call assert_fails('-3cquit', 'E16:') 4817endfunc 4818 4819" Test for getting a specific item from a quickfix list 4820func Xtest_getqflist_by_idx(cchar) 4821 call s:setup_commands(a:cchar) 4822 " Empty list 4823 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items) 4824 Xexpr ['F1:10:L10', 'F1:20:L20'] 4825 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items 4826 call assert_equal(bufnr('F1'), l[0].bufnr) 4827 call assert_equal(20, l[0].lnum) 4828 call assert_equal('L20', l[0].text) 4829 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items) 4830 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items) 4831 %bwipe! 4832endfunc 4833 4834func Test_getqflist_by_idx() 4835 call Xtest_getqflist_by_idx('c') 4836 call Xtest_getqflist_by_idx('l') 4837endfunc 4838 4839" Test for the 'quickfixtextfunc' setting 4840func Tqfexpr(info) 4841 if a:info.quickfix 4842 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items 4843 else 4844 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items 4845 endif 4846 4847 let l = [] 4848 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1) 4849 let e = qfl[idx] 4850 let s = '' 4851 if e.bufnr != 0 4852 let bname = bufname(e.bufnr) 4853 let s ..= fnamemodify(bname, ':.') 4854 endif 4855 let s ..= '-' 4856 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-' 4857 let s ..= e.text 4858 call add(l, s) 4859 endfor 4860 4861 return l 4862endfunc 4863 4864func Xtest_qftextfunc(cchar) 4865 call s:setup_commands(a:cchar) 4866 4867 set efm=%f:%l:%c:%m 4868 set quickfixtextfunc=Tqfexpr 4869 call assert_equal('Tqfexpr', &quickfixtextfunc) 4870 call assert_equal('', 4871 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4872 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4873 Xwindow 4874 call assert_equal('F1-L10C2-green', getline(1)) 4875 call assert_equal('F1-L20C4-blue', getline(2)) 4876 Xclose 4877 set quickfixtextfunc&vim 4878 Xwindow 4879 call assert_equal('F1|10 col 2| green', getline(1)) 4880 call assert_equal('F1|20 col 4| blue', getline(2)) 4881 Xclose 4882 set efm& 4883 set quickfixtextfunc& 4884 4885 " Test for per list 'quickfixtextfunc' setting 4886 func PerQfText(info) 4887 if a:info.quickfix 4888 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items 4889 else 4890 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items 4891 endif 4892 if empty(qfl) 4893 return [] 4894 endif 4895 let l = [] 4896 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1) 4897 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col) 4898 endfor 4899 return l 4900 endfunc 4901 set quickfixtextfunc=Tqfexpr 4902 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"}) 4903 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue'] 4904 Xwindow 4905 call assert_equal('Line 10, Col 2', getline(1)) 4906 call assert_equal('Line 20, Col 4', getline(2)) 4907 Xclose 4908 call assert_equal(function('PerQfText'), 4909 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4910 " Add entries to the list when the quickfix buffer is hidden 4911 Xaddexpr ['F1:30:6:red'] 4912 Xwindow 4913 call assert_equal('Line 30, Col 6', getline(3)) 4914 Xclose 4915 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''}) 4916 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) 4917 set quickfixtextfunc& 4918 delfunc PerQfText 4919 4920 " Non-existing function 4921 set quickfixtextfunc=Tabc 4922 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') 4923 call assert_fails("Xwindow", 'E117:') 4924 Xclose 4925 set quickfixtextfunc& 4926 4927 " set option to a non-function 4928 set quickfixtextfunc=[10,\ 20] 4929 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:') 4930 call assert_fails("Xwindow", 'E117:') 4931 Xclose 4932 set quickfixtextfunc& 4933 4934 " set option to a function with different set of arguments 4935 func Xqftext(a, b, c) 4936 return a:a .. a:b .. a:c 4937 endfunc 4938 set quickfixtextfunc=Xqftext 4939 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:') 4940 call assert_fails("Xwindow", 'E119:') 4941 Xclose 4942 4943 " set option to a function that returns a list with non-strings 4944 func Xqftext2(d) 4945 return ['one', [], 'two'] 4946 endfunc 4947 set quickfixtextfunc=Xqftext2 4948 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']", 4949 \ 'E730:') 4950 call assert_fails('Xwindow', 'E730:') 4951 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'], 4952 \ getline(1, '$')) 4953 Xclose 4954 4955 set quickfixtextfunc& 4956 delfunc Xqftext 4957 delfunc Xqftext2 4958 4959 " set the global option to a lambda function 4960 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')} 4961 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4962 Xwindow 4963 call assert_equal(['green', 'blue'], getline(1, '$')) 4964 Xclose 4965 call assert_equal("{d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 'v:val.text')}", &quickfixtextfunc) 4966 set quickfixtextfunc& 4967 4968 " use a lambda function that returns an empty list 4969 set quickfixtextfunc={d\ ->\ []} 4970 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4971 Xwindow 4972 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'], 4973 \ getline(1, '$')) 4974 Xclose 4975 set quickfixtextfunc& 4976 4977 " use a lambda function that returns a list with empty strings 4978 set quickfixtextfunc={d\ ->\ ['',\ '']} 4979 Xexpr ['F1:10:2:green', 'F1:20:4:blue'] 4980 Xwindow 4981 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'], 4982 \ getline(1, '$')) 4983 Xclose 4984 set quickfixtextfunc& 4985 4986 " set the per-quickfix list text function to a lambda function 4987 call g:Xsetlist([], ' ', 4988 \ {'quickfixtextfunc' : 4989 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 4990 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}}) 4991 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue'] 4992 Xwindow 4993 call assert_equal('Line 10, Col 2', getline(1)) 4994 call assert_equal('Line 20, Col 4', getline(2)) 4995 Xclose 4996 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)) 4997 call g:Xsetlist([], 'f') 4998endfunc 4999 5000func Test_qftextfunc() 5001 call Xtest_qftextfunc('c') 5002 call Xtest_qftextfunc('l') 5003endfunc 5004 5005" Running :lhelpgrep command more than once in a help window, doesn't jump to 5006" the help topic 5007func Test_lhelpgrep_from_help_window() 5008 call mkdir('Xtestdir/doc', 'p') 5009 call writefile(['window'], 'Xtestdir/doc/a.txt') 5010 call writefile(['buffer'], 'Xtestdir/doc/b.txt') 5011 let save_rtp = &rtp 5012 let &rtp = 'Xtestdir' 5013 lhelpgrep window 5014 lhelpgrep buffer 5015 call assert_equal('b.txt', fnamemodify(@%, ":p:t")) 5016 lhelpgrep window 5017 call assert_equal('a.txt', fnamemodify(@%, ":p:t")) 5018 let &rtp = save_rtp 5019 call delete('Xtestdir', 'rf') 5020 new | only! 5021endfunc 5022 5023" vim: shiftwidth=2 sts=2 expandtab 5024