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