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