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 = [
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      \ ]
856
857    call writefile(l, 'Xerrorfile1')
858    call writefile(l[:-2], 'Xerrorfile2')
859
860    let m = [
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	\ ]
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=["[Xtestfile1]",
1096	      \ "(1,17)  error: ';' missing",
1097	      \ "(21,2)  warning: variable 'z' not defined",
1098	      \ "(67,3)  error: end of file found before string ended",
1099	      \ "--",
1100	      \ "",
1101	      \ "[Xtestfile2]",
1102	      \ "--",
1103	      \ "",
1104	      \ "[Xtestfile3]",
1105	      \ "NEW compiler v1.1",
1106	      \ "(2,2)   warning: variable 'x' not defined",
1107	      \ "(67,3)  warning: 's' already defined",
1108	      \ "--"
1109	      \]
1110  set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
1111  " To exercise the push/pop file functionality in quickfix, the test files
1112  " need to be created.
1113  call writefile(['Line1'], 'Xtestfile1')
1114  call writefile(['Line2'], 'Xtestfile2')
1115  call writefile(['Line3'], 'Xtestfile3')
1116  cexpr ""
1117  for l in lines
1118      caddexpr l
1119  endfor
1120  let l = getqflist()
1121  call assert_equal(12, len(l))
1122  call assert_equal(21, l[2].lnum)
1123  call assert_equal(2, l[2].col)
1124  call assert_equal('w', l[2].type)
1125  call assert_equal('e', l[3].type)
1126  call delete('Xtestfile1')
1127  call delete('Xtestfile2')
1128  call delete('Xtestfile3')
1129
1130  " Tests for %E, %C and %Z format specifiers
1131  let lines = ["Error 275",
1132	      \ "line 42",
1133	      \ "column 3",
1134	      \ "' ' expected after '--'"
1135	      \]
1136  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1137  cgetexpr lines
1138  let l = getqflist()
1139  call assert_equal(275, l[0].nr)
1140  call assert_equal(42, l[0].lnum)
1141  call assert_equal(3, l[0].col)
1142  call assert_equal('E', l[0].type)
1143  call assert_equal("\n' ' expected after '--'", l[0].text)
1144
1145  " Test for %>
1146  let lines = ["Error in line 147 of foo.c:",
1147	      \"unknown variable 'i'"
1148	      \]
1149  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1150  cgetexpr lines
1151  let l = getqflist()
1152  call assert_equal(147, l[0].lnum)
1153  call assert_equal('E', l[0].type)
1154  call assert_equal("\nunknown variable 'i'", l[0].text)
1155
1156  " Test for %A, %C and other formats
1157  let lines = [
1158	  \"==============================================================",
1159	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
1160	  \"--------------------------------------------------------------",
1161	  \"Traceback (most recent call last):",
1162	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
1163	  \"    self.assertEquals(34, dtid)",
1164	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
1165	  \" failUnlessEqual",
1166	  \"    raise self.failureException, \\",
1167	  \"AssertionError: 34 != 33",
1168	  \"",
1169	  \"--------------------------------------------------------------",
1170	  \"Ran 27 tests in 0.063s"
1171	  \]
1172  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
1173  cgetexpr lines
1174  let l = getqflist()
1175  call assert_equal(8, len(l))
1176  call assert_equal(89, l[4].lnum)
1177  call assert_equal(1, l[4].valid)
1178  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
1179
1180  " Test for %o
1181  set efm=%f(%o):%l\ %m
1182  cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1183  call writefile(['Line1'], 'Xotestfile')
1184  let l = getqflist()
1185  call assert_equal(1, len(l), string(l))
1186  call assert_equal('Language.PureScript.Types', l[0].module)
1187  copen
1188  call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1189  call feedkeys("\<CR>", 'xn')
1190  call assert_equal('Xotestfile', expand('%:t'))
1191  cclose
1192  bd
1193  call delete("Xotestfile")
1194
1195  " The following sequence of commands used to crash Vim
1196  set efm=%W%m
1197  cgetexpr ['msg1']
1198  let l = getqflist()
1199  call assert_equal(1, len(l), string(l))
1200  call assert_equal('msg1', l[0].text)
1201  set efm=%C%m
1202  lexpr 'msg2'
1203  let l = getloclist(0)
1204  call assert_equal(1, len(l), string(l))
1205  call assert_equal('msg2', l[0].text)
1206  lopen
1207  call setqflist([], 'r')
1208  caddbuf
1209  let l = getqflist()
1210  call assert_equal(1, len(l), string(l))
1211  call assert_equal('|| msg2', l[0].text)
1212
1213  " When matching error lines, case should be ignored. Test for this.
1214  set noignorecase
1215  let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1216  call assert_equal(10, l.items[0].lnum)
1217  call assert_equal('Line 20', l.items[0].text)
1218  set ignorecase&
1219
1220  new | only
1221  let &efm = save_efm
1222endfunc
1223
1224func XquickfixChangedByAutocmd(cchar)
1225  call s:setup_commands(a:cchar)
1226  if a:cchar == 'c'
1227    let ErrorNr = 'E925'
1228    func! ReadFunc()
1229      colder
1230      cgetexpr []
1231    endfunc
1232  else
1233    let ErrorNr = 'E926'
1234    func! ReadFunc()
1235      lolder
1236      lgetexpr []
1237    endfunc
1238  endif
1239
1240  augroup testgroup
1241    au!
1242    autocmd BufReadCmd test_changed.txt call ReadFunc()
1243  augroup END
1244
1245  new | only
1246  let words = [ "a", "b" ]
1247  let qflist = []
1248  for word in words
1249    call add(qflist, {'filename': 'test_changed.txt'})
1250    call g:Xsetlist(qflist, ' ')
1251  endfor
1252  call assert_fails('Xrewind', ErrorNr . ':')
1253
1254  augroup! testgroup
1255endfunc
1256
1257func Test_quickfix_was_changed_by_autocmd()
1258  call XquickfixChangedByAutocmd('c')
1259  call XquickfixChangedByAutocmd('l')
1260endfunc
1261
1262func Test_caddbuffer_to_empty()
1263  helpgr quickfix
1264  call setqflist([], 'r')
1265  cad
1266  try
1267    cn
1268  catch
1269    " number of matches is unknown
1270    call assert_true(v:exception =~ 'E553:')
1271  endtry
1272  quit!
1273endfunc
1274
1275func Test_cgetexpr_works()
1276  " this must not crash Vim
1277  cgetexpr [$x]
1278  lgetexpr [$x]
1279endfunc
1280
1281" Tests for the setqflist() and setloclist() functions
1282func SetXlistTests(cchar, bnum)
1283  call s:setup_commands(a:cchar)
1284
1285  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1286	      \  {'bufnr': a:bnum, 'lnum': 2}])
1287  let l = g:Xgetlist()
1288  call assert_equal(2, len(l))
1289  call assert_equal(2, l[1].lnum)
1290
1291  Xnext
1292  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1293  let l = g:Xgetlist()
1294  call assert_equal(3, len(l))
1295  Xnext
1296  call assert_equal(3, line('.'))
1297
1298  " Appending entries to the list should not change the cursor position
1299  " in the quickfix window
1300  Xwindow
1301  1
1302  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1303	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1304  call assert_equal(1, line('.'))
1305  close
1306
1307  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1308	      \  {'bufnr': a:bnum, 'lnum': 4},
1309	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1310  let l = g:Xgetlist()
1311  call assert_equal(3, len(l))
1312  call assert_equal(5, l[2].lnum)
1313
1314  call g:Xsetlist([])
1315  let l = g:Xgetlist()
1316  call assert_equal(0, len(l))
1317
1318  " Tests for setting the 'valid' flag
1319  call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1320  Xwindow
1321  call assert_equal(1, winnr('$'))
1322  let l = g:Xgetlist()
1323  call g:Xsetlist(l)
1324  call assert_equal(0, g:Xgetlist()[0].valid)
1325  " Adding a non-valid entry should not mark the list as having valid entries
1326  call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1327  Xwindow
1328  call assert_equal(1, winnr('$'))
1329
1330  " :cnext/:cprev should still work even with invalid entries in the list
1331  let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1332	      \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1333  call g:Xsetlist(l)
1334  Xnext
1335  call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1336  Xprev
1337  call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1338  " :cnext/:cprev should still work after appending invalid entries to an
1339  " empty list
1340  call g:Xsetlist([])
1341  call g:Xsetlist(l, 'a')
1342  Xnext
1343  call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1344  Xprev
1345  call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1346
1347  call g:Xsetlist([{'text':'Text1', 'valid':1}])
1348  Xwindow
1349  call assert_equal(2, winnr('$'))
1350  Xclose
1351  let save_efm = &efm
1352  set efm=%m
1353  Xgetexpr 'TestMessage'
1354  let l = g:Xgetlist()
1355  call g:Xsetlist(l)
1356  call assert_equal(1, g:Xgetlist()[0].valid)
1357  let &efm = save_efm
1358
1359  " Error cases:
1360  " Refer to a non-existing buffer and pass a non-dictionary type
1361  call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1362	      \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1363  call g:Xsetlist([[1, 2,3]])
1364  call assert_equal(0, len(g:Xgetlist()))
1365endfunc
1366
1367func Test_setqflist()
1368  new Xtestfile | only
1369  let bnum = bufnr('%')
1370  call setline(1, range(1,5))
1371
1372  call SetXlistTests('c', bnum)
1373  call SetXlistTests('l', bnum)
1374
1375  enew!
1376  call delete('Xtestfile')
1377endfunc
1378
1379func Xlist_empty_middle(cchar)
1380  call s:setup_commands(a:cchar)
1381
1382  " create three quickfix lists
1383  let @/ = 'Test_'
1384  Xvimgrep // test_quickfix.vim
1385  let testlen = len(g:Xgetlist())
1386  call assert_true(testlen > 0)
1387  Xvimgrep empty test_quickfix.vim
1388  call assert_true(len(g:Xgetlist()) > 0)
1389  Xvimgrep matches test_quickfix.vim
1390  let matchlen = len(g:Xgetlist())
1391  call assert_true(matchlen > 0)
1392  Xolder
1393  " make the middle list empty
1394  call g:Xsetlist([], 'r')
1395  call assert_true(len(g:Xgetlist()) == 0)
1396  Xolder
1397  call assert_equal(testlen, len(g:Xgetlist()))
1398  Xnewer
1399  Xnewer
1400  call assert_equal(matchlen, len(g:Xgetlist()))
1401endfunc
1402
1403func Test_setqflist_empty_middle()
1404  call Xlist_empty_middle('c')
1405  call Xlist_empty_middle('l')
1406endfunc
1407
1408func Xlist_empty_older(cchar)
1409  call s:setup_commands(a:cchar)
1410
1411  " create three quickfix lists
1412  Xvimgrep one test_quickfix.vim
1413  let onelen = len(g:Xgetlist())
1414  call assert_true(onelen > 0)
1415  Xvimgrep two test_quickfix.vim
1416  let twolen = len(g:Xgetlist())
1417  call assert_true(twolen > 0)
1418  Xvimgrep three test_quickfix.vim
1419  let threelen = len(g:Xgetlist())
1420  call assert_true(threelen > 0)
1421  Xolder 2
1422  " make the first list empty, check the others didn't change
1423  call g:Xsetlist([], 'r')
1424  call assert_true(len(g:Xgetlist()) == 0)
1425  Xnewer
1426  call assert_equal(twolen, len(g:Xgetlist()))
1427  Xnewer
1428  call assert_equal(threelen, len(g:Xgetlist()))
1429endfunc
1430
1431func Test_setqflist_empty_older()
1432  call Xlist_empty_older('c')
1433  call Xlist_empty_older('l')
1434endfunc
1435
1436func XquickfixSetListWithAct(cchar)
1437  call s:setup_commands(a:cchar)
1438
1439  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1440          \    {'filename': 'fnameB', 'text': 'B'}]
1441  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1442          \    {'filename': 'fnameD', 'text': 'D'},
1443          \    {'filename': 'fnameE', 'text': 'E'}]
1444
1445  " {action} is unspecified.  Same as specifying ' '.
1446  new | only
1447  silent! Xnewer 99
1448  call g:Xsetlist(list1)
1449  call g:Xsetlist(list2)
1450  let li = g:Xgetlist()
1451  call assert_equal(3, len(li))
1452  call assert_equal('C', li[0]['text'])
1453  call assert_equal('D', li[1]['text'])
1454  call assert_equal('E', li[2]['text'])
1455  silent! Xolder
1456  let li = g:Xgetlist()
1457  call assert_equal(2, len(li))
1458  call assert_equal('A', li[0]['text'])
1459  call assert_equal('B', li[1]['text'])
1460
1461  " {action} is specified ' '.
1462  new | only
1463  silent! Xnewer 99
1464  call g:Xsetlist(list1)
1465  call g:Xsetlist(list2, ' ')
1466  let li = g:Xgetlist()
1467  call assert_equal(3, len(li))
1468  call assert_equal('C', li[0]['text'])
1469  call assert_equal('D', li[1]['text'])
1470  call assert_equal('E', li[2]['text'])
1471  silent! Xolder
1472  let li = g:Xgetlist()
1473  call assert_equal(2, len(li))
1474  call assert_equal('A', li[0]['text'])
1475  call assert_equal('B', li[1]['text'])
1476
1477  " {action} is specified 'a'.
1478  new | only
1479  silent! Xnewer 99
1480  call g:Xsetlist(list1)
1481  call g:Xsetlist(list2, 'a')
1482  let li = g:Xgetlist()
1483  call assert_equal(5, len(li))
1484  call assert_equal('A', li[0]['text'])
1485  call assert_equal('B', li[1]['text'])
1486  call assert_equal('C', li[2]['text'])
1487  call assert_equal('D', li[3]['text'])
1488  call assert_equal('E', li[4]['text'])
1489
1490  " {action} is specified 'r'.
1491  new | only
1492  silent! Xnewer 99
1493  call g:Xsetlist(list1)
1494  call g:Xsetlist(list2, 'r')
1495  let li = g:Xgetlist()
1496  call assert_equal(3, len(li))
1497  call assert_equal('C', li[0]['text'])
1498  call assert_equal('D', li[1]['text'])
1499  call assert_equal('E', li[2]['text'])
1500
1501  " Test for wrong value.
1502  new | only
1503  call assert_fails("call g:Xsetlist(0)", 'E714:')
1504  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1505  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1506  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1507  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1508endfunc
1509
1510func Test_setqflist_invalid_nr()
1511  " The following command used to crash Vim
1512  call setqflist([], ' ', {'nr' : $XXX_DOES_NOT_EXIST})
1513endfunc
1514
1515func Test_quickfix_set_list_with_act()
1516  call XquickfixSetListWithAct('c')
1517  call XquickfixSetListWithAct('l')
1518endfunc
1519
1520func XLongLinesTests(cchar)
1521  let l = g:Xgetlist()
1522
1523  call assert_equal(4, len(l))
1524  call assert_equal(1, l[0].lnum)
1525  call assert_equal(1, l[0].col)
1526  call assert_equal(1975, len(l[0].text))
1527  call assert_equal(2, l[1].lnum)
1528  call assert_equal(1, l[1].col)
1529  call assert_equal(4070, len(l[1].text))
1530  call assert_equal(3, l[2].lnum)
1531  call assert_equal(1, l[2].col)
1532  call assert_equal(4070, len(l[2].text))
1533  call assert_equal(4, l[3].lnum)
1534  call assert_equal(1, l[3].col)
1535  call assert_equal(10, len(l[3].text))
1536
1537  call g:Xsetlist([], 'r')
1538endfunc
1539
1540func s:long_lines_tests(cchar)
1541  call s:setup_commands(a:cchar)
1542
1543  let testfile = 'samples/quickfix.txt'
1544
1545  " file
1546  exe 'Xgetfile' testfile
1547  call XLongLinesTests(a:cchar)
1548
1549  " list
1550  Xexpr readfile(testfile)
1551  call XLongLinesTests(a:cchar)
1552
1553  " string
1554  Xexpr join(readfile(testfile), "\n")
1555  call XLongLinesTests(a:cchar)
1556
1557  " buffer
1558  exe 'edit' testfile
1559  exe 'Xbuffer' bufnr('%')
1560  call XLongLinesTests(a:cchar)
1561endfunc
1562
1563func Test_long_lines()
1564  call s:long_lines_tests('c')
1565  call s:long_lines_tests('l')
1566endfunc
1567
1568func s:create_test_file(filename)
1569  let l = []
1570  for i in range(1, 20)
1571      call add(l, 'Line' . i)
1572  endfor
1573  call writefile(l, a:filename)
1574endfunc
1575
1576func Test_switchbuf()
1577  call s:create_test_file('Xqftestfile1')
1578  call s:create_test_file('Xqftestfile2')
1579  call s:create_test_file('Xqftestfile3')
1580
1581  new | only
1582  edit Xqftestfile1
1583  let file1_winid = win_getid()
1584  new Xqftestfile2
1585  let file2_winid = win_getid()
1586  cgetexpr ['Xqftestfile1:5:Line5',
1587		\ 'Xqftestfile1:6:Line6',
1588		\ 'Xqftestfile2:10:Line10',
1589		\ 'Xqftestfile2:11:Line11',
1590		\ 'Xqftestfile3:15:Line15',
1591		\ 'Xqftestfile3:16:Line16']
1592
1593  new
1594  let winid = win_getid()
1595  cfirst | cnext
1596  call assert_equal(winid, win_getid())
1597  2cnext
1598  call assert_equal(winid, win_getid())
1599  2cnext
1600  call assert_equal(winid, win_getid())
1601  enew
1602
1603  set switchbuf=useopen
1604  cfirst | cnext
1605  call assert_equal(file1_winid, win_getid())
1606  2cnext
1607  call assert_equal(file2_winid, win_getid())
1608  2cnext
1609  call assert_equal(file2_winid, win_getid())
1610
1611  enew | only
1612  set switchbuf=usetab
1613  tabedit Xqftestfile1
1614  tabedit Xqftestfile2
1615  tabedit Xqftestfile3
1616  tabfirst
1617  cfirst | cnext
1618  call assert_equal(2, tabpagenr())
1619  2cnext
1620  call assert_equal(3, tabpagenr())
1621  6cnext
1622  call assert_equal(4, tabpagenr())
1623  2cpfile
1624  call assert_equal(2, tabpagenr())
1625  2cnfile
1626  call assert_equal(4, tabpagenr())
1627  tabfirst | tabonly | enew
1628
1629  set switchbuf=split
1630  cfirst | cnext
1631  call assert_equal(1, winnr('$'))
1632  cnext | cnext
1633  call assert_equal(2, winnr('$'))
1634  cnext | cnext
1635  call assert_equal(3, winnr('$'))
1636  enew | only
1637
1638  set switchbuf=newtab
1639  cfirst | cnext
1640  call assert_equal(1, tabpagenr('$'))
1641  cnext | cnext
1642  call assert_equal(2, tabpagenr('$'))
1643  cnext | cnext
1644  call assert_equal(3, tabpagenr('$'))
1645  tabfirst | enew | tabonly | only
1646
1647  set switchbuf=
1648  edit Xqftestfile1
1649  let file1_winid = win_getid()
1650  new Xqftestfile2
1651  let file2_winid = win_getid()
1652  copen
1653  exe "normal 1G\<CR>"
1654  call assert_equal(file1_winid, win_getid())
1655  copen
1656  exe "normal 3G\<CR>"
1657  call assert_equal(file2_winid, win_getid())
1658  copen | only
1659  exe "normal 5G\<CR>"
1660  call assert_equal(2, winnr('$'))
1661  call assert_equal(1, bufwinnr('Xqftestfile3'))
1662
1663  " If only quickfix window is open in the current tabpage, jumping to an
1664  " entry with 'switchubf' set to 'usetab' should search in other tabpages.
1665  enew | only
1666  set switchbuf=usetab
1667  tabedit Xqftestfile1
1668  tabedit Xqftestfile2
1669  tabedit Xqftestfile3
1670  tabfirst
1671  copen | only
1672  clast
1673  call assert_equal(4, tabpagenr())
1674  tabfirst | tabonly | enew | only
1675
1676  call delete('Xqftestfile1')
1677  call delete('Xqftestfile2')
1678  call delete('Xqftestfile3')
1679  set switchbuf&vim
1680
1681  enew | only
1682endfunc
1683
1684func Xadjust_qflnum(cchar)
1685  call s:setup_commands(a:cchar)
1686
1687  enew | only
1688
1689  let fname = 'Xqftestfile' . a:cchar
1690  call s:create_test_file(fname)
1691  exe 'edit ' . fname
1692
1693  Xgetexpr [fname . ':5:Line5',
1694	      \ fname . ':10:Line10',
1695	      \ fname . ':15:Line15',
1696	      \ fname . ':20:Line20']
1697
1698  6,14delete
1699  call append(6, ['Buffer', 'Window'])
1700
1701  let l = g:Xgetlist()
1702
1703  call assert_equal(5, l[0].lnum)
1704  call assert_equal(6, l[2].lnum)
1705  call assert_equal(13, l[3].lnum)
1706
1707  enew!
1708  call delete(fname)
1709endfunc
1710
1711func Test_adjust_lnum()
1712  call setloclist(0, [])
1713  call Xadjust_qflnum('c')
1714  call setqflist([])
1715  call Xadjust_qflnum('l')
1716endfunc
1717
1718" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1719func s:test_xgrep(cchar)
1720  call s:setup_commands(a:cchar)
1721
1722  " The following lines are used for the grep test. Don't remove.
1723  " Grep_Test_Text: Match 1
1724  " Grep_Test_Text: Match 2
1725  " GrepAdd_Test_Text: Match 1
1726  " GrepAdd_Test_Text: Match 2
1727  enew! | only
1728  set makeef&vim
1729  silent Xgrep Grep_Test_Text: test_quickfix.vim
1730  call assert_true(len(g:Xgetlist()) == 3)
1731  Xopen
1732  call assert_true(w:quickfix_title =~ '^:grep')
1733  Xclose
1734  enew
1735  set makeef=Temp_File_##
1736  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1737  call assert_true(len(g:Xgetlist()) == 6)
1738endfunc
1739
1740func Test_grep()
1741  if !has('unix')
1742    " The grepprg may not be set on non-Unix systems
1743    return
1744  endif
1745
1746  call s:test_xgrep('c')
1747  call s:test_xgrep('l')
1748endfunc
1749
1750func Test_two_windows()
1751  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1752  " make sure they each keep their own state.
1753  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1754  call mkdir('Xone/a', 'p')
1755  call mkdir('Xtwo/a', 'p')
1756  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1757  call writefile(lines, 'Xone/a/one.txt')
1758  call writefile(lines, 'Xtwo/a/two.txt')
1759
1760  new one
1761  let one_id = win_getid()
1762  lexpr ""
1763  new two
1764  let two_id = win_getid()
1765  lexpr ""
1766
1767  laddexpr "Entering dir 'Xtwo/a'"
1768  call win_gotoid(one_id)
1769  laddexpr "Entering dir 'Xone/a'"
1770  call win_gotoid(two_id)
1771  laddexpr 'two.txt:5:two two two'
1772  call win_gotoid(one_id)
1773  laddexpr 'one.txt:3:one one one'
1774
1775  let loc_one = getloclist(one_id)
1776  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1777  call assert_equal(3, loc_one[1].lnum)
1778
1779  let loc_two = getloclist(two_id)
1780  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1781  call assert_equal(5, loc_two[1].lnum)
1782
1783  call win_gotoid(one_id)
1784  bwipe!
1785  call win_gotoid(two_id)
1786  bwipe!
1787  call delete('Xone', 'rf')
1788  call delete('Xtwo', 'rf')
1789endfunc
1790
1791func XbottomTests(cchar)
1792  call s:setup_commands(a:cchar)
1793
1794  " Calling lbottom without any errors should fail
1795  if a:cchar == 'l'
1796      call assert_fails('lbottom', 'E776:')
1797  endif
1798
1799  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1800  Xopen
1801  let wid = win_getid()
1802  call assert_equal(1, line('.'))
1803  wincmd w
1804  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1805  Xbottom
1806  call win_gotoid(wid)
1807  call assert_equal(2, line('.'))
1808  Xclose
1809endfunc
1810
1811" Tests for the :cbottom and :lbottom commands
1812func Test_cbottom()
1813  call XbottomTests('c')
1814  call XbottomTests('l')
1815endfunc
1816
1817func HistoryTest(cchar)
1818  call s:setup_commands(a:cchar)
1819
1820  " clear all lists after the first one, then replace the first one.
1821  call g:Xsetlist([])
1822  call assert_fails('Xolder 99', 'E380:')
1823  let entry = {'filename': 'foo', 'lnum': 42}
1824  call g:Xsetlist([entry], 'r')
1825  call g:Xsetlist([entry, entry])
1826  call g:Xsetlist([entry, entry, entry])
1827  let res = split(execute(a:cchar . 'hist'), "\n")
1828  call assert_equal(3, len(res))
1829  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1830  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1831  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1832  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1833
1834  " Test for changing the quickfix lists
1835  call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
1836  exe '1' . a:cchar . 'hist'
1837  call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
1838  exe '3' . a:cchar . 'hist'
1839  call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
1840  call assert_fails('-2' . a:cchar . 'hist', 'E16:')
1841  call assert_fails('4' . a:cchar . 'hist', 'E16:')
1842
1843  call g:Xsetlist([], 'f')
1844  let l = split(execute(a:cchar . 'hist'), "\n")
1845  call assert_equal('No entries', l[0])
1846  if a:cchar == 'c'
1847    call assert_fails('4chist', 'E16:')
1848  else
1849    call assert_fails('4lhist', 'E776:')
1850  endif
1851
1852  " An empty list should still show the stack history
1853  call g:Xsetlist([])
1854  let res = split(execute(a:cchar . 'hist'), "\n")
1855  call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
1856
1857  call g:Xsetlist([], 'f')
1858endfunc
1859
1860func Test_history()
1861  call HistoryTest('c')
1862  call HistoryTest('l')
1863endfunc
1864
1865func Test_duplicate_buf()
1866  " make sure we can get the highest buffer number
1867  edit DoesNotExist
1868  edit DoesNotExist2
1869  let last_buffer = bufnr("$")
1870
1871  " make sure only one buffer is created
1872  call writefile(['this one', 'that one'], 'Xgrepthis')
1873  vimgrep one Xgrepthis
1874  vimgrep one Xgrepthis
1875  call assert_equal(last_buffer + 1, bufnr("$"))
1876
1877  call delete('Xgrepthis')
1878endfunc
1879
1880" Quickfix/Location list set/get properties tests
1881func Xproperty_tests(cchar)
1882    call s:setup_commands(a:cchar)
1883
1884    " Error cases
1885    call assert_fails('call g:Xgetlist(99)', 'E715:')
1886    call assert_fails('call g:Xsetlist(99)', 'E714:')
1887    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
1888
1889    " Set and get the title
1890    call g:Xsetlist([])
1891    Xopen
1892    wincmd p
1893    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
1894    let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
1895    call assert_equal(0, s)
1896    let d = g:Xgetlist({"title":1})
1897    call assert_equal('Sample', d.title)
1898    " Try setting title to a non-string value
1899    call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
1900    call assert_equal('Sample', g:Xgetlist({"title":1}).title)
1901
1902    Xopen
1903    call assert_equal('Sample', w:quickfix_title)
1904    Xclose
1905
1906    " Tests for action argument
1907    silent! Xolder 999
1908    let qfnr = g:Xgetlist({'all':1}).nr
1909    call g:Xsetlist([], 'r', {'title' : 'N1'})
1910    call assert_equal('N1', g:Xgetlist({'all':1}).title)
1911    call g:Xsetlist([], ' ', {'title' : 'N2'})
1912    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
1913
1914    let res = g:Xgetlist({'nr': 0})
1915    call assert_equal(qfnr + 1, res.nr)
1916    call assert_equal(['nr'], keys(res))
1917
1918    call g:Xsetlist([], ' ', {'title' : 'N3'})
1919    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
1920
1921    " Changing the title of an earlier quickfix list
1922    call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
1923    call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
1924
1925    " Changing the title of an invalid quickfix list
1926    call assert_equal(-1, g:Xsetlist([], ' ',
1927		\ {'title' : 'SomeTitle', 'nr' : 99}))
1928    call assert_equal(-1, g:Xsetlist([], ' ',
1929		\ {'title' : 'SomeTitle', 'nr' : 'abc'}))
1930
1931    if a:cchar == 'c'
1932	copen
1933	call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
1934	cclose
1935    endif
1936
1937    " Invalid arguments
1938    call assert_fails('call g:Xgetlist([])', 'E715')
1939    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
1940    let s = g:Xsetlist([], 'a', {'abc':1})
1941    call assert_equal(-1, s)
1942
1943    call assert_equal({}, g:Xgetlist({'abc':1}))
1944    call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
1945    call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
1946
1947    if a:cchar == 'l'
1948	call assert_equal({}, getloclist(99, {'title': 1}))
1949    endif
1950
1951    " Context related tests
1952    let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
1953    call assert_equal(0, s)
1954    call test_garbagecollect_now()
1955    let d = g:Xgetlist({'context':1})
1956    call assert_equal([1,2,3], d.context)
1957    call g:Xsetlist([], 'a', {'context':{'color':'green'}})
1958    let d = g:Xgetlist({'context':1})
1959    call assert_equal({'color':'green'}, d.context)
1960    call g:Xsetlist([], 'a', {'context':"Context info"})
1961    let d = g:Xgetlist({'context':1})
1962    call assert_equal("Context info", d.context)
1963    call g:Xsetlist([], 'a', {'context':246})
1964    let d = g:Xgetlist({'context':1})
1965    call assert_equal(246, d.context)
1966    if a:cchar == 'l'
1967	" Test for copying context across two different location lists
1968	new | only
1969	let w1_id = win_getid()
1970	let l = [1]
1971	call setloclist(0, [], 'a', {'context':l})
1972	new
1973	let w2_id = win_getid()
1974	call add(l, 2)
1975	call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
1976	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1977	unlet! l
1978	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1979	only
1980	call setloclist(0, [], 'f')
1981	call assert_equal('', getloclist(0, {'context':1}).context)
1982    endif
1983
1984    " Test for changing the context of previous quickfix lists
1985    call g:Xsetlist([], 'f')
1986    Xexpr "One"
1987    Xexpr "Two"
1988    Xexpr "Three"
1989    call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
1990    call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
1991    " Also, check for setting the context using quickfix list number zero.
1992    call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
1993    call test_garbagecollect_now()
1994    let l = g:Xgetlist({'nr' : 1, 'context' : 1})
1995    call assert_equal([1], l.context)
1996    let l = g:Xgetlist({'nr' : 2, 'context' : 1})
1997    call assert_equal([2], l.context)
1998    let l = g:Xgetlist({'nr' : 3, 'context' : 1})
1999    call assert_equal([3], l.context)
2000
2001    " Test for changing the context through reference and for garbage
2002    " collection of quickfix context
2003    let l = ["red"]
2004    call g:Xsetlist([], ' ', {'context' : l})
2005    call add(l, "blue")
2006    let x = g:Xgetlist({'context' : 1})
2007    call add(x.context, "green")
2008    call assert_equal(["red", "blue", "green"], l)
2009    call assert_equal(["red", "blue", "green"], x.context)
2010    unlet l
2011    call test_garbagecollect_now()
2012    let m = g:Xgetlist({'context' : 1})
2013    call assert_equal(["red", "blue", "green"], m.context)
2014
2015    " Test for setting/getting items
2016    Xexpr ""
2017    let qfprev = g:Xgetlist({'nr':0})
2018    let s = g:Xsetlist([], ' ', {'title':'Green',
2019		\ 'items' : [{'filename':'F1', 'lnum':10}]})
2020    call assert_equal(0, s)
2021    let qfcur = g:Xgetlist({'nr':0})
2022    call assert_true(qfcur.nr == qfprev.nr + 1)
2023    let l = g:Xgetlist({'items':1})
2024    call assert_equal('F1', bufname(l.items[0].bufnr))
2025    call assert_equal(10, l.items[0].lnum)
2026    call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2027		\  {'filename':'F2', 'lnum':30}]})
2028    let l = g:Xgetlist({'items':1})
2029    call assert_equal('F2', bufname(l.items[2].bufnr))
2030    call assert_equal(30, l.items[2].lnum)
2031    call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2032    let l = g:Xgetlist({'items':1})
2033    call assert_equal('F3', bufname(l.items[0].bufnr))
2034    call assert_equal(40, l.items[0].lnum)
2035    call g:Xsetlist([], 'r', {'items' : []})
2036    let l = g:Xgetlist({'items':1})
2037    call assert_equal(0, len(l.items))
2038
2039    call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2040    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2041    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2042    call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2043
2044    " Test for getting id of window associated with a location list window
2045    if a:cchar == 'l'
2046      only
2047      call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2048      let wid = win_getid()
2049      Xopen
2050      call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2051      wincmd w
2052      call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2053      only
2054    endif
2055
2056    " The following used to crash Vim with address sanitizer
2057    call g:Xsetlist([], 'f')
2058    call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2059    call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
2060
2061    " Try setting the items using a string
2062    call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
2063
2064    " Save and restore the quickfix stack
2065    call g:Xsetlist([], 'f')
2066    call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2067    Xexpr "File1:10:Line1"
2068    Xexpr "File2:20:Line2"
2069    Xexpr "File3:30:Line3"
2070    let last_qf = g:Xgetlist({'nr':'$'}).nr
2071    call assert_equal(3, last_qf)
2072    let qstack = []
2073    for i in range(1, last_qf)
2074	let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2075    endfor
2076    call g:Xsetlist([], 'f')
2077    for i in range(len(qstack))
2078	call g:Xsetlist([], ' ', qstack[i])
2079    endfor
2080    call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2081    call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2082    call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2083    call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2084    call g:Xsetlist([], 'f')
2085
2086    " Swap two quickfix lists
2087    Xexpr "File1:10:Line10"
2088    Xexpr "File2:20:Line20"
2089    Xexpr "File3:30:Line30"
2090    call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2091    call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2092    let l1=g:Xgetlist({'nr':1,'all':1})
2093    let l2=g:Xgetlist({'nr':2,'all':1})
2094    let save_id = l1.id
2095    let l1.id=l2.id
2096    let l2.id=save_id
2097    call g:Xsetlist([], 'r', l1)
2098    call g:Xsetlist([], 'r', l2)
2099    let newl1=g:Xgetlist({'nr':1,'all':1})
2100    let newl2=g:Xgetlist({'nr':2,'all':1})
2101    call assert_equal('Fruits', newl1.title)
2102    call assert_equal(['Fruits'], newl1.context)
2103    call assert_equal('Line20', newl1.items[0].text)
2104    call assert_equal('Colors', newl2.title)
2105    call assert_equal(['Colors'], newl2.context)
2106    call assert_equal('Line10', newl2.items[0].text)
2107    call g:Xsetlist([], 'f')
2108endfunc
2109
2110func Test_qf_property()
2111    call Xproperty_tests('c')
2112    call Xproperty_tests('l')
2113endfunc
2114
2115" Test for setting the current index in the location/quickfix list
2116func Xtest_setqfidx(cchar)
2117  call s:setup_commands(a:cchar)
2118
2119  Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2120  Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2121  Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2122
2123  call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2124  call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2125  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2126  Xolder 2
2127  Xopen
2128  call assert_equal(3, line('.'))
2129  Xnewer
2130  call assert_equal(2, line('.'))
2131  Xnewer
2132  call assert_equal(2, line('.'))
2133  " Update the current index with the quickfix window open
2134  wincmd w
2135  call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2136  Xopen
2137  call assert_equal(3, line('.'))
2138  Xclose
2139
2140  " Set the current index to the last entry
2141  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2142  call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2143  " A large value should set the index to the last index
2144  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2145  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2146  call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2147  " Invalid index values
2148  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2149  call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2150  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2151  call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2152  call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2153  call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2154  call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2155
2156  call g:Xsetlist([], 'f')
2157  new | only
2158endfunc
2159
2160func Test_setqfidx()
2161  call Xtest_setqfidx('c')
2162  call Xtest_setqfidx('l')
2163endfunc
2164
2165" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
2166func QfAutoCmdHandler(loc, cmd)
2167  call add(g:acmds, a:loc . a:cmd)
2168endfunc
2169
2170func Test_Autocmd()
2171  autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2172  autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2173
2174  let g:acmds = []
2175  cexpr "F1:10:Line 10"
2176  caddexpr "F1:20:Line 20"
2177  cgetexpr "F1:30:Line 30"
2178  cexpr ""
2179  caddexpr ""
2180  cgetexpr ""
2181  silent! cexpr non_existing_func()
2182  silent! caddexpr non_existing_func()
2183  silent! cgetexpr non_existing_func()
2184  let l = ['precexpr',
2185	      \ 'postcexpr',
2186	      \ 'precaddexpr',
2187	      \ 'postcaddexpr',
2188	      \ 'precgetexpr',
2189	      \ 'postcgetexpr',
2190	      \ 'precexpr',
2191	      \ 'postcexpr',
2192	      \ 'precaddexpr',
2193	      \ 'postcaddexpr',
2194	      \ 'precgetexpr',
2195	      \ 'postcgetexpr',
2196	      \ 'precexpr',
2197	      \ 'precaddexpr',
2198	      \ 'precgetexpr']
2199  call assert_equal(l, g:acmds)
2200
2201  let g:acmds = []
2202  enew! | call append(0, "F2:10:Line 10")
2203  cbuffer!
2204  enew! | call append(0, "F2:20:Line 20")
2205  cgetbuffer
2206  enew! | call append(0, "F2:30:Line 30")
2207  caddbuffer
2208  new
2209  let bnum = bufnr('%')
2210  bunload
2211  exe 'silent! cbuffer! ' . bnum
2212  exe 'silent! cgetbuffer ' . bnum
2213  exe 'silent! caddbuffer ' . bnum
2214  enew!
2215  let l = ['precbuffer',
2216	      \ 'postcbuffer',
2217	      \ 'precgetbuffer',
2218	      \ 'postcgetbuffer',
2219	      \ 'precaddbuffer',
2220	      \ 'postcaddbuffer',
2221	      \ 'precbuffer',
2222	      \ 'precgetbuffer',
2223	      \ 'precaddbuffer']
2224  call assert_equal(l, g:acmds)
2225
2226  call writefile(['Xtest:1:Line1'], 'Xtest')
2227  call writefile([], 'Xempty')
2228  let g:acmds = []
2229  cfile Xtest
2230  caddfile Xtest
2231  cgetfile Xtest
2232  cfile Xempty
2233  caddfile Xempty
2234  cgetfile Xempty
2235  silent! cfile do_not_exist
2236  silent! caddfile do_not_exist
2237  silent! cgetfile do_not_exist
2238  let l = ['precfile',
2239	      \ 'postcfile',
2240	      \ 'precaddfile',
2241	      \ 'postcaddfile',
2242	      \ 'precgetfile',
2243	      \ 'postcgetfile',
2244	      \ 'precfile',
2245	      \ 'postcfile',
2246	      \ 'precaddfile',
2247	      \ 'postcaddfile',
2248	      \ 'precgetfile',
2249	      \ 'postcgetfile',
2250	      \ 'precfile',
2251	      \ 'postcfile',
2252	      \ 'precaddfile',
2253	      \ 'postcaddfile',
2254	      \ 'precgetfile',
2255	      \ 'postcgetfile']
2256  call assert_equal(l, g:acmds)
2257
2258  let g:acmds = []
2259  helpgrep quickfix
2260  silent! helpgrep non_existing_help_topic
2261  vimgrep test Xtest
2262  vimgrepadd test Xtest
2263  silent! vimgrep non_existing_test Xtest
2264  silent! vimgrepadd non_existing_test Xtest
2265  set makeprg=
2266  silent! make
2267  set makeprg&
2268  let l = ['prehelpgrep',
2269	      \ 'posthelpgrep',
2270	      \ 'prehelpgrep',
2271	      \ 'posthelpgrep',
2272	      \ 'previmgrep',
2273	      \ 'postvimgrep',
2274	      \ 'previmgrepadd',
2275	      \ 'postvimgrepadd',
2276	      \ 'previmgrep',
2277	      \ 'postvimgrep',
2278	      \ 'previmgrepadd',
2279	      \ 'postvimgrepadd',
2280	      \ 'premake',
2281	      \ 'postmake']
2282  call assert_equal(l, g:acmds)
2283
2284  if has('unix')
2285    " Run this test only on Unix-like systems. The grepprg may not be set on
2286    " non-Unix systems.
2287    " The following lines are used for the grep test. Don't remove.
2288    " Grep_Autocmd_Text: Match 1
2289    " GrepAdd_Autocmd_Text: Match 2
2290    let g:acmds = []
2291    silent grep Grep_Autocmd_Text test_quickfix.vim
2292    silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2293    silent grep abc123def Xtest
2294    silent grepadd abc123def Xtest
2295    let l = ['pregrep',
2296		\ 'postgrep',
2297		\ 'pregrepadd',
2298		\ 'postgrepadd',
2299		\ 'pregrep',
2300		\ 'postgrep',
2301		\ 'pregrepadd',
2302		\ 'postgrepadd']
2303    call assert_equal(l, g:acmds)
2304  endif
2305
2306  call delete('Xtest')
2307  call delete('Xempty')
2308  au! QuickFixCmdPre
2309  au! QuickFixCmdPost
2310endfunc
2311
2312func Test_Autocmd_Exception()
2313  set efm=%m
2314  lgetexpr '?'
2315
2316  try
2317    call DoesNotExit()
2318  catch
2319    lgetexpr '1'
2320  finally
2321    lgetexpr '1'
2322  endtry
2323
2324  call assert_equal('1', getloclist(0)[0].text)
2325
2326  set efm&vim
2327endfunc
2328
2329func Test_caddbuffer_wrong()
2330  " This used to cause a memory access in freed memory.
2331  let save_efm = &efm
2332  set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2333  cgetexpr ['WWWW', 'EEEE', 'CCCC']
2334  let &efm = save_efm
2335  caddbuffer
2336  bwipe!
2337endfunc
2338
2339func Test_caddexpr_wrong()
2340  " This used to cause a memory access in freed memory.
2341  cbuffer
2342  cbuffer
2343  copen
2344  let save_efm = &efm
2345  set efm=%
2346  call assert_fails('caddexpr ""', 'E376:')
2347  let &efm = save_efm
2348endfunc
2349
2350func Test_dirstack_cleanup()
2351  " This used to cause a memory access in freed memory.
2352  let save_efm = &efm
2353  lexpr '0'
2354  lopen
2355  fun X(c)
2356    let save_efm=&efm
2357    set efm=%D%f
2358    if a:c == 'c'
2359      caddexpr '::'
2360    else
2361      laddexpr ':0:0'
2362    endif
2363    let &efm=save_efm
2364  endfun
2365  call X('c')
2366  call X('l')
2367  call setqflist([], 'r')
2368  caddbuffer
2369  let &efm = save_efm
2370endfunc
2371
2372" Tests for jumping to entries from the location list window and quickfix
2373" window
2374func Test_cwindow_jump()
2375  set efm=%f%%%l%%%m
2376  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2377  lopen | only
2378  lfirst
2379  call assert_true(winnr('$') == 2)
2380  call assert_true(winnr() == 1)
2381  " Location list for the new window should be set
2382  call assert_true(getloclist(0)[2].text == 'Line 30')
2383
2384  " Open a scratch buffer
2385  " Open a new window and create a location list
2386  " Open the location list window and close the other window
2387  " Jump to an entry.
2388  " Should create a new window and jump to the entry. The scratch buffer
2389  " should not be used.
2390  enew | only
2391  set buftype=nofile
2392  below new
2393  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2394  lopen
2395  2wincmd c
2396  lnext
2397  call assert_true(winnr('$') == 3)
2398  call assert_true(winnr() == 2)
2399
2400  " Open two windows with two different location lists
2401  " Open the location list window and close the previous window
2402  " Jump to an entry in the location list window
2403  " Should open the file in the first window and not set the location list.
2404  enew | only
2405  lgetexpr ["F1%5%Line 5"]
2406  below new
2407  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2408  lopen
2409  2wincmd c
2410  lnext
2411  call assert_true(winnr() == 1)
2412  call assert_true(getloclist(0)[0].text == 'Line 5')
2413
2414  enew | only
2415  cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2416  copen
2417  cnext
2418  call assert_true(winnr('$') == 2)
2419  call assert_true(winnr() == 1)
2420
2421  enew | only
2422  set efm&vim
2423endfunc
2424
2425func XvimgrepTests(cchar)
2426  call s:setup_commands(a:cchar)
2427
2428  call writefile(['Editor:VIM vim',
2429	      \ 'Editor:Emacs EmAcS',
2430	      \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2431  call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2432
2433  " Error cases
2434  call assert_fails('Xvimgrep /abc *', 'E682:')
2435
2436  let @/=''
2437  call assert_fails('Xvimgrep // *', 'E35:')
2438
2439  call assert_fails('Xvimgrep abc', 'E683:')
2440  call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2441  call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2442
2443  Xexpr ""
2444  Xvimgrepadd Notepad Xtestfile1
2445  Xvimgrepadd MacOS Xtestfile2
2446  let l = g:Xgetlist()
2447  call assert_equal(2, len(l))
2448  call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2449
2450  Xvimgrep #\cvim#g Xtestfile?
2451  let l = g:Xgetlist()
2452  call assert_equal(2, len(l))
2453  call assert_equal(8, l[0].col)
2454  call assert_equal(12, l[1].col)
2455
2456  1Xvimgrep ?Editor? Xtestfile*
2457  let l = g:Xgetlist()
2458  call assert_equal(1, len(l))
2459  call assert_equal('Editor:VIM vim', l[0].text)
2460
2461  edit +3 Xtestfile2
2462  Xvimgrep +\cemacs+j Xtestfile1
2463  let l = g:Xgetlist()
2464  call assert_equal('Xtestfile2', bufname(''))
2465  call assert_equal('Editor:Emacs EmAcS', l[0].text)
2466
2467  " Test for unloading a buffer after vimgrep searched the buffer
2468  %bwipe
2469  Xvimgrep /Editor/j Xtestfile*
2470  call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2471  call assert_equal([], getbufinfo('Xtestfile2'))
2472
2473  call delete('Xtestfile1')
2474  call delete('Xtestfile2')
2475endfunc
2476
2477" Tests for the :vimgrep command
2478func Test_vimgrep()
2479  call XvimgrepTests('c')
2480  call XvimgrepTests('l')
2481endfunc
2482
2483" Test for incsearch highlighting of the :vimgrep pattern
2484" This test used to cause "E315: ml_get: invalid lnum" errors.
2485func Test_vimgrep_incsearch()
2486  enew
2487  set incsearch
2488  call test_override("char_avail", 1)
2489
2490  call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2491  let l = getqflist()
2492  call assert_equal(2, len(l))
2493
2494  call test_override("ALL", 0)
2495  set noincsearch
2496endfunc
2497
2498func XfreeTests(cchar)
2499  call s:setup_commands(a:cchar)
2500
2501  enew | only
2502
2503  " Deleting the quickfix stack should work even When the current list is
2504  " somewhere in the middle of the stack
2505  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2506  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2507  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2508  Xolder
2509  call g:Xsetlist([], 'f')
2510  call assert_equal(0, len(g:Xgetlist()))
2511
2512  " After deleting the stack, adding a new list should create a stack with a
2513  " single list.
2514  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2515  call assert_equal(1, g:Xgetlist({'all':1}).nr)
2516
2517  " Deleting the stack from a quickfix window should update/clear the
2518  " quickfix/location list window.
2519  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2520  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2521  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2522  Xolder
2523  Xwindow
2524  call g:Xsetlist([], 'f')
2525  call assert_equal(2, winnr('$'))
2526  call assert_equal(1, line('$'))
2527  Xclose
2528
2529  " Deleting the stack from a non-quickfix window should update/clear the
2530  " quickfix/location list window.
2531  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2532  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2533  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2534  Xolder
2535  Xwindow
2536  wincmd p
2537  call g:Xsetlist([], 'f')
2538  call assert_equal(0, len(g:Xgetlist()))
2539  wincmd p
2540  call assert_equal(2, winnr('$'))
2541  call assert_equal(1, line('$'))
2542
2543  " After deleting the location list stack, if the location list window is
2544  " opened, then a new location list should be created. So opening the
2545  " location list window again should not create a new window.
2546  if a:cchar == 'l'
2547      lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2548      wincmd p
2549      lopen
2550      call assert_equal(2, winnr('$'))
2551  endif
2552  Xclose
2553endfunc
2554
2555" Tests for the quickfix free functionality
2556func Test_qf_free()
2557  call XfreeTests('c')
2558  call XfreeTests('l')
2559endfunc
2560
2561" Test for buffer overflow when parsing lines and adding new entries to
2562" the quickfix list.
2563func Test_bufoverflow()
2564  set efm=%f:%l:%m
2565  cgetexpr ['File1:100:' . repeat('x', 1025)]
2566
2567  set efm=%+GCompiler:\ %.%#,%f:%l:%m
2568  cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2569
2570  set efm=%DEntering\ directory\ %f,%f:%l:%m
2571  cgetexpr ['Entering directory ' . repeat('a', 1006),
2572	      \ 'File1:10:Hello World']
2573  set efm&vim
2574endfunc
2575
2576" Tests for getting the quickfix stack size
2577func XsizeTests(cchar)
2578  call s:setup_commands(a:cchar)
2579
2580  call g:Xsetlist([], 'f')
2581  call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2582  call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2583  call assert_equal(0, g:Xgetlist({'nr':0}).nr)
2584
2585  Xexpr "File1:10:Line1"
2586  Xexpr "File2:20:Line2"
2587  Xexpr "File3:30:Line3"
2588  Xolder | Xolder
2589  call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2590  call g:Xsetlist([], 'f')
2591
2592  Xexpr "File1:10:Line1"
2593  Xexpr "File2:20:Line2"
2594  Xexpr "File3:30:Line3"
2595  Xolder | Xolder
2596  call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2597  call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2598endfunc
2599
2600func Test_Qf_Size()
2601  call XsizeTests('c')
2602  call XsizeTests('l')
2603endfunc
2604
2605func Test_cclose_from_copen()
2606    augroup QF_Test
2607	au!
2608        au FileType qf :call assert_fails(':cclose', 'E788')
2609    augroup END
2610    copen
2611    augroup QF_Test
2612	au!
2613    augroup END
2614    augroup! QF_Test
2615endfunc
2616
2617func Test_cclose_in_autocmd()
2618  " Problem is only triggered if "starting" is zero, so that the OptionsSet
2619  " event will be triggered.
2620  call test_override('starting', 1)
2621  augroup QF_Test
2622    au!
2623    au FileType qf :call assert_fails(':cclose', 'E788')
2624  augroup END
2625  copen
2626  augroup QF_Test
2627    au!
2628  augroup END
2629  augroup! QF_Test
2630  call test_override('starting', 0)
2631endfunc
2632
2633" Check that ":file" without an argument is possible even when "curbuf_lock"
2634" is set.
2635func Test_file_from_copen()
2636  " Works without argument.
2637  augroup QF_Test
2638    au!
2639    au FileType qf file
2640  augroup END
2641  copen
2642
2643  augroup QF_Test
2644    au!
2645  augroup END
2646  cclose
2647
2648  " Fails with argument.
2649  augroup QF_Test
2650    au!
2651    au FileType qf call assert_fails(':file foo', 'E788')
2652  augroup END
2653  copen
2654  augroup QF_Test
2655    au!
2656  augroup END
2657  cclose
2658
2659  augroup! QF_Test
2660endfunction
2661
2662func Test_resize_from_copen()
2663    augroup QF_Test
2664	au!
2665        au FileType qf resize 5
2666    augroup END
2667    try
2668	" This should succeed without any exception.  No other buffers are
2669	" involved in the autocmd.
2670	copen
2671    finally
2672	augroup QF_Test
2673	    au!
2674	augroup END
2675	augroup! QF_Test
2676    endtry
2677endfunc
2678
2679" Tests for the quickfix buffer b:changedtick variable
2680func Xchangedtick_tests(cchar)
2681  call s:setup_commands(a:cchar)
2682
2683  new | only
2684
2685  Xexpr "" | Xexpr "" | Xexpr ""
2686
2687  Xopen
2688  Xolder
2689  Xolder
2690  Xaddexpr "F1:10:Line10"
2691  Xaddexpr "F2:20:Line20"
2692  call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
2693  call g:Xsetlist([], 'f')
2694  call assert_equal(8, getbufvar('%', 'changedtick'))
2695  Xclose
2696endfunc
2697
2698func Test_changedtick()
2699  call Xchangedtick_tests('c')
2700  call Xchangedtick_tests('l')
2701endfunc
2702
2703" Tests for parsing an expression using setqflist()
2704func Xsetexpr_tests(cchar)
2705  call s:setup_commands(a:cchar)
2706
2707  let t = ["File1:10:Line10", "File1:20:Line20"]
2708  call g:Xsetlist([], ' ', {'lines' : t})
2709  call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
2710
2711  let l = g:Xgetlist()
2712  call assert_equal(3, len(l))
2713  call assert_equal(20, l[1].lnum)
2714  call assert_equal('Line30', l[2].text)
2715  call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
2716  let l = g:Xgetlist()
2717  call assert_equal(1, len(l))
2718  call assert_equal('Line5', l[0].text)
2719  call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
2720  call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
2721
2722  call g:Xsetlist([], 'f')
2723  " Add entries to multiple lists
2724  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
2725  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
2726  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
2727  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
2728  call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
2729  call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
2730
2731  " Adding entries using a custom efm
2732  set efm&
2733  call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
2734				\ 'lines' : ["F1#10#L10", "F2#20#L20"]})
2735  call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
2736  call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
2737  call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
2738  call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
2739  call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
2740				\ 'lines' : ['F1:10:L10']}))
2741endfunc
2742
2743func Test_setexpr()
2744  call Xsetexpr_tests('c')
2745  call Xsetexpr_tests('l')
2746endfunc
2747
2748" Tests for per quickfix/location list directory stack
2749func Xmultidirstack_tests(cchar)
2750  call s:setup_commands(a:cchar)
2751
2752  call g:Xsetlist([], 'f')
2753  Xexpr "" | Xexpr ""
2754
2755  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
2756  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
2757  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
2758  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
2759
2760  let l1 = g:Xgetlist({'nr':1, 'items':1})
2761  let l2 = g:Xgetlist({'nr':2, 'items':1})
2762  call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
2763  call assert_equal(3, l1.items[1].lnum)
2764  call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
2765  call assert_equal(5, l2.items[1].lnum)
2766endfunc
2767
2768func Test_multidirstack()
2769  call mkdir('Xone/a', 'p')
2770  call mkdir('Xtwo/a', 'p')
2771  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2772  call writefile(lines, 'Xone/a/one.txt')
2773  call writefile(lines, 'Xtwo/a/two.txt')
2774  let save_efm = &efm
2775  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2776
2777  call Xmultidirstack_tests('c')
2778  call Xmultidirstack_tests('l')
2779
2780  let &efm = save_efm
2781  call delete('Xone', 'rf')
2782  call delete('Xtwo', 'rf')
2783endfunc
2784
2785" Tests for per quickfix/location list file stack
2786func Xmultifilestack_tests(cchar)
2787  call s:setup_commands(a:cchar)
2788
2789  call g:Xsetlist([], 'f')
2790  Xexpr "" | Xexpr ""
2791
2792  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
2793  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
2794  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
2795  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
2796
2797  let l1 = g:Xgetlist({'nr':1, 'items':1})
2798  let l2 = g:Xgetlist({'nr':2, 'items':1})
2799  call assert_equal('one.txt', bufname(l1.items[1].bufnr))
2800  call assert_equal(3, l1.items[1].lnum)
2801  call assert_equal('two.txt', bufname(l2.items[1].bufnr))
2802  call assert_equal(5, l2.items[1].lnum)
2803
2804  " Test for start of a new error line in the same line where a previous
2805  " error line ends with a file stack.
2806  let efm_val = 'Error\ l%l\ in\ %f,'
2807  let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
2808  let l = g:Xgetlist({'lines' : [
2809	      \ '(one.txt',
2810	      \ 'Error l4 in one.txt',
2811	      \ ') (two.txt',
2812	      \ 'Error l6 in two.txt',
2813	      \ ')',
2814	      \ 'Error l8 in one.txt'
2815	      \ ], 'efm' : efm_val})
2816  call assert_equal(3, len(l.items))
2817  call assert_equal('one.txt', bufname(l.items[0].bufnr))
2818  call assert_equal(4, l.items[0].lnum)
2819  call assert_equal('one.txt', l.items[0].text)
2820  call assert_equal('two.txt', bufname(l.items[1].bufnr))
2821  call assert_equal(6, l.items[1].lnum)
2822  call assert_equal('two.txt', l.items[1].text)
2823  call assert_equal('one.txt', bufname(l.items[2].bufnr))
2824  call assert_equal(8, l.items[2].lnum)
2825  call assert_equal('', l.items[2].text)
2826endfunc
2827
2828func Test_multifilestack()
2829  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2830  call writefile(lines, 'one.txt')
2831  call writefile(lines, 'two.txt')
2832  let save_efm = &efm
2833  set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
2834
2835  call Xmultifilestack_tests('c')
2836  call Xmultifilestack_tests('l')
2837
2838  let &efm = save_efm
2839  call delete('one.txt')
2840  call delete('two.txt')
2841endfunc
2842
2843" Tests for per buffer 'efm' setting
2844func Test_perbuf_efm()
2845  call writefile(["File1-10-Line10"], 'one.txt')
2846  call writefile(["File2#20#Line20"], 'two.txt')
2847  set efm=%f#%l#%m
2848  new | only
2849  new
2850  setlocal efm=%f-%l-%m
2851  cfile one.txt
2852  wincmd w
2853  caddfile two.txt
2854
2855  let l = getqflist()
2856  call assert_equal(10, l[0].lnum)
2857  call assert_equal('Line20', l[1].text)
2858
2859  set efm&
2860  new | only
2861  call delete('one.txt')
2862  call delete('two.txt')
2863endfunc
2864
2865" Open multiple help windows using ":lhelpgrep
2866" This test used to crash Vim
2867func Test_Multi_LL_Help()
2868    new | only
2869    lhelpgrep window
2870    lopen
2871    e#
2872    lhelpgrep buffer
2873    call assert_equal(3, winnr('$'))
2874    call assert_true(len(getloclist(1)) != 0)
2875    call assert_true(len(getloclist(2)) != 0)
2876    new | only
2877endfunc
2878
2879" Tests for adding new quickfix lists using setqflist()
2880func XaddQf_tests(cchar)
2881  call s:setup_commands(a:cchar)
2882
2883  " Create a new list using ' ' for action
2884  call g:Xsetlist([], 'f')
2885  call g:Xsetlist([], ' ', {'title' : 'Test1'})
2886  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2887  call assert_equal(1, l.nr)
2888  call assert_equal('Test1', l.title)
2889
2890  " Create a new list using ' ' for action and '$' for 'nr'
2891  call g:Xsetlist([], 'f')
2892  call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
2893  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2894  call assert_equal(1, l.nr)
2895  call assert_equal('Test2', l.title)
2896
2897  " Create a new list using 'a' for action
2898  call g:Xsetlist([], 'f')
2899  call g:Xsetlist([], 'a', {'title' : 'Test3'})
2900  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2901  call assert_equal(1, l.nr)
2902  call assert_equal('Test3', l.title)
2903
2904  " Create a new list using 'a' for action and '$' for 'nr'
2905  call g:Xsetlist([], 'f')
2906  call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
2907  call g:Xsetlist([], 'a', {'title' : 'Test4'})
2908  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2909  call assert_equal(1, l.nr)
2910  call assert_equal('Test4', l.title)
2911
2912  " Adding a quickfix list should remove all the lists following the current
2913  " list.
2914  Xexpr "" | Xexpr "" | Xexpr ""
2915  silent! 10Xolder
2916  call g:Xsetlist([], ' ', {'title' : 'Test5'})
2917  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2918  call assert_equal(2, l.nr)
2919  call assert_equal('Test5', l.title)
2920
2921  " Add a quickfix list using '$' as the list number.
2922  let lastqf = g:Xgetlist({'nr':'$'}).nr
2923  silent! 99Xolder
2924  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
2925  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2926  call assert_equal(lastqf + 1, l.nr)
2927  call assert_equal('Test6', l.title)
2928
2929  " Add a quickfix list using 'nr' set to one more than the quickfix
2930  " list size.
2931  let lastqf = g:Xgetlist({'nr':'$'}).nr
2932  silent! 99Xolder
2933  call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
2934  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2935  call assert_equal(lastqf + 1, l.nr)
2936  call assert_equal('Test7', l.title)
2937
2938  " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
2939  exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
2940  silent! 99Xolder
2941  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
2942  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2943  call assert_equal(10, l.nr)
2944  call assert_equal('Test8', l.title)
2945
2946  " Add a quickfix list using 'nr' set to a value greater than 10
2947  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
2948
2949  " Try adding a quickfix list with 'nr' set to a value greater than the
2950  " quickfix list size but less than 10.
2951  call g:Xsetlist([], 'f')
2952  Xexpr "" | Xexpr "" | Xexpr ""
2953  silent! 99Xolder
2954  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
2955
2956  " Add a quickfix list using 'nr' set to a some string or list
2957  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
2958endfunc
2959
2960func Test_add_qf()
2961  call XaddQf_tests('c')
2962  call XaddQf_tests('l')
2963endfunc
2964
2965" Test for getting the quickfix list items from some text without modifying
2966" the quickfix stack
2967func XgetListFromLines(cchar)
2968  call s:setup_commands(a:cchar)
2969  call g:Xsetlist([], 'f')
2970
2971  let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
2972  call assert_equal(2, len(l))
2973  call assert_equal(30, l[1].lnum)
2974
2975  call assert_equal({}, g:Xgetlist({'lines' : 10}))
2976  call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
2977  call assert_equal([], g:Xgetlist({'lines' : []}).items)
2978  call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
2979
2980  " Parse text using a custom efm
2981  set efm&
2982  let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
2983  call assert_equal('Line30', l[0].text)
2984  let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
2985  call assert_equal('File3:30:Line30', l[0].text)
2986  let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
2987  call assert_equal({}, l)
2988  call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
2989  call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
2990
2991  " Make sure that the quickfix stack is not modified
2992  call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
2993endfunc
2994
2995func Test_get_list_from_lines()
2996  call XgetListFromLines('c')
2997  call XgetListFromLines('l')
2998endfunc
2999
3000" Tests for the quickfix list id
3001func Xqfid_tests(cchar)
3002  call s:setup_commands(a:cchar)
3003
3004  call g:Xsetlist([], 'f')
3005  call assert_equal(0, g:Xgetlist({'id':0}).id)
3006  Xexpr ''
3007  let start_id = g:Xgetlist({'id' : 0}).id
3008  Xexpr '' | Xexpr ''
3009  Xolder
3010  call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3011  call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3012  call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
3013  call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
3014  call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
3015  call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3016  call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
3017
3018  call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3019  call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
3020  call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
3021  call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3022  call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3023  call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3024
3025  let qfid = g:Xgetlist({'id':0, 'nr':0})
3026  call g:Xsetlist([], 'f')
3027  call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
3028endfunc
3029
3030func Test_qf_id()
3031  call Xqfid_tests('c')
3032  call Xqfid_tests('l')
3033endfunc
3034
3035func Xqfjump_tests(cchar)
3036  call s:setup_commands(a:cchar)
3037
3038  call writefile(["Line1\tFoo", "Line2"], 'F1')
3039  call writefile(["Line1\tBar", "Line2"], 'F2')
3040  call writefile(["Line1\tBaz", "Line2"], 'F3')
3041
3042  call g:Xsetlist([], 'f')
3043
3044  " Tests for
3045  "   Jumping to a line using a pattern
3046  "   Jumping to a column greater than the last column in a line
3047  "   Jumping to a line greater than the last line in the file
3048  let l = []
3049  for i in range(1, 7)
3050    call add(l, {})
3051  endfor
3052  let l[0].filename='F1'
3053  let l[0].pattern='Line1'
3054  let l[1].filename='F2'
3055  let l[1].pattern='Line1'
3056  let l[2].filename='F3'
3057  let l[2].pattern='Line1'
3058  let l[3].filename='F3'
3059  let l[3].lnum=1
3060  let l[3].col=9
3061  let l[3].vcol=1
3062  let l[4].filename='F3'
3063  let l[4].lnum=99
3064  let l[5].filename='F3'
3065  let l[5].lnum=1
3066  let l[5].col=99
3067  let l[5].vcol=1
3068  let l[6].filename='F3'
3069  let l[6].pattern='abcxyz'
3070
3071  call g:Xsetlist([], ' ', {'items' : l})
3072  Xopen | only
3073  2Xnext
3074  call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
3075  call assert_equal('F3', bufname('%'))
3076  Xnext
3077  call assert_equal(7, col('.'))
3078  Xnext
3079  call assert_equal(2, line('.'))
3080  Xnext
3081  call assert_equal(9, col('.'))
3082  2
3083  Xnext
3084  call assert_equal(2, line('.'))
3085
3086  if a:cchar == 'l'
3087    " When jumping to a location list entry in the location list window and
3088    " no usable windows are available, then a new window should be opened.
3089    enew! | new | only
3090    call g:Xsetlist([], 'f')
3091    setlocal buftype=nofile
3092    new
3093    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']})
3094    Xopen
3095    let winid = win_getid()
3096    wincmd p
3097    close
3098    call win_gotoid(winid)
3099    Xnext
3100    call assert_equal(3, winnr('$'))
3101    call assert_equal(1, winnr())
3102    call assert_equal(2, line('.'))
3103
3104    " When jumping to an entry in the location list window and the window
3105    " associated with the location list is not present and a window containing
3106    " the file is already present, then that window should be used.
3107    close
3108    belowright new
3109    call g:Xsetlist([], 'f')
3110    edit F3
3111    call win_gotoid(winid)
3112    Xlast
3113    call assert_equal(3, winnr())
3114    call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3115    call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3116  endif
3117
3118  " Cleanup
3119  enew!
3120  new | only
3121
3122  call delete('F1')
3123  call delete('F2')
3124  call delete('F3')
3125endfunc
3126
3127func Test_qfjump()
3128  call Xqfjump_tests('c')
3129  call Xqfjump_tests('l')
3130endfunc
3131
3132" Tests for the getqflist() and getloclist() functions when the list is not
3133" present or is empty
3134func Xgetlist_empty_tests(cchar)
3135  call s:setup_commands(a:cchar)
3136
3137  " Empty quickfix stack
3138  call g:Xsetlist([], 'f')
3139  call assert_equal('', g:Xgetlist({'context' : 0}).context)
3140  call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3141  call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3142  call assert_equal([], g:Xgetlist({'items' : 0}).items)
3143  call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3144  call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3145  call assert_equal('', g:Xgetlist({'title' : 0}).title)
3146  call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
3147  call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
3148  if a:cchar == 'c'
3149    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3150		  \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
3151		  \ 'title' : '', 'winid' : 0, 'changedtick': 0},
3152		  \ g:Xgetlist({'all' : 0}))
3153  else
3154    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3155		\ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
3156		\ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
3157		\ 'qfbufnr' : 0},
3158		\ g:Xgetlist({'all' : 0}))
3159  endif
3160
3161  " Quickfix window with empty stack
3162  silent! Xopen
3163  let qfwinid = (a:cchar == 'c') ? win_getid() : 0
3164  let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
3165  call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3166  Xclose
3167
3168  " Empty quickfix list
3169  Xexpr ""
3170  call assert_equal('', g:Xgetlist({'context' : 0}).context)
3171  call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3172  call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3173  call assert_equal([], g:Xgetlist({'items' : 0}).items)
3174  call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3175  call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3176  call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3177  call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
3178  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3179
3180  let qfid = g:Xgetlist({'id' : 0}).id
3181  call g:Xsetlist([], 'f')
3182
3183  " Non-existing quickfix identifier
3184  call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3185  call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3186  call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3187  call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3188  call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3189  call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3190  call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3191  call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
3192  call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
3193  if a:cchar == 'c'
3194    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3195		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3196		\ 'qfbufnr' : qfbufnr,
3197		\ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3198  else
3199    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3200		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3201		\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
3202		\ g:Xgetlist({'id' : qfid, 'all' : 0}))
3203  endif
3204
3205  " Non-existing quickfix list number
3206  call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3207  call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3208  call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3209  call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3210  call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3211  call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3212  call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3213  call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
3214  call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
3215  if a:cchar == 'c'
3216    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3217		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3218		\ 'changedtick' : 0, 'qfbufnr' : qfbufnr},
3219		\ g:Xgetlist({'nr' : 5, 'all' : 0}))
3220  else
3221    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3222		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3223		\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
3224		\ g:Xgetlist({'nr' : 5, 'all' : 0}))
3225  endif
3226endfunc
3227
3228func Test_getqflist()
3229  call Xgetlist_empty_tests('c')
3230  call Xgetlist_empty_tests('l')
3231endfunc
3232
3233func Test_getqflist_invalid_nr()
3234  " The following commands used to crash Vim
3235  cexpr ""
3236  call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3237
3238  " Cleanup
3239  call setqflist([], 'r')
3240endfunc
3241
3242" Tests for the quickfix/location list changedtick
3243func Xqftick_tests(cchar)
3244  call s:setup_commands(a:cchar)
3245
3246  call g:Xsetlist([], 'f')
3247
3248  Xexpr "F1:10:Line10"
3249  let qfid = g:Xgetlist({'id' : 0}).id
3250  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3251  Xaddexpr "F2:20:Line20\nF2:21:Line21"
3252  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3253  call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3254  call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3255  call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3256  call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3257  call g:Xsetlist([], 'a', {'title' : 'New Title'})
3258  call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3259
3260  enew!
3261  call append(0, ["F5:50:L50", "F6:60:L60"])
3262  Xaddbuffer
3263  call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3264  enew!
3265
3266  call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3267  call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3268  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3269	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3270  call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3271  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3272	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3273  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3274  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3275	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3276  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3277
3278  call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3279  Xfile Xone
3280  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3281  Xaddfile Xone
3282  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3283
3284  " Test case for updating a non-current quickfix list
3285  call g:Xsetlist([], 'f')
3286  Xexpr "F1:1:L1"
3287  Xexpr "F2:2:L2"
3288  call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3289  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3290  call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3291
3292  call delete("Xone")
3293endfunc
3294
3295func Test_qf_tick()
3296  call Xqftick_tests('c')
3297  call Xqftick_tests('l')
3298endfunc
3299
3300" Test helpgrep with lang specifier
3301func Xtest_helpgrep_with_lang_specifier(cchar)
3302  call s:setup_commands(a:cchar)
3303  Xhelpgrep Vim@en
3304  call assert_equal('help', &filetype)
3305  call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3306  new | only
3307endfunc
3308
3309func Test_helpgrep_with_lang_specifier()
3310  call Xtest_helpgrep_with_lang_specifier('c')
3311  call Xtest_helpgrep_with_lang_specifier('l')
3312endfunc
3313
3314" The following test used to crash Vim.
3315" Open the location list window and close the regular window associated with
3316" the location list. When the garbage collection runs now, it incorrectly
3317" marks the location list context as not in use and frees the context.
3318func Test_ll_window_ctx()
3319  call setloclist(0, [], 'f')
3320  call setloclist(0, [], 'a', {'context' : []})
3321  lopen | only
3322  call test_garbagecollect_now()
3323  echo getloclist(0, {'context' : 1}).context
3324  enew | only
3325endfunc
3326
3327" The following test used to crash vim
3328func Test_lfile_crash()
3329  sp Xtest
3330  au QuickFixCmdPre * bw
3331  call assert_fails('lfile', 'E40')
3332  au! QuickFixCmdPre
3333endfunc
3334
3335" The following test used to crash vim
3336func Test_lbuffer_crash()
3337  sv Xtest
3338  augroup QF_Test
3339    au!
3340    au * * bw
3341  augroup END
3342  lbuffer
3343  augroup QF_Test
3344    au!
3345  augroup END
3346endfunc
3347
3348" The following test used to crash vim
3349func Test_lexpr_crash()
3350  augroup QF_Test
3351    au!
3352    au * * call setloclist(0, [], 'f')
3353  augroup END
3354  lexpr ""
3355  augroup QF_Test
3356    au!
3357  augroup END
3358
3359  enew | only
3360  augroup QF_Test
3361    au!
3362    au BufNew * call setloclist(0, [], 'f')
3363  augroup END
3364  lexpr 'x:1:x'
3365  augroup QF_Test
3366    au!
3367  augroup END
3368
3369  enew | only
3370  lexpr ''
3371  lopen
3372  augroup QF_Test
3373    au!
3374    au FileType * call setloclist(0, [], 'f')
3375  augroup END
3376  lexpr ''
3377  augroup QF_Test
3378    au!
3379  augroup END
3380endfunc
3381
3382" The following test used to crash Vim
3383func Test_lvimgrep_crash()
3384  sv Xtest
3385  augroup QF_Test
3386    au!
3387    au * * call setloclist(0, [], 'f')
3388  augroup END
3389  lvimgrep quickfix test_quickfix.vim
3390  augroup QF_Test
3391    au!
3392  augroup END
3393
3394  new | only
3395  augroup QF_Test
3396    au!
3397    au BufEnter * call setloclist(0, [], 'r')
3398  augroup END
3399  call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3400  augroup QF_Test
3401    au!
3402  augroup END
3403
3404  enew | only
3405endfunc
3406
3407" Test for the position of the quickfix and location list window
3408func Test_qfwin_pos()
3409  " Open two windows
3410  new | only
3411  new
3412  cexpr ['F1:10:L10']
3413  copen
3414  " Quickfix window should be the bottom most window
3415  call assert_equal(3, winnr())
3416  close
3417  " Open at the very top
3418  wincmd t
3419  topleft copen
3420  call assert_equal(1, winnr())
3421  close
3422  " open left of the current window
3423  wincmd t
3424  below new
3425  leftabove copen
3426  call assert_equal(2, winnr())
3427  close
3428  " open right of the current window
3429  rightbelow copen
3430  call assert_equal(3, winnr())
3431  close
3432endfunc
3433
3434" Tests for quickfix/location lists changed by autocommands when
3435" :vimgrep/:lvimgrep commands are running.
3436func Test_vimgrep_autocmd()
3437  call setqflist([], 'f')
3438  call writefile(['stars'], 'Xtest1.txt')
3439  call writefile(['stars'], 'Xtest2.txt')
3440
3441  " Test 1:
3442  " When searching for a pattern using :vimgrep, if the quickfix list is
3443  " changed by an autocmd, the results should be added to the correct quickfix
3444  " list.
3445  autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3446  silent vimgrep stars Xtest*.txt
3447  call assert_equal(1, getqflist({'nr' : 0}).nr)
3448  call assert_equal(3, getqflist({'nr' : '$'}).nr)
3449  call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3450  au! BufRead Xtest2.txt
3451
3452  " Test 2:
3453  " When searching for a pattern using :vimgrep, if the quickfix list is
3454  " freed, then a error should be given.
3455  silent! %bwipe!
3456  call setqflist([], 'f')
3457  autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3458  call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3459  au! BufRead Xtest2.txt
3460
3461  " Test 3:
3462  " When searching for a pattern using :lvimgrep, if the location list is
3463  " freed, then the command should error out.
3464  silent! %bwipe!
3465  let g:save_winid = win_getid()
3466  autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3467  call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3468  au! BufRead Xtest2.txt
3469
3470  call delete('Xtest1.txt')
3471  call delete('Xtest2.txt')
3472  call setqflist([], 'f')
3473endfunc
3474
3475" The following test used to crash Vim
3476func Test_lhelpgrep_autocmd()
3477  lhelpgrep quickfix
3478  autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3479  lhelpgrep buffer
3480  call assert_equal('help', &filetype)
3481  call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3482  lhelpgrep tabpage
3483  call assert_equal('help', &filetype)
3484  call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3485  au! QuickFixCmdPost
3486
3487  new | only
3488  augroup QF_Test
3489    au!
3490    au BufEnter * call setqflist([], 'f')
3491  augroup END
3492  call assert_fails('helpgrep quickfix', 'E925:')
3493  augroup QF_Test
3494    au! BufEnter
3495  augroup END
3496
3497  new | only
3498  augroup QF_Test
3499    au!
3500    au BufEnter * call setqflist([], 'r')
3501  augroup END
3502  call assert_fails('helpgrep quickfix', 'E925:')
3503  augroup QF_Test
3504    au! BufEnter
3505  augroup END
3506
3507  new | only
3508  augroup QF_Test
3509    au!
3510    au BufEnter * call setloclist(0, [], 'r')
3511  augroup END
3512  call assert_fails('lhelpgrep quickfix', 'E926:')
3513  augroup QF_Test
3514    au! BufEnter
3515  augroup END
3516
3517  new | only
3518endfunc
3519
3520" Test for shortening/simplifying the file name when opening the
3521" quickfix window or when displaying the quickfix list
3522func Test_shorten_fname()
3523  if !has('unix')
3524    return
3525  endif
3526  %bwipe
3527  " Create a quickfix list with a absolute path filename
3528  let fname = getcwd() . '/test_quickfix.vim'
3529  call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3530  call assert_equal(fname, bufname('test_quickfix.vim'))
3531  " Opening the quickfix window should simplify the file path
3532  cwindow
3533  call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3534  cclose
3535  %bwipe
3536  " Create a quickfix list with a absolute path filename
3537  call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3538  call assert_equal(fname, bufname('test_quickfix.vim'))
3539  " Displaying the quickfix list should simplify the file path
3540  silent! clist
3541  call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3542endfunc
3543
3544" Quickfix title tests
3545" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3546" Otherwise due to indentation, the title is set with spaces at the beginning
3547" of the command.
3548func Test_qftitle()
3549  call writefile(["F1:1:Line1"], 'Xerr')
3550
3551  " :cexpr
3552  exe "cexpr readfile('Xerr')"
3553  call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3554
3555  " :cgetexpr
3556  exe "cgetexpr readfile('Xerr')"
3557  call assert_equal(":cgetexpr readfile('Xerr')",
3558					\ getqflist({'title' : 1}).title)
3559
3560  " :caddexpr
3561  call setqflist([], 'f')
3562  exe "caddexpr readfile('Xerr')"
3563  call assert_equal(":caddexpr readfile('Xerr')",
3564					\ getqflist({'title' : 1}).title)
3565
3566  " :cbuffer
3567  new Xerr
3568  exe "cbuffer"
3569  call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3570
3571  " :cgetbuffer
3572  edit Xerr
3573  exe "cgetbuffer"
3574  call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3575
3576  " :caddbuffer
3577  call setqflist([], 'f')
3578  edit Xerr
3579  exe "caddbuffer"
3580  call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3581
3582  " :cfile
3583  exe "cfile Xerr"
3584  call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
3585
3586  " :cgetfile
3587  exe "cgetfile Xerr"
3588  call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
3589
3590  " :caddfile
3591  call setqflist([], 'f')
3592  exe "caddfile Xerr"
3593  call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
3594
3595  " :grep
3596  set grepprg=internal
3597  exe "grep F1 Xerr"
3598  call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
3599
3600  " :grepadd
3601  call setqflist([], 'f')
3602  exe "grepadd F1 Xerr"
3603  call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
3604  set grepprg&vim
3605
3606  " :vimgrep
3607  exe "vimgrep F1 Xerr"
3608  call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
3609
3610  " :vimgrepadd
3611  call setqflist([], 'f')
3612  exe "vimgrepadd F1 Xerr"
3613  call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
3614
3615  call setqflist(['F1:10:L10'], ' ')
3616  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3617
3618  call setqflist([], 'f')
3619  call setqflist(['F1:10:L10'], 'a')
3620  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3621
3622  call setqflist([], 'f')
3623  call setqflist(['F1:10:L10'], 'r')
3624  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3625
3626  close
3627  call delete('Xerr')
3628
3629  call setqflist([], ' ', {'title' : 'Errors'})
3630  copen
3631  call assert_equal('Errors', w:quickfix_title)
3632  call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
3633  call assert_equal('Errors', w:quickfix_title)
3634  cclose
3635endfunc
3636
3637func Test_lbuffer_with_bwipe()
3638  new
3639  new
3640  augroup nasty
3641    au * * bwipe
3642  augroup END
3643  lbuffer
3644  augroup nasty
3645    au!
3646  augroup END
3647endfunc
3648
3649" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
3650" running
3651func Xexpr_acmd_freelist(cchar)
3652  call s:setup_commands(a:cchar)
3653
3654  " This was using freed memory.
3655  augroup nasty
3656    au * * call g:Xsetlist([], 'f')
3657  augroup END
3658  Xexpr "x"
3659  augroup nasty
3660    au!
3661  augroup END
3662endfunc
3663
3664func Test_cexpr_acmd_freelist()
3665  call Xexpr_acmd_freelist('c')
3666  call Xexpr_acmd_freelist('l')
3667endfunc
3668
3669" Test for commands that create a new quickfix/location list and jump to the
3670" first error automatically.
3671func Xjumpto_first_error_test(cchar)
3672  call s:setup_commands(a:cchar)
3673
3674  call s:create_test_file('Xtestfile1')
3675  call s:create_test_file('Xtestfile2')
3676  let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
3677
3678  " Test for cexpr/lexpr
3679  enew
3680  Xexpr l
3681  call assert_equal('Xtestfile1', bufname(''))
3682  call assert_equal(2, line('.'))
3683
3684  " Test for cfile/lfile
3685  enew
3686  call writefile(l, 'Xerr')
3687  Xfile Xerr
3688  call assert_equal('Xtestfile1', bufname(''))
3689  call assert_equal(2, line('.'))
3690
3691  " Test for cbuffer/lbuffer
3692  edit Xerr
3693  Xbuffer
3694  call assert_equal('Xtestfile1', bufname(''))
3695  call assert_equal(2, line('.'))
3696
3697  call delete('Xerr')
3698  call delete('Xtestfile1')
3699  call delete('Xtestfile2')
3700endfunc
3701
3702func Test_jumpto_first_error()
3703  call Xjumpto_first_error_test('c')
3704  call Xjumpto_first_error_test('l')
3705endfunc
3706
3707" Test for a quickfix autocmd changing the quickfix/location list before
3708" jumping to the first error in the new list.
3709func Xautocmd_changelist(cchar)
3710  call s:setup_commands(a:cchar)
3711
3712  " Test for cfile/lfile
3713  call s:create_test_file('Xtestfile1')
3714  call s:create_test_file('Xtestfile2')
3715  Xexpr 'Xtestfile1:2:Line2'
3716  autocmd QuickFixCmdPost * Xolder
3717  call writefile(['Xtestfile2:4:Line4'], 'Xerr')
3718  Xfile Xerr
3719  call assert_equal('Xtestfile2', bufname(''))
3720  call assert_equal(4, line('.'))
3721  autocmd! QuickFixCmdPost
3722
3723  " Test for cbuffer/lbuffer
3724  call g:Xsetlist([], 'f')
3725  Xexpr 'Xtestfile1:2:Line2'
3726  autocmd QuickFixCmdPost * Xolder
3727  call writefile(['Xtestfile2:4:Line4'], 'Xerr')
3728  edit Xerr
3729  Xbuffer
3730  call assert_equal('Xtestfile2', bufname(''))
3731  call assert_equal(4, line('.'))
3732  autocmd! QuickFixCmdPost
3733
3734  " Test for cexpr/lexpr
3735  call g:Xsetlist([], 'f')
3736  Xexpr 'Xtestfile1:2:Line2'
3737  autocmd QuickFixCmdPost * Xolder
3738  Xexpr 'Xtestfile2:4:Line4'
3739  call assert_equal('Xtestfile2', bufname(''))
3740  call assert_equal(4, line('.'))
3741  autocmd! QuickFixCmdPost
3742
3743  " The grepprg may not be set on non-Unix systems
3744  if has('unix')
3745    " Test for grep/lgrep
3746    call g:Xsetlist([], 'f')
3747    Xexpr 'Xtestfile1:2:Line2'
3748    autocmd QuickFixCmdPost * Xolder
3749    silent Xgrep Line5 Xtestfile2
3750    call assert_equal('Xtestfile2', bufname(''))
3751    call assert_equal(5, line('.'))
3752    autocmd! QuickFixCmdPost
3753  endif
3754
3755  " Test for vimgrep/lvimgrep
3756  call g:Xsetlist([], 'f')
3757  Xexpr 'Xtestfile1:2:Line2'
3758  autocmd QuickFixCmdPost * Xolder
3759  silent Xvimgrep Line5 Xtestfile2
3760  call assert_equal('Xtestfile2', bufname(''))
3761  call assert_equal(5, line('.'))
3762  autocmd! QuickFixCmdPost
3763
3764  " Test for autocommands clearing the quickfix list before jumping to the
3765  " first error. This should not result in an error
3766  autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
3767  let v:errmsg = ''
3768  " Test for cfile/lfile
3769  Xfile Xerr
3770  call assert_true(v:errmsg !~# 'E42:')
3771  " Test for cbuffer/lbuffer
3772  edit Xerr
3773  Xbuffer
3774  call assert_true(v:errmsg !~# 'E42:')
3775  " Test for cexpr/lexpr
3776  Xexpr 'Xtestfile2:4:Line4'
3777  call assert_true(v:errmsg !~# 'E42:')
3778  " Test for grep/lgrep
3779  " The grepprg may not be set on non-Unix systems
3780  if has('unix')
3781    silent Xgrep Line5 Xtestfile2
3782    call assert_true(v:errmsg !~# 'E42:')
3783  endif
3784  " Test for vimgrep/lvimgrep
3785  call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
3786  autocmd! QuickFixCmdPost
3787
3788  call delete('Xerr')
3789  call delete('Xtestfile1')
3790  call delete('Xtestfile2')
3791endfunc
3792
3793func Test_autocmd_changelist()
3794  call Xautocmd_changelist('c')
3795  call Xautocmd_changelist('l')
3796endfunc
3797
3798" Tests for the ':filter /pat/ clist' command
3799func Test_filter_clist()
3800  cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
3801  call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
3802			\ split(execute('filter /Line 15/ clist'), "\n"))
3803  call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
3804			\ split(execute('filter /Xfile1/ clist'), "\n"))
3805  call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
3806
3807  call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
3808			\ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
3809  call assert_equal([' 2 pqr:pat2:  '],
3810			\ split(execute('filter /pqr/ clist'), "\n"))
3811  call assert_equal([' 1 abc:pat1:  '],
3812			\ split(execute('filter /pat1/ clist'), "\n"))
3813endfunc
3814
3815" Tests for the "CTRL-W <CR>" command.
3816func Xview_result_split_tests(cchar)
3817  call s:setup_commands(a:cchar)
3818
3819  " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
3820  call g:Xsetlist([])
3821  Xopen
3822  let l:win_count = winnr('$')
3823  call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
3824  call assert_equal(l:win_count, winnr('$'))
3825  Xclose
3826endfunc
3827
3828func Test_view_result_split()
3829  call Xview_result_split_tests('c')
3830  call Xview_result_split_tests('l')
3831endfunc
3832
3833" Test that :cc sets curswant
3834func Test_curswant()
3835  helpgrep quickfix
3836  normal! llll
3837  1cc
3838  call assert_equal(getcurpos()[4], virtcol('.'))
3839  cclose | helpclose
3840endfunc
3841
3842" Test for opening a file from the quickfix window using CTRL-W <Enter>
3843" doesn't leave an empty buffer around.
3844func Test_splitview()
3845  call s:create_test_file('Xtestfile1')
3846  call s:create_test_file('Xtestfile2')
3847  new | only
3848  let last_bufnr = bufnr('Test_sv_1', 1)
3849  let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
3850  cgetexpr l
3851  copen
3852  let numbufs = len(getbufinfo())
3853  exe "normal \<C-W>\<CR>"
3854  copen
3855  exe "normal j\<C-W>\<CR>"
3856  " Make sure new empty buffers are not created
3857  call assert_equal(numbufs, len(getbufinfo()))
3858  " Creating a new buffer should use the next available buffer number
3859  call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
3860  bwipe Test_sv_1
3861  bwipe Test_sv_2
3862  new | only
3863
3864  " When split opening files from location list window, make sure that two
3865  " windows doesn't refer to the same location list
3866  lgetexpr l
3867  let locid = getloclist(0, {'id' : 0}).id
3868  lopen
3869  exe "normal \<C-W>\<CR>"
3870  call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
3871  call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
3872  new | only
3873
3874  " When split opening files from a helpgrep location list window, a new help
3875  " window should be opened with a copy of the location list.
3876  lhelpgrep window
3877  let locid = getloclist(0, {'id' : 0}).id
3878  lwindow
3879  exe "normal j\<C-W>\<CR>"
3880  call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
3881  call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
3882  new | only
3883
3884  call delete('Xtestfile1')
3885  call delete('Xtestfile2')
3886endfunc
3887
3888" Test for parsing entries using visual screen column
3889func Test_viscol()
3890  enew
3891  call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
3892  edit Xfile1
3893
3894  " Use byte offset for column number
3895  set efm&
3896  cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
3897  call assert_equal([5, 8], [col('.'), virtcol('.')])
3898  cnext
3899  call assert_equal([9, 12], [col('.'), virtcol('.')])
3900  cnext
3901  call assert_equal([14, 20], [col('.'), virtcol('.')])
3902
3903  " Use screen column offset for column number
3904  set efm=%f:%l:%v:%m
3905  cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
3906  call assert_equal([5, 8], [col('.'), virtcol('.')])
3907  cnext
3908  call assert_equal([9, 12], [col('.'), virtcol('.')])
3909  cnext
3910  call assert_equal([14, 20], [col('.'), virtcol('.')])
3911  cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
3912  call assert_equal([5, 8], [col('.'), virtcol('.')])
3913  cnext
3914  call assert_equal([10, 16], [col('.'), virtcol('.')])
3915  cnext
3916  call assert_equal([14, 20], [col('.'), virtcol('.')])
3917
3918  enew
3919  call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
3920
3921  " Use byte offset for column number
3922  set efm&
3923  cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
3924  call assert_equal([8, 10], [col('.'), virtcol('.')])
3925  cnext
3926  call assert_equal([11, 17], [col('.'), virtcol('.')])
3927  cnext
3928  call assert_equal([16, 25], [col('.'), virtcol('.')])
3929
3930  " Use screen column offset for column number
3931  set efm=%f:%l:%v:%m
3932  cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
3933  call assert_equal([8, 10], [col('.'), virtcol('.')])
3934  cnext
3935  call assert_equal([11, 17], [col('.'), virtcol('.')])
3936  cnext
3937  call assert_equal([16, 25], [col('.'), virtcol('.')])
3938
3939  enew | only
3940  set efm&
3941  call delete('Xfile1')
3942endfunc
3943
3944" Test for the quickfix window buffer
3945func Xqfbuf_test(cchar)
3946  call s:setup_commands(a:cchar)
3947
3948  " Quickfix buffer should be reused across closing and opening a quickfix
3949  " window
3950  Xexpr "F1:10:Line10"
3951  Xopen
3952  let qfbnum = bufnr('')
3953  Xclose
3954  " Even after the quickfix window is closed, the buffer should be loaded
3955  call assert_true(bufloaded(qfbnum))
3956  call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
3957  Xopen
3958  " Buffer should be reused when opening the window again
3959  call assert_equal(qfbnum, bufnr(''))
3960  Xclose
3961
3962  if a:cchar == 'l'
3963    %bwipe
3964    " For a location list, when both the file window and the location list
3965    " window for the list are closed, then the buffer should be freed.
3966    new | only
3967    lexpr "F1:10:Line10"
3968    let wid = win_getid()
3969    lopen
3970    let qfbnum = bufnr('')
3971    call assert_match(qfbnum . ' %a-  "\[Location List]"', execute('ls'))
3972    close
3973    " When the location list window is closed, the buffer name should not
3974    " change to 'Quickfix List'
3975    call assert_match(qfbnum . 'u h-  "\[Location List]"', execute('ls!'))
3976    call assert_true(bufloaded(qfbnum))
3977
3978    " After deleting a location list buffer using ":bdelete", opening the
3979    " location list window should mark the buffer as a location list buffer.
3980    exe "bdelete " . qfbnum
3981    lopen
3982    call assert_equal("quickfix", &buftype)
3983    call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
3984    call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
3985    call assert_false(&swapfile)
3986    lclose
3987
3988    " When the location list is cleared for the window, the buffer should be
3989    " removed
3990    call setloclist(0, [], 'f')
3991    call assert_false(bufexists(qfbnum))
3992    call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
3993
3994    " When the location list is freed with the location list window open, the
3995    " location list buffer should not be lost. It should be reused when the
3996    " location list is again populated.
3997    lexpr "F1:10:Line10"
3998    lopen
3999    let wid = win_getid()
4000    let qfbnum = bufnr('')
4001    wincmd p
4002    call setloclist(0, [], 'f')
4003    lexpr "F1:10:Line10"
4004    lopen
4005    call assert_equal(wid, win_getid())
4006    call assert_equal(qfbnum, bufnr(''))
4007    lclose
4008
4009    " When the window with the location list is closed, the buffer should be
4010    " removed
4011    new | only
4012    call assert_false(bufexists(qfbnum))
4013  endif
4014endfunc
4015
4016func Test_qfbuf()
4017  call Xqfbuf_test('c')
4018  call Xqfbuf_test('l')
4019endfunc
4020
4021" If there is an autocmd to use only one window, then opening the location
4022" list window used to crash Vim.
4023func Test_winonly_autocmd()
4024  call s:create_test_file('Xtest1')
4025  " Autocmd to show only one Vim window at a time
4026  autocmd WinEnter * only
4027  new
4028  " Load the location list
4029  lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4030  let loclistid = getloclist(0, {'id' : 0}).id
4031  " Open the location list window. Only this window will be shown and the file
4032  " window is closed.
4033  lopen
4034  call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4035  " Jump to an entry in the location list and make sure that the cursor is
4036  " positioned correctly.
4037  ll 3
4038  call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4039  call assert_equal('Xtest1', bufname(''))
4040  call assert_equal(15, line('.'))
4041  " Cleanup
4042  autocmd! WinEnter
4043  new | only
4044  call delete('Xtest1')
4045endfunc
4046
4047" Test to make sure that an empty quickfix buffer is not reused for loading
4048" a normal buffer.
4049func Test_empty_qfbuf()
4050  enew | only
4051  call writefile(["Test"], 'Xfile1')
4052  call setqflist([], 'f')
4053  copen | only
4054  let qfbuf = bufnr('')
4055  edit Xfile1
4056  call assert_notequal(qfbuf, bufnr(''))
4057  enew
4058  call delete('Xfile1')
4059endfunc
4060
4061" Test for the :cbelow, :cabove, :lbelow and :labove commands.
4062" And for the :cafter, :cbefore, :lafter and :lbefore commands.
4063func Xtest_below(cchar)
4064  call s:setup_commands(a:cchar)
4065
4066  " No quickfix/location list
4067  call assert_fails('Xbelow', 'E42:')
4068  call assert_fails('Xabove', 'E42:')
4069  call assert_fails('Xbefore', 'E42:')
4070  call assert_fails('Xafter', 'E42:')
4071
4072  " Empty quickfix/location list
4073  call g:Xsetlist([])
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  call s:create_test_file('X1')
4080  call s:create_test_file('X2')
4081  call s:create_test_file('X3')
4082  call s:create_test_file('X4')
4083
4084  " Invalid entries
4085  edit X1
4086  call g:Xsetlist(["E1", "E2"])
4087  call assert_fails('Xbelow', 'E42:')
4088  call assert_fails('Xabove', 'E42:')
4089  call assert_fails('3Xbelow', 'E42:')
4090  call assert_fails('4Xabove', 'E42:')
4091  call assert_fails('Xbefore', 'E42:')
4092  call assert_fails('Xafter', 'E42:')
4093  call assert_fails('3Xbefore', 'E42:')
4094  call assert_fails('4Xafter', 'E42:')
4095
4096  " Test the commands with various arguments
4097  Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"]
4098  edit +7 X2
4099  Xabove
4100  call assert_equal(['X2', 5], [bufname(''), line('.')])
4101  call assert_fails('Xabove', 'E553:')
4102  normal 7G
4103  Xbefore
4104  call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
4105  call assert_fails('Xbefore', 'E553:')
4106
4107  normal 2j
4108  Xbelow
4109  call assert_equal(['X2', 10], [bufname(''), line('.')])
4110  normal 7G
4111  Xafter
4112  call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
4113
4114  " Last error in this file
4115  Xbelow 99
4116  call assert_equal(['X2', 15], [bufname(''), line('.')])
4117  call assert_fails('Xbelow', 'E553:')
4118  normal gg
4119  Xafter 99
4120  call assert_equal(['X2', 15, 4], [bufname(''), line('.'), col('.')])
4121  call assert_fails('Xafter', 'E553:')
4122
4123  " First error in this file
4124  Xabove 99
4125  call assert_equal(['X2', 5], [bufname(''), line('.')])
4126  call assert_fails('Xabove', 'E553:')
4127  normal G
4128  Xbefore 99
4129  call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
4130  call assert_fails('Xbefore', 'E553:')
4131
4132  normal gg
4133  Xbelow 2
4134  call assert_equal(['X2', 10], [bufname(''), line('.')])
4135  normal gg
4136  Xafter 2
4137  call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
4138
4139  normal G
4140  Xabove 2
4141  call assert_equal(['X2', 10], [bufname(''), line('.')])
4142  normal G
4143  Xbefore 2
4144  call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
4145
4146  edit X4
4147  call assert_fails('Xabove', 'E42:')
4148  call assert_fails('Xbelow', 'E42:')
4149  call assert_fails('Xbefore', 'E42:')
4150  call assert_fails('Xafter', 'E42:')
4151  if a:cchar == 'l'
4152    " If a buffer has location list entries from some other window but not
4153    " from the current window, then the commands should fail.
4154    edit X1 | split | call setloclist(0, [], 'f')
4155    call assert_fails('Xabove', 'E776:')
4156    call assert_fails('Xbelow', 'E776:')
4157    call assert_fails('Xbefore', 'E776:')
4158    call assert_fails('Xafter', 'E776:')
4159    close
4160  endif
4161
4162  " Test for lines with multiple quickfix entries
4163  Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4164	      \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4165	      \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4166  edit +1 X2
4167  Xbelow 2
4168  call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
4169  normal 1G
4170  Xafter 2
4171  call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
4172
4173  normal gg
4174  Xbelow 99
4175  call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
4176  normal gg
4177  Xafter 99
4178  call assert_equal(['X2', 15, 3], [bufname(''), line('.'), col('.')])
4179
4180  normal G
4181  Xabove 2
4182  call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
4183  normal G
4184  Xbefore 2
4185  call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
4186
4187  normal G
4188  Xabove 99
4189  call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
4190  normal G
4191  Xbefore 99
4192  call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
4193
4194  normal 10G
4195  Xabove
4196  call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
4197  normal 10G$
4198  2Xbefore
4199  call assert_equal(['X2', 10, 2], [bufname(''), line('.'), col('.')])
4200
4201  normal 10G
4202  Xbelow
4203  call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
4204  normal 9G
4205  5Xafter
4206  call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
4207
4208  " Invalid range
4209  if a:cchar == 'c'
4210    call assert_fails('-2cbelow', 'E16:')
4211    call assert_fails('-2cafter', 'E16:')
4212  else
4213    call assert_fails('-2lbelow', 'E16:')
4214    call assert_fails('-2lafter', 'E16:')
4215  endif
4216
4217  call delete('X1')
4218  call delete('X2')
4219  call delete('X3')
4220  call delete('X4')
4221endfunc
4222
4223func Test_cbelow()
4224  call Xtest_below('c')
4225  call Xtest_below('l')
4226endfunc
4227
4228func Test_quickfix_count()
4229  let commands = [
4230	\ 'cNext',
4231	\ 'cNfile',
4232	\ 'cabove',
4233	\ 'cbelow',
4234	\ 'cfirst',
4235	\ 'clast',
4236	\ 'cnewer',
4237	\ 'cnext',
4238	\ 'cnfile',
4239	\ 'colder',
4240	\ 'cprevious',
4241	\ 'crewind',
4242	\
4243	\ 'lNext',
4244	\ 'lNfile',
4245	\ 'labove',
4246	\ 'lbelow',
4247	\ 'lfirst',
4248	\ 'llast',
4249	\ 'lnewer',
4250	\ 'lnext',
4251	\ 'lnfile',
4252	\ 'lolder',
4253	\ 'lprevious',
4254	\ 'lrewind',
4255	\ ]
4256  for cmd in commands
4257    call assert_fails('-1' .. cmd, 'E16:')
4258    call assert_fails('.' .. cmd, 'E16:')
4259    call assert_fails('%' .. cmd, 'E16:')
4260    call assert_fails('$' .. cmd, 'E16:')
4261  endfor
4262endfunc
4263