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