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