blob: 6d119fe3e39fa5fee044f717a1214f9ff257f68c [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01005
Bram Moolenaare00fdf32019-09-15 19:09:42 +02006source screendump.vim
7
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01008set encoding=utf-8
9
Bram Moolenaar2b946c92016-11-12 18:14:44 +010010func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020011 if a:cchar == 'c'
12 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
13 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020014 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020015 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020016 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010017 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020018 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020019 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020020 command! -nargs=* Xclose <mods>cclose <args>
21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
22 command! -nargs=* Xgetfile <mods>cgetfile <args>
23 command! -nargs=* Xaddfile <mods>caddfile <args>
24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
27 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020028 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020030 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
31 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020032 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020033 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020034 command! -nargs=* Xexpr <mods>cexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010035 command! -count -nargs=* Xvimgrep <mods> <count>vimgrep <args>
36 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020037 command! -nargs=* Xgrep <mods> grep <args>
38 command! -nargs=* Xgrepadd <mods> grepadd <args>
39 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010040 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020041 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
42 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020043 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
44 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020045 let g:Xgetlist = function('getqflist')
46 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020047 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020048 else
49 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
50 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020051 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020052 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020053 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010054 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020055 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020056 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020057 command! -nargs=* Xclose <mods>lclose <args>
58 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
59 command! -nargs=* Xgetfile <mods>lgetfile <args>
60 command! -nargs=* Xaddfile <mods>laddfile <args>
61 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
62 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
63 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
64 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020065 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
66 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020067 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
68 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020069 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020070 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020071 command! -nargs=* Xexpr <mods>lexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010072 command! -count -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
73 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020074 command! -nargs=* Xgrep <mods> lgrep <args>
75 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
76 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010077 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020078 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
79 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020080 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
81 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020082 let g:Xgetlist = function('getloclist', [0])
83 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020084 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020085 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010086endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020087
Bram Moolenaarda59dd52016-01-05 21:59:58 +010088" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010089func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020090 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010091
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020092 if a:cchar == 'l'
93 call assert_fails('llist', 'E776:')
94 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020096 Xgetexpr []
97 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098 call assert_true(v:errmsg ==# 'E42: No Errors')
99
100 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200101 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100103 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100104
105 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100106 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100107 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
108 \ ' 4 Xtestfile2:2 col 2: Line2',
109 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
110
111 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100112 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100113 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
114 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100115 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100116
117 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100118 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100119 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
120 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
121
Bram Moolenaaree85df32017-03-19 14:19:50 +0100122 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
124
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
127
Bram Moolenaaree85df32017-03-19 14:19:50 +0100128 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100129 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
130 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100131
132 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100133 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100134 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
135 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100136
137 " Different types of errors
138 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
139 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
140 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
141 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
142 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
143 let l = split(execute('Xlist', ""), "\n")
144 call assert_equal([' 1:10 col 5 warning 11: Warning',
145 \ ' 2:20 col 10 error 22: Error',
146 \ ' 3:30 col 15 info 33: Info',
147 \ ' 4:40 col 20 x 44: Other',
148 \ ' 5:50 col 25 55: one'], l)
149
Bram Moolenaard76ce852018-05-01 15:02:04 +0200150 " Test for module names, one needs to explicitly set `'valid':v:true` so
151 call g:Xsetlist([
152 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
153 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
154 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
155 let l = split(execute('Xlist', ""), "\n")
156 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
157 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
158 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
159
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100160 " For help entries in the quickfix list, only the filename without directory
161 " should be displayed
162 Xhelpgrep setqflist()
163 let l = split(execute('Xlist 1', ''), "\n")
164 call assert_match('^ 1 [^\\/]\{-}:', l[0])
165
Bram Moolenaaree85df32017-03-19 14:19:50 +0100166 " Error cases
167 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100168endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100169
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100170func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100171 call XlistTests('c')
172 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100173endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100174
175" Tests for the :colder, :cnewer, :lolder and :lnewer commands
176" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100177" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100178func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200179 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100180
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200181 if a:cchar == 'l'
182 " No location list for the current window
183 call assert_fails('lolder', 'E776:')
184 call assert_fails('lnewer', 'E776:')
185 endif
186
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200187 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200188 call g:Xsetlist(list)
189
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100190 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200191 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100192 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
193
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200194 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100195 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
196
197 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200198 Xgetexpr ['Xtestfile1:1:3:Line1']
199 Xgetexpr ['Xtestfile2:2:2:Line2']
200 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100201
202 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200203 Xolder
204 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100205 call assert_equal('Line2', l[0].text)
206
207 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200208 Xnewer
209 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100210 call assert_equal('Line3', l[0].text)
211
212 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 Xolder 2
214 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100215 call assert_equal('Line1', l[0].text)
216
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200217 Xnewer 2
218 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100219 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100220endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100221
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100222func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223 call XageTests('c')
224 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100225endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100226
227" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
228" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100229func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100231
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200232 " Opening the location list window without any errors should fail
233 if a:cchar == 'l'
234 call assert_fails('lopen', 'E776:')
235 endif
236
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200238 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100239
240 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200241 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100242 call assert_true(winnr('$') == 1)
243
244 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200245 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
246 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100247
248 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200249 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100250 call assert_true(winnr('$') == 2 && winnr() == 2 &&
251 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200252 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
254 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200255 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100256 call assert_true(winnr('$') == 1)
257
258 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200259 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100260
261 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200262 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100263 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
264 \ && winheight('.') == 5)
265
266 " Opening the window again, should move the cursor to that window
267 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200268 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269 call assert_true(winnr('$') == 2 && winnr() == 2 &&
270 \ winheight('.') == 7 &&
271 \ getline('.') ==# '|| non-error 1')
272
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100273 " :cnext in quickfix window should move to the next entry
274 Xnext
275 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200278 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100279 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200280
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100281 " Specifying the width should adjust the width for a vertically split
282 " quickfix window.
283 vert Xopen
284 call assert_equal(10, winwidth(0))
285 vert Xopen 12
286 call assert_equal(12, winwidth(0))
287 Xclose
288
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200289 " Horizontally or vertically splitting the quickfix window should create a
290 " normal window/buffer
291 Xopen
292 wincmd s
293 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
294 call assert_equal(0, getwininfo(win_getid())[0].loclist)
295 call assert_notequal('quickfix', &buftype)
296 close
297 Xopen
298 wincmd v
299 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
300 call assert_equal(0, getwininfo(win_getid())[0].loclist)
301 call assert_notequal('quickfix', &buftype)
302 close
303 Xopen
304 Xclose
305
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200306 if a:cchar == 'c'
307 " Opening the quickfix window in multiple tab pages should reuse the
308 " quickfix buffer
309 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
310 \ 'Xtestfile3:3:1:Line3']
311 Xopen
312 let qfbufnum = bufnr('%')
313 tabnew
314 Xopen
315 call assert_equal(qfbufnum, bufnr('%'))
316 new | only | tabonly
317 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100318endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100319
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100320func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100321 call XwindowTests('c')
322 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100323endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100324
Bram Moolenaar36d50222019-05-02 20:17:40 +0200325func Test_copenHeight()
326 copen
327 wincmd H
328 let height = winheight(0)
329 copen 10
330 call assert_equal(height, winheight(0))
331 quit
332endfunc
333
Bram Moolenaar1142a312019-10-16 14:51:39 +0200334func Test_copenHeight_tabline()
335 set tabline=foo showtabline=2
336 copen
337 wincmd H
338 let height = winheight(0)
339 copen 10
340 call assert_equal(height, winheight(0))
341 quit
342 set tabline& showtabline&
343endfunc
344
345
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
347" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100348func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200349 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100350
351 call writefile(['Xtestfile1:700:10:Line 700',
352 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
353
354 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200355 Xfile Xqftestfile1
356 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100357 call assert_true(len(l) == 2 &&
358 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
359 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
360
Bram Moolenaar049cba92016-06-26 14:38:04 +0200361 " Test with a non existent file
362 call assert_fails('Xfile non_existent_file', 'E40')
363
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100364 " Run cfile/lfile from a modified buffer
365 enew!
366 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200367 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
369
370 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 Xaddfile Xqftestfile1
372 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373 call assert_true(len(l) == 3 &&
374 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
375
376 call writefile(['Xtestfile1:222:77:Line 222',
377 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
378
379 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200380 Xgetfile Xqftestfile1
381 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100382 call assert_true(len(l) == 2 &&
383 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
384 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
385
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100386 " Test for a file with a long line and without a newline at the end
387 let text = repeat('x', 1024)
388 let t = 'a.txt:18:' . text
389 call writefile([t], 'Xqftestfile1', 'b')
390 silent! Xfile Xqftestfile1
391 call assert_equal(text, g:Xgetlist()[0].text)
392
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100393 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100394endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100396func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100397 call XfileTests('c')
398 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100399endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100400
401" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
402" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100403func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200404 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100405
406 enew!
407 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
408 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200409 Xbuffer!
410 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411 call assert_true(len(l) == 2 &&
412 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
413 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
414
415 enew!
416 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
417 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200418 Xgetbuffer
419 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420 call assert_true(len(l) == 2 &&
421 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
422 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
423
424 enew!
425 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
426 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200427 Xaddbuffer
428 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100429 call assert_true(len(l) == 4 &&
430 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
431 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
432 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200433 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434
Bram Moolenaaree85df32017-03-19 14:19:50 +0100435 " Check for invalid buffer
436 call assert_fails('Xbuffer 199', 'E474:')
437
438 " Check for unloaded buffer
439 edit Xtestfile1
440 let bnr = bufnr('%')
441 enew!
442 call assert_fails('Xbuffer ' . bnr, 'E681:')
443
444 " Check for invalid range
445 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
446 " commands. So directly call the commands.
447 if (a:cchar == 'c')
448 call assert_fails('900,999cbuffer', 'E16:')
449 else
450 call assert_fails('900,999lbuffer', 'E16:')
451 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100452endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100453
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100454func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100455 call XbufferTests('c')
456 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100457endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100458
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100459func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200460 call s:setup_commands(a:cchar)
461
462 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100463endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200464
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100465func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200466 call XexprTests('c')
467 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100468endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200469
470" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100471func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200472 call s:setup_commands(a:cchar)
473
Bram Moolenaar74240d32017-12-10 15:26:15 +0100474 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200475 " Jumping to first or next location list entry without any error should
476 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100477 if a:cchar == 'c'
478 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100479 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100480 else
481 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100482 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200483 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100484 call assert_fails('Xnext', err)
485 call assert_fails('Xprev', err)
486 call assert_fails('Xnfile', err)
487 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100488 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200489
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100490 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100491 call assert_fails(cmd, 'E42:')
492
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200493 call s:create_test_file('Xqftestfile1')
494 call s:create_test_file('Xqftestfile2')
495
496 Xgetexpr ['Xqftestfile1:5:Line5',
497 \ 'Xqftestfile1:6:Line6',
498 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200499 \ 'Xqftestfile2:11:Line11',
500 \ 'RegularLine1',
501 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200502
503 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100504 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200505 call assert_fails('Xprev', 'E553')
506 call assert_fails('Xpfile', 'E553')
507 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200508 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200509 call assert_equal(10, line('.'))
510 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200511 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200512 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100513 5Xcc
514 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
515 2Xcc
516 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100517 if a:cchar == 'c'
518 cc
519 else
520 ll
521 endif
522 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100523 10Xcc
524 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200526 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200527 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528 call assert_equal(11, line('.'))
529 call assert_fails('Xnext', 'E553')
530 call assert_fails('Xnfile', 'E553')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100531 " To process the range using quickfix list entries, directly use the
532 " quickfix commands (don't use the user defined commands)
533 if a:cchar == 'c'
534 $cc
535 else
536 $ll
537 endif
538 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200539 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200540 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200541 call assert_equal(5, line('.'))
542
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200543 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200544 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200545 call assert_equal(11, line('.'))
546 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200547 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 call assert_equal(5, line('.'))
549
Bram Moolenaar74240d32017-12-10 15:26:15 +0100550 " Jumping to an error from the error window using cc command
551 Xgetexpr ['Xqftestfile1:5:Line5',
552 \ 'Xqftestfile1:6:Line6',
553 \ 'Xqftestfile2:10:Line10',
554 \ 'Xqftestfile2:11:Line11']
555 Xopen
556 10Xcc
557 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200558 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100559 Xopen
560 call cursor(2, 1)
561 if a:cchar == 'c'
562 .cc
563 else
564 .ll
565 endif
566 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200567 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100568
569 " Jumping to an error from the error window (when only the error window is
570 " present)
571 Xopen | only
572 Xlast 1
573 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200574 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100575
Bram Moolenaaree85df32017-03-19 14:19:50 +0100576 Xexpr ""
577 call assert_fails('Xnext', 'E42:')
578
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200579 call delete('Xqftestfile1')
580 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200581
582 " Should be able to use next/prev with invalid entries
583 Xexpr ""
584 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
585 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100586 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200587 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
588 Xlast
589 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
590 Xfirst
591 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
592 2Xnext
593 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100594endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200595
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100596func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200597 call Xtest_browse('c')
598 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100599endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200600
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100601func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200602 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100603 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100604
Bram Moolenaarce90e362019-09-08 18:58:44 +0200605 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100606 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100607
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200608 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100609 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100610
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200611 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100612 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100613
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200614 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100615 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100616
617endfunc
618
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100619func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200620 call s:setup_commands(a:cchar)
621 Xhelpgrep quickfix
622 Xopen
623 if a:cchar == 'c'
624 let title_text = ':helpgrep quickfix'
625 else
626 let title_text = ':lhelpgrep quickfix'
627 endif
628 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200629
630 " Jumping to a help topic should open the help window
631 only
632 Xnext
633 call assert_true(&buftype == 'help')
634 call assert_true(winnr('$') == 2)
635 " Jumping to the next match should reuse the help window
636 Xnext
637 call assert_true(&buftype == 'help')
638 call assert_true(winnr() == 1)
639 call assert_true(winnr('$') == 2)
640 " Jumping to the next match from the quickfix window should reuse the help
641 " window
642 Xopen
643 Xnext
644 call assert_true(&buftype == 'help')
645 call assert_true(winnr() == 1)
646 call assert_true(winnr('$') == 2)
647
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100648 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200649 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100650
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100651 " When the current window is vertically split, jumping to a help match
652 " should open the help window at the top.
653 only | enew
654 let w1 = win_getid()
655 vert new
656 let w2 = win_getid()
657 Xnext
658 let w3 = win_getid()
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100661 " See jump_to_help_window() for details
662 let w2_width = winwidth(w2)
663 if w2_width != &columns && w2_width < 80
664 call assert_equal(['col', [['leaf', w3],
665 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
666 else
667 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
668 \ ['leaf', w1]]] , winlayout())
669 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100670
671 new | only
672 set buftype=help
673 set modified
674 call assert_fails('Xnext', 'E37:')
675 set nomodified
676 new | only
677
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200678 if a:cchar == 'l'
679 " When a help window is present, running :lhelpgrep should reuse the
680 " help window and not the current window
681 new | only
682 call g:Xsetlist([], 'f')
683 help index.txt
684 wincmd w
685 lhelpgrep quickfix
686 call assert_equal(1, winnr())
687 call assert_notequal([], getloclist(1))
688 call assert_equal([], getloclist(2))
689 endif
690
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200691 new | only
692
Bram Moolenaaree85df32017-03-19 14:19:50 +0100693 " Search for non existing help string
694 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200695 " Invalid regular expression
696 call assert_fails('Xhelpgrep \@<!', 'E480:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100697endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200698
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100699func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200700 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200701 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200702 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100703endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100704
Bram Moolenaar6920c722016-01-22 22:44:10 +0100705func Test_errortitle()
706 augroup QfBufWinEnter
707 au!
708 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
709 augroup END
710 copen
711 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
712 call setqflist(a)
713 call assert_equal(':setqflist()', g:a)
714 augroup QfBufWinEnter
715 au!
716 augroup END
717 augroup! QfBufWinEnter
718endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100719
Bram Moolenaar5584df62016-03-18 21:00:51 +0100720func Test_vimgreptitle()
721 augroup QfBufWinEnter
722 au!
723 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
724 augroup END
725 try
726 vimgrep /pattern/j file
727 catch /E480/
728 endtry
729 copen
730 call assert_equal(': vimgrep /pattern/j file', g:a)
731 augroup QfBufWinEnter
732 au!
733 augroup END
734 augroup! QfBufWinEnter
735endfunc
736
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100737func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200738 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100739
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200740 Xgetexpr ['file:1:1:message']
741 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100742 if a:cchar == 'c'
743 call setqflist(l, 'r')
744 else
745 call setloclist(0, l, 'r')
746 endif
747
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200748 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100749 if a:cchar == 'c'
750 let title = ':setqflist()'
751 else
752 let title = ':setloclist()'
753 endif
754 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200755 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100756endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100757
758" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100759func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200760 call XqfTitleTests('c')
761 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100762endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100763
764" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100765func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100766 let save_efm = &efm
767 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
768 cgetexpr ['WWWW', 'EEEE', 'CCCC']
769 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
770 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
771 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
772 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
773 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
774 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
775 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
776 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
777 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100778endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100779
780" This will test for problems in quickfix:
781" A. incorrectly copying location lists which caused the location list to show
782" a different name than the file that was actually being displayed.
783" B. not reusing the window for which the location list window is opened but
784" instead creating new windows.
785" C. make sure that the location list window is not reused instead of the
786" window it belongs to.
787"
788" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100789func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100790 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
791 let word = substitute(base, '\v(.*)\..*', '\1', '')
792
793 setl modifiable
794 setl noreadonly
795 setl noswapfile
796 setl bufhidden=delete
797 %del _
798 " For problem 2:
799 " 'buftype' has to be set to reproduce the constant opening of new windows
800 setl buftype=nofile
801
802 call setline(1, word)
803
804 setl nomodified
805 setl nomodifiable
806 setl readonly
807 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100808endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100809
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100810func Test_locationlist()
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100811 enew
812
813 augroup testgroup
814 au!
815 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
816 augroup END
817
818 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
819
820 let qflist = []
821 for word in words
822 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
823 " NOTE: problem 1:
824 " intentionally not setting 'lnum' so that the quickfix entries are not
825 " valid
Bram Moolenaaraad222c2019-09-06 22:46:09 +0200826 eval qflist->setloclist(0, ' ')
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100827 endfor
828
829 " Test A
830 lrewind
831 enew
832 lopen
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200833 4lnext
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100834 vert split
835 wincmd L
836 lopen
837 wincmd p
838 lnext
839 let fileName = expand("%")
840 wincmd p
841 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
842 let fileName = substitute(fileName, '\\', '/', 'g')
843 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
844 call assert_equal("test://bar.txt", fileName)
845 call assert_equal("test://bar.txt", locationListFileName)
846
847 wincmd n | only
848
849 " Test B:
850 lrewind
851 lopen
852 2
853 exe "normal \<CR>"
854 wincmd p
855 3
856 exe "normal \<CR>"
857 wincmd p
858 4
859 exe "normal \<CR>"
860 call assert_equal(2, winnr('$'))
861 wincmd n | only
862
863 " Test C:
864 lrewind
865 lopen
866 " Let's move the location list window to the top to check whether it (the
867 " first window found) will be reused when we try to open new windows:
868 wincmd K
869 2
870 exe "normal \<CR>"
871 wincmd p
872 3
873 exe "normal \<CR>"
874 wincmd p
875 4
876 exe "normal \<CR>"
877 1wincmd w
878 call assert_equal('quickfix', &buftype)
879 2wincmd w
880 let bufferName = expand("%")
881 let bufferName = substitute(bufferName, '\\', '/', 'g')
882 call assert_equal('test://quux.txt', bufferName)
883
884 wincmd n | only
885
886 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100887endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100888
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100889func Test_locationlist_curwin_was_closed()
Bram Moolenaar0899d692016-03-19 13:35:03 +0100890 augroup testgroup
891 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +0200892 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
Bram Moolenaar0899d692016-03-19 13:35:03 +0100893 augroup END
894
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100895 func! R(n)
Bram Moolenaar0899d692016-03-19 13:35:03 +0100896 quit
897 endfunc
898
899 new
900 let q = []
Bram Moolenaard106e5b2016-04-21 19:38:07 +0200901 call add(q, {'filename': 'test_curwin.txt' })
Bram Moolenaar0899d692016-03-19 13:35:03 +0100902 call setloclist(0, q)
903 call assert_fails('lrewind', 'E924:')
904
905 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100906endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100907
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100908func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200909 call writefile(['loclistfoo'], 'loclistfoo')
910 call writefile(['loclistbar'], 'loclistbar')
911 set switchbuf=usetab
912
913 edit loclistfoo
914 tabedit loclistbar
915 silent lgrep loclistfoo loclist*
916 call assert_equal(1, tabpagenr())
917
918 enew | only | tabonly
919 set switchbuf&vim
920 call delete('loclistfoo')
921 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100922endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200923
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100924" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100925func Test_efm1()
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100926 if !has('unix')
927 " The 'errorformat' setting is different on non-Unix systems.
928 " This test works only on Unix-like systems.
929 return
930 endif
931
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200932 let l =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200933 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
934 "Xtestfile", line 6 col 19; this is an error
935 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
936 Xtestfile:9: parse error before `asd'
937 make: *** [vim] Error 1
938 in file "Xtestfile" linenr 10: there is an error
939
940 2 returned
941 "Xtestfile", line 11 col 1; this is an error
942 "Xtestfile", line 12 col 2; this is another error
943 "Xtestfile", line 14:10; this is an error in column 10
944 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
945 "Xtestfile", linenr 16: yet another problem
946 Error in "Xtestfile" at line 17:
947 x should be a dot
948 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
949 ^
950 Error in "Xtestfile" at line 18:
951 x should be a dot
952 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
953 .............^
954 Error in "Xtestfile" at line 19:
955 x should be a dot
956 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
957 --------------^
958 Error in "Xtestfile" at line 20:
959 x should be a dot
960 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
961 ^
962
963 Does anyone know what is the problem and how to correction it?
964 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
965 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200966 [DATA]
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100967
968 call writefile(l, 'Xerrorfile1')
969 call writefile(l[:-2], 'Xerrorfile2')
970
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200971 let m =<< [DATA]
972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
987 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
988 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
989 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
991 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
992 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
993[DATA]
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100994 call writefile(m, 'Xtestfile')
995
996 let save_efm = &efm
997 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
998 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
999
1000 exe 'cf Xerrorfile2'
1001 clast
1002 copen
1003 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1004 wincmd p
1005
1006 exe 'cf Xerrorfile1'
1007 call assert_equal([4, 12], [line('.'), col('.')])
1008 cn
1009 call assert_equal([6, 19], [line('.'), col('.')])
1010 cn
1011 call assert_equal([9, 2], [line('.'), col('.')])
1012 cn
1013 call assert_equal([10, 2], [line('.'), col('.')])
1014 cn
1015 call assert_equal([11, 1], [line('.'), col('.')])
1016 cn
1017 call assert_equal([12, 2], [line('.'), col('.')])
1018 cn
1019 call assert_equal([14, 10], [line('.'), col('.')])
1020 cn
1021 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1022 cn
1023 call assert_equal([16, 2], [line('.'), col('.')])
1024 cn
1025 call assert_equal([17, 6], [line('.'), col('.')])
1026 cn
1027 call assert_equal([18, 7], [line('.'), col('.')])
1028 cn
1029 call assert_equal([19, 8], [line('.'), col('.')])
1030 cn
1031 call assert_equal([20, 9], [line('.'), col('.')])
1032 clast
1033 cprev
1034 cprev
1035 wincmd w
1036 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1037 wincmd p
1038
1039 let &efm = save_efm
1040 call delete('Xerrorfile1')
1041 call delete('Xerrorfile2')
1042 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001043endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001044
Bram Moolenaarab47c612016-06-14 22:02:26 +02001045" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001046func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001047 call s:setup_commands(a:cchar)
1048
Bram Moolenaarab47c612016-06-14 22:02:26 +02001049 let save_efm=&efm
1050 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1051
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001052 let lines = ["Entering dir 'dir1/a'",
1053 \ 'habits2.txt:1:Nine Healthy Habits',
1054 \ "Entering dir 'b'",
1055 \ 'habits3.txt:2:0 Hours of television',
1056 \ 'habits2.txt:7:5 Small meals',
1057 \ "Entering dir 'dir1/c'",
1058 \ 'habits4.txt:3:1 Hour of exercise',
1059 \ "Leaving dir 'dir1/c'",
1060 \ "Leaving dir 'dir1/a'",
1061 \ 'habits1.txt:4:2 Liters of water',
1062 \ "Entering dir 'dir2'",
1063 \ 'habits5.txt:5:3 Cups of hot green tea',
1064 \ "Leaving dir 'dir2'"
1065 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001066
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001067 Xexpr ""
1068 for l in lines
1069 Xaddexpr l
1070 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001071
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001072 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001073
1074 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1075 call assert_equal(1, qf[1].lnum)
1076 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1077 call assert_equal(2, qf[3].lnum)
1078 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1079 call assert_equal(7, qf[4].lnum)
1080 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1081 call assert_equal(3, qf[6].lnum)
1082 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1083 call assert_equal(4, qf[9].lnum)
1084 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1085 call assert_equal(5, qf[11].lnum)
1086
1087 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001088endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001089
1090" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001091func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001092 " Create the directory stack and files
1093 call mkdir('dir1')
1094 call mkdir('dir1/a')
1095 call mkdir('dir1/a/b')
1096 call mkdir('dir1/c')
1097 call mkdir('dir2')
1098
1099 let lines = ["Nine Healthy Habits",
1100 \ "0 Hours of television",
1101 \ "1 Hour of exercise",
1102 \ "2 Liters of water",
1103 \ "3 Cups of hot green tea",
1104 \ "4 Short mental breaks",
1105 \ "5 Small meals",
1106 \ "6 AM wake up time",
1107 \ "7 Minutes of laughter",
1108 \ "8 Hours of sleep (at least)",
1109 \ "9 PM end of the day and off to bed"
1110 \ ]
1111 call writefile(lines, 'habits1.txt')
1112 call writefile(lines, 'dir1/a/habits2.txt')
1113 call writefile(lines, 'dir1/a/b/habits3.txt')
1114 call writefile(lines, 'dir1/c/habits4.txt')
1115 call writefile(lines, 'dir2/habits5.txt')
1116
1117 call s:dir_stack_tests('c')
1118 call s:dir_stack_tests('l')
1119
1120 call delete('dir1', 'rf')
1121 call delete('dir2', 'rf')
1122 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001123endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001124
Bram Moolenaar9b457942016-10-09 16:10:05 +02001125" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001126func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001127 call s:setup_commands(a:cchar)
1128
1129 let save_efm = &efm
1130
1131 let &efm =
1132 \ '%Eerror %m %l,' .
1133 \ '%-Wignored %m %l,' .
1134 \ '%+Cmore ignored %m %l,' .
1135 \ '%Zignored end'
1136 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1137 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1138 call assert_equal([['resync', 1, 4, 'E']], l)
1139
1140 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001141endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001142
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001143func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001144 call Xefm_ignore_continuations('c')
1145 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001146endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001147
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001148" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001149func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001150 call s:setup_commands(a:cchar)
1151
Bram Moolenaar049cba92016-06-26 14:38:04 +02001152 let save_efm = &efm
1153
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001154 set efm=%f:%l:%m,%f:%f:%l:%m
1155 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1156
1157 set efm=%f:%l:%m,%f:%l:%r:%m
1158 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1159
1160 set efm=%f:%l:%m,%O:%f:%l:%m
1161 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1162
1163 set efm=%f:%l:%m,%f:%l:%*[^a-z
1164 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1165
1166 set efm=%f:%l:%m,%f:%l:%*c
1167 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1168
1169 set efm=%f:%l:%m,%L%M%N
1170 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1171
1172 set efm=%f:%l:%m,%f:%l:%m:%R
1173 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1174
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001175 " Invalid regular expression
1176 set efm=%\\%%k
1177 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1178
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001179 set efm=
1180 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1181
1182 set efm=%DEntering\ dir\ abc,%f:%l:%m
1183 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1184
1185 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001186endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001187
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001188func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001189 call Xinvalid_efm_Tests('c')
1190 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001191endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001192
1193" TODO:
1194" Add tests for the following formats in 'errorformat'
1195" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001196func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001197 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001198
1199 " Test for %s format in efm
1200 set efm=%f:%s
1201 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001202 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001203 call assert_equal('^\VLine search text\$', l[0].pattern)
1204 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001205
Bram Moolenaaree85df32017-03-19 14:19:50 +01001206 let l = split(execute('clist', ''), "\n")
1207 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1208
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001209 " Test for a long line
1210 cexpr 'Xtestfile:' . repeat('a', 1026)
1211 let l = getqflist()
1212 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1213
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001214 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001215 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001216 [Xtestfile1]
1217 (1,17) error: ';' missing
1218 (21,2) warning: variable 'z' not defined
1219 (67,3) error: end of file found before string ended
1220 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001221
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001222 [Xtestfile2]
1223 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001224
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001225 [Xtestfile3]
1226 NEW compiler v1.1
1227 (2,2) warning: variable 'x' not defined
1228 (67,3) warning: 's' already defined
1229 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001230 [DATA]
1231
Bram Moolenaaree85df32017-03-19 14:19:50 +01001232 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001233 " To exercise the push/pop file functionality in quickfix, the test files
1234 " need to be created.
1235 call writefile(['Line1'], 'Xtestfile1')
1236 call writefile(['Line2'], 'Xtestfile2')
1237 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001238 cexpr ""
1239 for l in lines
1240 caddexpr l
1241 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001242 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001243 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001244 call assert_equal(21, l[2].lnum)
1245 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001246 call assert_equal('w', l[2].type)
1247 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001248 call delete('Xtestfile1')
1249 call delete('Xtestfile2')
1250 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001251
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001252 " Test for %P, %Q with non-existing files
1253 cexpr lines
1254 let l = getqflist()
1255 call assert_equal(14, len(l))
1256 call assert_equal('[Xtestfile1]', l[0].text)
1257 call assert_equal('[Xtestfile2]', l[6].text)
1258 call assert_equal('[Xtestfile3]', l[9].text)
1259
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001260 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001261 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001262 Error 275
1263 line 42
1264 column 3
1265 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001266 [DATA]
1267
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001268 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1269 cgetexpr lines
1270 let l = getqflist()
1271 call assert_equal(275, l[0].nr)
1272 call assert_equal(42, l[0].lnum)
1273 call assert_equal(3, l[0].col)
1274 call assert_equal('E', l[0].type)
1275 call assert_equal("\n' ' expected after '--'", l[0].text)
1276
1277 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001278 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001279 Error in line 147 of foo.c:
1280 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001281 [DATA]
1282
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001283 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1284 cgetexpr lines
1285 let l = getqflist()
1286 call assert_equal(147, l[0].lnum)
1287 call assert_equal('E', l[0].type)
1288 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001289
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001290 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001291 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001292 ==============================================================
1293 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1294 --------------------------------------------------------------
1295 Traceback (most recent call last):
1296 File "unittests/dbfacadeTest.py", line 89, in testFoo
1297 self.assertEquals(34, dtid)
1298 File "/usr/lib/python2.2/unittest.py", line 286, in
1299 failUnlessEqual
1300 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001301 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001302
1303 --------------------------------------------------------------
1304 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001305 [DATA]
1306
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001307 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001308 cgetexpr lines
1309 let l = getqflist()
1310 call assert_equal(8, len(l))
1311 call assert_equal(89, l[4].lnum)
1312 call assert_equal(1, l[4].valid)
1313 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001314 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001315
Bram Moolenaard76ce852018-05-01 15:02:04 +02001316 " Test for %o
1317 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001318 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1319 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001320 let l = getqflist()
1321 call assert_equal(1, len(l), string(l))
1322 call assert_equal('Language.PureScript.Types', l[0].module)
1323 copen
1324 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1325 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001326 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001327 cclose
1328 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001329 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001330
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001331 " Test for a long module name
1332 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1333 let l = getqflist()
1334 call assert_equal(repeat('m', 1024), l[0].module)
1335 call assert_equal(15, l[0].lnum)
1336 call assert_equal('message', l[0].text)
1337
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001338 " The following sequence of commands used to crash Vim
1339 set efm=%W%m
1340 cgetexpr ['msg1']
1341 let l = getqflist()
1342 call assert_equal(1, len(l), string(l))
1343 call assert_equal('msg1', l[0].text)
1344 set efm=%C%m
1345 lexpr 'msg2'
1346 let l = getloclist(0)
1347 call assert_equal(1, len(l), string(l))
1348 call assert_equal('msg2', l[0].text)
1349 lopen
1350 call setqflist([], 'r')
1351 caddbuf
1352 let l = getqflist()
1353 call assert_equal(1, len(l), string(l))
1354 call assert_equal('|| msg2', l[0].text)
1355
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001356 " When matching error lines, case should be ignored. Test for this.
1357 set noignorecase
1358 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1359 call assert_equal(10, l.items[0].lnum)
1360 call assert_equal('Line 20', l.items[0].text)
1361 set ignorecase&
1362
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001363 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001364 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001365endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001366
Bram Moolenaare9283662020-06-07 14:10:47 +02001367" Test for '%t' (error type) field in 'efm'
1368func Test_efm_error_type()
1369 let save_efm = &efm
1370
1371 " error type
1372 set efm=%f:%l:%t:%m
1373 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1374 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1375 let output = split(execute('clist'), "\n")
1376 call assert_equal([
1377 \ ' 1 Xfile1:10 error: msg1',
1378 \ ' 2 Xfile1:20 warning: msg2',
1379 \ ' 3 Xfile1:30 info: msg3',
1380 \ ' 4 Xfile1:40 note: msg4',
1381 \ ' 5 Xfile1:50 R: msg5'], output)
1382
1383 " error type and a error number
1384 set efm=%f:%l:%t:%n:%m
1385 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1386 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1387 let output = split(execute('clist'), "\n")
1388 call assert_equal([
1389 \ ' 1 Xfile1:10 error 2: msg1',
1390 \ ' 2 Xfile1:20 warning 4: msg2',
1391 \ ' 3 Xfile1:30 info 6: msg3',
1392 \ ' 4 Xfile1:40 note 8: msg4',
1393 \ ' 5 Xfile1:50 R 3: msg5'], output)
1394 let &efm = save_efm
1395endfunc
1396
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001397func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001398 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001399 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001400 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001401 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001402 colder
1403 cgetexpr []
1404 endfunc
1405 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001406 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001407 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001408 lolder
1409 lgetexpr []
1410 endfunc
1411 endif
1412
1413 augroup testgroup
1414 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001415 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001416 augroup END
1417
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001418 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001419 let words = [ "a", "b" ]
1420 let qflist = []
1421 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001422 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001423 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001424 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001425 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001426
1427 augroup! testgroup
1428endfunc
1429
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001430func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001431 call XquickfixChangedByAutocmd('c')
1432 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001433endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001434
1435func Test_caddbuffer_to_empty()
1436 helpgr quickfix
1437 call setqflist([], 'r')
1438 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001439 try
1440 cn
1441 catch
1442 " number of matches is unknown
1443 call assert_true(v:exception =~ 'E553:')
1444 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001445 quit!
1446endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001447
1448func Test_cgetexpr_works()
1449 " this must not crash Vim
1450 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001451 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001452endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001453
1454" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001455func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001456 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001457
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001458 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001459 \ {'bufnr': a:bnum, 'lnum': 2}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001460 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001461 call assert_equal(2, len(l))
1462 call assert_equal(2, l[1].lnum)
1463
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001464 Xnext
1465 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1466 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001467 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001468 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001469 call assert_equal(3, line('.'))
1470
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001471 " Appending entries to the list should not change the cursor position
1472 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001473 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001474 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001475 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001476 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1477 call assert_equal(1, line('.'))
1478 close
1479
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001480 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001481 \ {'bufnr': a:bnum, 'lnum': 4},
1482 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001483 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001484 call assert_equal(3, len(l))
1485 call assert_equal(5, l[2].lnum)
1486
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001487 call g:Xsetlist([])
1488 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001489 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001490
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001491 " Tests for setting the 'valid' flag
1492 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1493 Xwindow
1494 call assert_equal(1, winnr('$'))
1495 let l = g:Xgetlist()
1496 call g:Xsetlist(l)
1497 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001498 " Adding a non-valid entry should not mark the list as having valid entries
1499 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1500 Xwindow
1501 call assert_equal(1, winnr('$'))
1502
1503 " :cnext/:cprev should still work even with invalid entries in the list
1504 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1505 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1506 call g:Xsetlist(l)
1507 Xnext
1508 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1509 Xprev
1510 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1511 " :cnext/:cprev should still work after appending invalid entries to an
1512 " empty list
1513 call g:Xsetlist([])
1514 call g:Xsetlist(l, 'a')
1515 Xnext
1516 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1517 Xprev
1518 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1519
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001520 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1521 Xwindow
1522 call assert_equal(2, winnr('$'))
1523 Xclose
1524 let save_efm = &efm
1525 set efm=%m
1526 Xgetexpr 'TestMessage'
1527 let l = g:Xgetlist()
1528 call g:Xsetlist(l)
1529 call assert_equal(1, g:Xgetlist()[0].valid)
1530 let &efm = save_efm
1531
Bram Moolenaaree85df32017-03-19 14:19:50 +01001532 " Error cases:
1533 " Refer to a non-existing buffer and pass a non-dictionary type
1534 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1535 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1536 call g:Xsetlist([[1, 2,3]])
1537 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001538 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001539endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001540
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001541func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001542 new Xtestfile | only
1543 let bnum = bufnr('%')
1544 call setline(1, range(1,5))
1545
1546 call SetXlistTests('c', bnum)
1547 call SetXlistTests('l', bnum)
1548
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001549 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001550 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001551endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001552
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001553func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001554 call s:setup_commands(a:cchar)
1555
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001556 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001557 let @/ = 'Test_'
1558 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001560 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001561 Xvimgrep empty test_quickfix.vim
1562 call assert_true(len(g:Xgetlist()) > 0)
1563 Xvimgrep matches test_quickfix.vim
1564 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001565 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001566 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001567 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001568 call g:Xsetlist([], 'r')
1569 call assert_true(len(g:Xgetlist()) == 0)
1570 Xolder
1571 call assert_equal(testlen, len(g:Xgetlist()))
1572 Xnewer
1573 Xnewer
1574 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001575endfunc
1576
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001577func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001578 call Xlist_empty_middle('c')
1579 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001580endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001581
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001582func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001583 call s:setup_commands(a:cchar)
1584
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001585 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001586 Xvimgrep one test_quickfix.vim
1587 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001588 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001589 Xvimgrep two test_quickfix.vim
1590 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001591 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001592 Xvimgrep three test_quickfix.vim
1593 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001594 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001595 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001596 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001597 call g:Xsetlist([], 'r')
1598 call assert_true(len(g:Xgetlist()) == 0)
1599 Xnewer
1600 call assert_equal(twolen, len(g:Xgetlist()))
1601 Xnewer
1602 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001603endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001604
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001605func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001606 call Xlist_empty_older('c')
1607 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001608endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001609
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001610func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001611 call s:setup_commands(a:cchar)
1612
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001613 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1614 \ {'filename': 'fnameB', 'text': 'B'}]
1615 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1616 \ {'filename': 'fnameD', 'text': 'D'},
1617 \ {'filename': 'fnameE', 'text': 'E'}]
1618
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001619 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001620 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001621 silent! Xnewer 99
1622 call g:Xsetlist(list1)
1623 call g:Xsetlist(list2)
1624 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001625 call assert_equal(3, len(li))
1626 call assert_equal('C', li[0]['text'])
1627 call assert_equal('D', li[1]['text'])
1628 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001629 silent! Xolder
1630 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001631 call assert_equal(2, len(li))
1632 call assert_equal('A', li[0]['text'])
1633 call assert_equal('B', li[1]['text'])
1634
1635 " {action} is specified ' '.
1636 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001637 silent! Xnewer 99
1638 call g:Xsetlist(list1)
1639 call g:Xsetlist(list2, ' ')
1640 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001641 call assert_equal(3, len(li))
1642 call assert_equal('C', li[0]['text'])
1643 call assert_equal('D', li[1]['text'])
1644 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001645 silent! Xolder
1646 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001647 call assert_equal(2, len(li))
1648 call assert_equal('A', li[0]['text'])
1649 call assert_equal('B', li[1]['text'])
1650
1651 " {action} is specified 'a'.
1652 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 silent! Xnewer 99
1654 call g:Xsetlist(list1)
1655 call g:Xsetlist(list2, 'a')
1656 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001657 call assert_equal(5, len(li))
1658 call assert_equal('A', li[0]['text'])
1659 call assert_equal('B', li[1]['text'])
1660 call assert_equal('C', li[2]['text'])
1661 call assert_equal('D', li[3]['text'])
1662 call assert_equal('E', li[4]['text'])
1663
1664 " {action} is specified 'r'.
1665 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001666 silent! Xnewer 99
1667 call g:Xsetlist(list1)
1668 call g:Xsetlist(list2, 'r')
1669 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001670 call assert_equal(3, len(li))
1671 call assert_equal('C', li[0]['text'])
1672 call assert_equal('D', li[1]['text'])
1673 call assert_equal('E', li[2]['text'])
1674
1675 " Test for wrong value.
1676 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001677 call assert_fails("call g:Xsetlist(0)", 'E714:')
1678 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1679 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1680 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1681 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001682endfunc
1683
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001684func Test_setqflist_invalid_nr()
1685 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001686 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001687endfunc
1688
Bram Moolenaar99234f22020-02-10 22:56:54 +01001689func Test_setqflist_user_sets_buftype()
1690 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1691 set buftype=quickfix
1692 call setqflist([], 'a')
1693 enew
1694endfunc
1695
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001696func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001697 call XquickfixSetListWithAct('c')
1698 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001699endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001700
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001701func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001702 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001703
Bram Moolenaar049cba92016-06-26 14:38:04 +02001704 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001705 call assert_equal(1, l[0].lnum)
1706 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001707 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001708 call assert_equal(2, l[1].lnum)
1709 call assert_equal(1, l[1].col)
1710 call assert_equal(4070, len(l[1].text))
1711 call assert_equal(3, l[2].lnum)
1712 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001713 call assert_equal(4070, len(l[2].text))
1714 call assert_equal(4, l[3].lnum)
1715 call assert_equal(1, l[3].col)
1716 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001717
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001718 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001719endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001720
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001721func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001722 call s:setup_commands(a:cchar)
1723
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001724 let testfile = 'samples/quickfix.txt'
1725
1726 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001727 exe 'Xgetfile' testfile
1728 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001729
1730 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001731 Xexpr readfile(testfile)
1732 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001733
1734 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 Xexpr join(readfile(testfile), "\n")
1736 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001737
1738 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 exe 'edit' testfile
1740 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001741 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001742endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001743
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001744func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001745 call s:long_lines_tests('c')
1746 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001747endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001748
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001749func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001750 let l = []
1751 for i in range(1, 20)
1752 call add(l, 'Line' . i)
1753 endfor
1754 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001755endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001756
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001758 call s:create_test_file('Xqftestfile1')
1759 call s:create_test_file('Xqftestfile2')
1760 call s:create_test_file('Xqftestfile3')
1761
1762 new | only
1763 edit Xqftestfile1
1764 let file1_winid = win_getid()
1765 new Xqftestfile2
1766 let file2_winid = win_getid()
1767 cgetexpr ['Xqftestfile1:5:Line5',
1768 \ 'Xqftestfile1:6:Line6',
1769 \ 'Xqftestfile2:10:Line10',
1770 \ 'Xqftestfile2:11:Line11',
1771 \ 'Xqftestfile3:15:Line15',
1772 \ 'Xqftestfile3:16:Line16']
1773
1774 new
1775 let winid = win_getid()
1776 cfirst | cnext
1777 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001778 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001779 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001780 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001781 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001782
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001783 " Test for 'switchbuf' set to search for files in windows in the current
1784 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001785 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001786 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001787 cfirst | cnext
1788 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001789 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001790 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001791 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001792 call assert_equal(file2_winid, win_getid())
1793
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001794 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1795 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001796 enew | only
1797 set switchbuf=usetab
1798 tabedit Xqftestfile1
1799 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001800 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001801 tabfirst
1802 cfirst | cnext
1803 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001804 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001805 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001806 6cnext
1807 call assert_equal(4, tabpagenr())
1808 2cpfile
1809 call assert_equal(2, tabpagenr())
1810 2cnfile
1811 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001812 tabfirst | tabonly | enew
1813
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001814 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001815 set switchbuf=split
1816 cfirst | cnext
1817 call assert_equal(1, winnr('$'))
1818 cnext | cnext
1819 call assert_equal(2, winnr('$'))
1820 cnext | cnext
1821 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001822
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001823 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001824 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001825 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001826 cfirst | cnext
1827 call assert_equal(1, tabpagenr('$'))
1828 cnext | cnext
1829 call assert_equal(2, tabpagenr('$'))
1830 cnext | cnext
1831 call assert_equal(3, tabpagenr('$'))
1832 tabfirst | enew | tabonly | only
1833
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001834 set switchbuf=uselast
1835 split
1836 let last_winid = win_getid()
1837 copen
1838 exe "normal 1G\<CR>"
1839 call assert_equal(last_winid, win_getid())
1840 enew | only
1841
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001842 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1843 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001844 set switchbuf=
1845 edit Xqftestfile1
1846 let file1_winid = win_getid()
1847 new Xqftestfile2
1848 let file2_winid = win_getid()
1849 copen
1850 exe "normal 1G\<CR>"
1851 call assert_equal(file1_winid, win_getid())
1852 copen
1853 exe "normal 3G\<CR>"
1854 call assert_equal(file2_winid, win_getid())
1855 copen | only
1856 exe "normal 5G\<CR>"
1857 call assert_equal(2, winnr('$'))
1858 call assert_equal(1, bufwinnr('Xqftestfile3'))
1859
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001860 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001861 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001862 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001863 set switchbuf=usetab
1864 tabedit Xqftestfile1
1865 tabedit Xqftestfile2
1866 tabedit Xqftestfile3
1867 tabfirst
1868 copen | only
1869 clast
1870 call assert_equal(4, tabpagenr())
1871 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001872
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001873 " Jumping to a file that is not present in any of the tabpages and the
1874 " current tabpage doesn't have any usable windows, should open it in a new
1875 " window in the current tabpage.
1876 copen | only
1877 cfirst
1878 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001879 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001880
1881 " If opening a file changes 'switchbuf', then the new value should be
1882 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001883 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001884 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1885 enew | only
1886 set switchbuf&vim
1887 cexpr "Xqftestfile1:1:10"
1888 call assert_equal('split', &switchbuf)
1889 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1890 enew | only
1891 set switchbuf=useopen
1892 cexpr "Xqftestfile1:1:10"
1893 call assert_equal('usetab', &switchbuf)
1894 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1895 enew | only
1896 set switchbuf=useopen
1897 cexpr "Xqftestfile1:1:10"
1898 call assert_equal('', &switchbuf)
1899
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 call delete('Xqftestfile1')
1901 call delete('Xqftestfile2')
1902 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001903 set switchbuf&vim
1904
1905 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001906endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001907
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001908func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001909 call s:setup_commands(a:cchar)
1910
1911 enew | only
1912
Bram Moolenaarc1542742016-07-20 21:44:37 +02001913 let fname = 'Xqftestfile' . a:cchar
1914 call s:create_test_file(fname)
1915 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02001916
Bram Moolenaarc1542742016-07-20 21:44:37 +02001917 Xgetexpr [fname . ':5:Line5',
1918 \ fname . ':10:Line10',
1919 \ fname . ':15:Line15',
1920 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02001921
1922 6,14delete
1923 call append(6, ['Buffer', 'Window'])
1924
1925 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001926 call assert_equal(5, l[0].lnum)
1927 call assert_equal(6, l[2].lnum)
1928 call assert_equal(13, l[3].lnum)
1929
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001930 " If a file doesn't have any quickfix entries, then deleting lines in the
1931 " file should not update the quickfix list
1932 call g:Xsetlist([], 'f')
1933 1,2delete
1934 call assert_equal([], g:Xgetlist())
1935
Bram Moolenaar049cba92016-06-26 14:38:04 +02001936 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02001937 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001938endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001939
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001940func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02001941 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001942 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02001943 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001944 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001945endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001946
1947" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001948func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001949 call s:setup_commands(a:cchar)
1950
1951 " The following lines are used for the grep test. Don't remove.
1952 " Grep_Test_Text: Match 1
1953 " Grep_Test_Text: Match 2
1954 " GrepAdd_Test_Text: Match 1
1955 " GrepAdd_Test_Text: Match 2
1956 enew! | only
1957 set makeef&vim
1958 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001959 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001960 Xopen
1961 call assert_true(w:quickfix_title =~ '^:grep')
1962 Xclose
1963 enew
1964 set makeef=Temp_File_##
1965 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001966 call assert_true(len(g:Xgetlist()) == 9)
1967
1968 " Try with 'grepprg' set to 'internal'
1969 set grepprg=internal
1970 silent Xgrep Grep_Test_Text: test_quickfix.vim
1971 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1972 call assert_true(len(g:Xgetlist()) == 9)
1973 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001974
1975 call writefile(['Vim'], 'XtestTempFile')
1976 set makeef=XtestTempFile
1977 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001978 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001979 call assert_false(filereadable('XtestTempFile'))
1980 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001981endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001982
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001983func Test_grep()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001984 if !has('unix')
1985 " The grepprg may not be set on non-Unix systems
1986 return
1987 endif
1988
1989 call s:test_xgrep('c')
1990 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001991endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001992
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001993func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001994 " Use one 'errorformat' for two windows. Add an expression to each of them,
1995 " make sure they each keep their own state.
1996 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1997 call mkdir('Xone/a', 'p')
1998 call mkdir('Xtwo/a', 'p')
1999 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2000 call writefile(lines, 'Xone/a/one.txt')
2001 call writefile(lines, 'Xtwo/a/two.txt')
2002
2003 new one
2004 let one_id = win_getid()
2005 lexpr ""
2006 new two
2007 let two_id = win_getid()
2008 lexpr ""
2009
2010 laddexpr "Entering dir 'Xtwo/a'"
2011 call win_gotoid(one_id)
2012 laddexpr "Entering dir 'Xone/a'"
2013 call win_gotoid(two_id)
2014 laddexpr 'two.txt:5:two two two'
2015 call win_gotoid(one_id)
2016 laddexpr 'one.txt:3:one one one'
2017
2018 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002019 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2020 call assert_equal(3, loc_one[1].lnum)
2021
2022 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002023 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2024 call assert_equal(5, loc_two[1].lnum)
2025
2026 call win_gotoid(one_id)
2027 bwipe!
2028 call win_gotoid(two_id)
2029 bwipe!
2030 call delete('Xone', 'rf')
2031 call delete('Xtwo', 'rf')
2032endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002033
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002034func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002035 call s:setup_commands(a:cchar)
2036
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002037 " Calling lbottom without any errors should fail
2038 if a:cchar == 'l'
2039 call assert_fails('lbottom', 'E776:')
2040 endif
2041
Bram Moolenaar875feea2017-06-11 16:07:51 +02002042 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002043 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002044 let wid = win_getid()
2045 call assert_equal(1, line('.'))
2046 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002047 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002048 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002049 call win_gotoid(wid)
2050 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002051 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002052endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002053
2054" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002055func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002056 call XbottomTests('c')
2057 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002058endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002059
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002060func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002061 call s:setup_commands(a:cchar)
2062
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002063 " clear all lists after the first one, then replace the first one.
2064 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002065 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002066 let entry = {'filename': 'foo', 'lnum': 42}
2067 call g:Xsetlist([entry], 'r')
2068 call g:Xsetlist([entry, entry])
2069 call g:Xsetlist([entry, entry, entry])
2070 let res = split(execute(a:cchar . 'hist'), "\n")
2071 call assert_equal(3, len(res))
2072 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2073 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2074 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2075 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002076
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002077 " Test for changing the quickfix lists
2078 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2079 exe '1' . a:cchar . 'hist'
2080 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2081 exe '3' . a:cchar . 'hist'
2082 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2083 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2084 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2085
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002086 call g:Xsetlist([], 'f')
2087 let l = split(execute(a:cchar . 'hist'), "\n")
2088 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002089 if a:cchar == 'c'
2090 call assert_fails('4chist', 'E16:')
2091 else
2092 call assert_fails('4lhist', 'E776:')
2093 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002094
2095 " An empty list should still show the stack history
2096 call g:Xsetlist([])
2097 let res = split(execute(a:cchar . 'hist'), "\n")
2098 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2099
2100 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002101endfunc
2102
2103func Test_history()
2104 call HistoryTest('c')
2105 call HistoryTest('l')
2106endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002107
2108func Test_duplicate_buf()
2109 " make sure we can get the highest buffer number
2110 edit DoesNotExist
2111 edit DoesNotExist2
2112 let last_buffer = bufnr("$")
2113
2114 " make sure only one buffer is created
2115 call writefile(['this one', 'that one'], 'Xgrepthis')
2116 vimgrep one Xgrepthis
2117 vimgrep one Xgrepthis
2118 call assert_equal(last_buffer + 1, bufnr("$"))
2119
2120 call delete('Xgrepthis')
2121endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002122
2123" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002124func Xproperty_tests(cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002125 call s:setup_commands(a:cchar)
2126
2127 " Error cases
2128 call assert_fails('call g:Xgetlist(99)', 'E715:')
2129 call assert_fails('call g:Xsetlist(99)', 'E714:')
2130 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
2131
2132 " Set and get the title
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002133 call g:Xsetlist([])
Bram Moolenaard823fa92016-08-12 16:29:27 +02002134 Xopen
2135 wincmd p
2136 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002137 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2138 call assert_equal(0, s)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002139 let d = g:Xgetlist({"title":1})
2140 call assert_equal('Sample', d.title)
Bram Moolenaara2aa8a22018-04-24 13:55:00 +02002141 " Try setting title to a non-string value
2142 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2143 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002144
2145 Xopen
2146 call assert_equal('Sample', w:quickfix_title)
2147 Xclose
2148
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002149 " Tests for action argument
2150 silent! Xolder 999
2151 let qfnr = g:Xgetlist({'all':1}).nr
2152 call g:Xsetlist([], 'r', {'title' : 'N1'})
2153 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2154 call g:Xsetlist([], ' ', {'title' : 'N2'})
2155 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
Bram Moolenaar890680c2016-09-27 21:28:56 +02002156
2157 let res = g:Xgetlist({'nr': 0})
2158 call assert_equal(qfnr + 1, res.nr)
2159 call assert_equal(['nr'], keys(res))
2160
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002161 call g:Xsetlist([], ' ', {'title' : 'N3'})
2162 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2163
Bram Moolenaaree85df32017-03-19 14:19:50 +01002164 " Changing the title of an earlier quickfix list
Bram Moolenaar55b69262017-08-13 13:42:01 +02002165 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
Bram Moolenaaree85df32017-03-19 14:19:50 +01002166 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2167
2168 " Changing the title of an invalid quickfix list
2169 call assert_equal(-1, g:Xsetlist([], ' ',
2170 \ {'title' : 'SomeTitle', 'nr' : 99}))
2171 call assert_equal(-1, g:Xsetlist([], ' ',
2172 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2173
2174 if a:cchar == 'c'
2175 copen
2176 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2177 cclose
2178 endif
2179
Bram Moolenaard823fa92016-08-12 16:29:27 +02002180 " Invalid arguments
2181 call assert_fails('call g:Xgetlist([])', 'E715')
2182 call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
2183 let s = g:Xsetlist([], 'a', {'abc':1})
2184 call assert_equal(-1, s)
2185
2186 call assert_equal({}, g:Xgetlist({'abc':1}))
Bram Moolenaara6d48492017-12-12 22:45:31 +01002187 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2188 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002189
2190 if a:cchar == 'l'
Bram Moolenaar890680c2016-09-27 21:28:56 +02002191 call assert_equal({}, getloclist(99, {'title': 1}))
Bram Moolenaard823fa92016-08-12 16:29:27 +02002192 endif
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002193
2194 " Context related tests
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002195 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2196 call assert_equal(0, s)
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002197 call test_garbagecollect_now()
2198 let d = g:Xgetlist({'context':1})
2199 call assert_equal([1,2,3], d.context)
2200 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2201 let d = g:Xgetlist({'context':1})
2202 call assert_equal({'color':'green'}, d.context)
2203 call g:Xsetlist([], 'a', {'context':"Context info"})
2204 let d = g:Xgetlist({'context':1})
2205 call assert_equal("Context info", d.context)
2206 call g:Xsetlist([], 'a', {'context':246})
2207 let d = g:Xgetlist({'context':1})
2208 call assert_equal(246, d.context)
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02002209 " set other Vim data types as context
2210 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2211 if has('channel')
2212 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2213 endif
2214 if has('job')
2215 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2216 endif
2217 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2218 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2219 call g:Xsetlist([], 'a', {'context' : ''})
2220 call test_garbagecollect_now()
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002221 if a:cchar == 'l'
2222 " Test for copying context across two different location lists
2223 new | only
2224 let w1_id = win_getid()
2225 let l = [1]
2226 call setloclist(0, [], 'a', {'context':l})
2227 new
2228 let w2_id = win_getid()
2229 call add(l, 2)
2230 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2231 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2232 unlet! l
2233 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2234 only
2235 call setloclist(0, [], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01002236 call assert_equal('', getloclist(0, {'context':1}).context)
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002237 endif
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002238
2239 " Test for changing the context of previous quickfix lists
2240 call g:Xsetlist([], 'f')
2241 Xexpr "One"
2242 Xexpr "Two"
2243 Xexpr "Three"
Bram Moolenaar55b69262017-08-13 13:42:01 +02002244 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2245 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002246 " Also, check for setting the context using quickfix list number zero.
Bram Moolenaar55b69262017-08-13 13:42:01 +02002247 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002248 call test_garbagecollect_now()
2249 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2250 call assert_equal([1], l.context)
2251 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2252 call assert_equal([2], l.context)
2253 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2254 call assert_equal([3], l.context)
2255
2256 " Test for changing the context through reference and for garbage
2257 " collection of quickfix context
2258 let l = ["red"]
2259 call g:Xsetlist([], ' ', {'context' : l})
2260 call add(l, "blue")
2261 let x = g:Xgetlist({'context' : 1})
2262 call add(x.context, "green")
2263 call assert_equal(["red", "blue", "green"], l)
2264 call assert_equal(["red", "blue", "green"], x.context)
2265 unlet l
2266 call test_garbagecollect_now()
2267 let m = g:Xgetlist({'context' : 1})
2268 call assert_equal(["red", "blue", "green"], m.context)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002269
2270 " Test for setting/getting items
2271 Xexpr ""
2272 let qfprev = g:Xgetlist({'nr':0})
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002273 let s = g:Xsetlist([], ' ', {'title':'Green',
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002274 \ 'items' : [{'filename':'F1', 'lnum':10}]})
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002275 call assert_equal(0, s)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002276 let qfcur = g:Xgetlist({'nr':0})
2277 call assert_true(qfcur.nr == qfprev.nr + 1)
2278 let l = g:Xgetlist({'items':1})
2279 call assert_equal('F1', bufname(l.items[0].bufnr))
2280 call assert_equal(10, l.items[0].lnum)
2281 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2282 \ {'filename':'F2', 'lnum':30}]})
2283 let l = g:Xgetlist({'items':1})
2284 call assert_equal('F2', bufname(l.items[2].bufnr))
2285 call assert_equal(30, l.items[2].lnum)
2286 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2287 let l = g:Xgetlist({'items':1})
2288 call assert_equal('F3', bufname(l.items[0].bufnr))
2289 call assert_equal(40, l.items[0].lnum)
2290 call g:Xsetlist([], 'r', {'items' : []})
2291 let l = g:Xgetlist({'items':1})
2292 call assert_equal(0, len(l.items))
2293
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002294 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2295 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2296 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2297 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2298
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02002299 " Test for getting id of window associated with a location list window
2300 if a:cchar == 'l'
2301 only
2302 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2303 let wid = win_getid()
2304 Xopen
2305 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2306 wincmd w
2307 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2308 only
2309 endif
2310
Bram Moolenaarae338332017-08-11 20:25:26 +02002311 " The following used to crash Vim with address sanitizer
2312 call g:Xsetlist([], 'f')
2313 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2314 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
2315
Bram Moolenaara2aa8a22018-04-24 13:55:00 +02002316 " Try setting the items using a string
2317 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
2318
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002319 " Save and restore the quickfix stack
2320 call g:Xsetlist([], 'f')
2321 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2322 Xexpr "File1:10:Line1"
2323 Xexpr "File2:20:Line2"
2324 Xexpr "File3:30:Line3"
2325 let last_qf = g:Xgetlist({'nr':'$'}).nr
2326 call assert_equal(3, last_qf)
2327 let qstack = []
2328 for i in range(1, last_qf)
2329 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2330 endfor
2331 call g:Xsetlist([], 'f')
2332 for i in range(len(qstack))
2333 call g:Xsetlist([], ' ', qstack[i])
2334 endfor
2335 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2336 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2337 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2338 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2339 call g:Xsetlist([], 'f')
2340
2341 " Swap two quickfix lists
2342 Xexpr "File1:10:Line10"
2343 Xexpr "File2:20:Line20"
2344 Xexpr "File3:30:Line30"
2345 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2346 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2347 let l1=g:Xgetlist({'nr':1,'all':1})
2348 let l2=g:Xgetlist({'nr':2,'all':1})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02002349 let save_id = l1.id
2350 let l1.id=l2.id
2351 let l2.id=save_id
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002352 call g:Xsetlist([], 'r', l1)
2353 call g:Xsetlist([], 'r', l2)
2354 let newl1=g:Xgetlist({'nr':1,'all':1})
2355 let newl2=g:Xgetlist({'nr':2,'all':1})
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002356 call assert_equal('Fruits', newl1.title)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002357 call assert_equal(['Fruits'], newl1.context)
2358 call assert_equal('Line20', newl1.items[0].text)
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002359 call assert_equal('Colors', newl2.title)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002360 call assert_equal(['Colors'], newl2.context)
2361 call assert_equal('Line10', newl2.items[0].text)
2362 call g:Xsetlist([], 'f')
Bram Moolenaarbe7a50c2020-06-30 22:11:44 +02002363
2364 " Cannot specify both a non-empty list argument and a dict argument
2365 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002366endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002367
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002368func Test_qf_property()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002369 call Xproperty_tests('c')
2370 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002371endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002372
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002373" Test for setting the current index in the location/quickfix list
2374func Xtest_setqfidx(cchar)
2375 call s:setup_commands(a:cchar)
2376
2377 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2378 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2379 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2380
2381 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2382 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2383 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2384 Xolder 2
2385 Xopen
2386 call assert_equal(3, line('.'))
2387 Xnewer
2388 call assert_equal(2, line('.'))
2389 Xnewer
2390 call assert_equal(2, line('.'))
2391 " Update the current index with the quickfix window open
2392 wincmd w
2393 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2394 Xopen
2395 call assert_equal(3, line('.'))
2396 Xclose
2397
2398 " Set the current index to the last entry
2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2400 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2401 " A large value should set the index to the last index
2402 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2403 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2404 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2405 " Invalid index values
2406 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2407 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2408 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2409 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2410 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2411 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2412 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2413
2414 call g:Xsetlist([], 'f')
2415 new | only
2416endfunc
2417
2418func Test_setqfidx()
2419 call Xtest_setqfidx('c')
2420 call Xtest_setqfidx('l')
2421endfunc
2422
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002423" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002424func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002425 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002426endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002427
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002428func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002429 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2430 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2431
2432 let g:acmds = []
2433 cexpr "F1:10:Line 10"
2434 caddexpr "F1:20:Line 20"
2435 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002436 cexpr ""
2437 caddexpr ""
2438 cgetexpr ""
2439 silent! cexpr non_existing_func()
2440 silent! caddexpr non_existing_func()
2441 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002442 let l = ['precexpr',
2443 \ 'postcexpr',
2444 \ 'precaddexpr',
2445 \ 'postcaddexpr',
2446 \ 'precgetexpr',
2447 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002448 \ 'precexpr',
2449 \ 'postcexpr',
2450 \ 'precaddexpr',
2451 \ 'postcaddexpr',
2452 \ 'precgetexpr',
2453 \ 'postcgetexpr',
2454 \ 'precexpr',
2455 \ 'precaddexpr',
2456 \ 'precgetexpr']
2457 call assert_equal(l, g:acmds)
2458
2459 let g:acmds = []
2460 enew! | call append(0, "F2:10:Line 10")
2461 cbuffer!
2462 enew! | call append(0, "F2:20:Line 20")
2463 cgetbuffer
2464 enew! | call append(0, "F2:30:Line 30")
2465 caddbuffer
2466 new
2467 let bnum = bufnr('%')
2468 bunload
2469 exe 'silent! cbuffer! ' . bnum
2470 exe 'silent! cgetbuffer ' . bnum
2471 exe 'silent! caddbuffer ' . bnum
2472 enew!
2473 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002474 \ 'postcbuffer',
2475 \ 'precgetbuffer',
2476 \ 'postcgetbuffer',
2477 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002478 \ 'postcaddbuffer',
2479 \ 'precbuffer',
2480 \ 'precgetbuffer',
2481 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002482 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002483
2484 call writefile(['Xtest:1:Line1'], 'Xtest')
2485 call writefile([], 'Xempty')
2486 let g:acmds = []
2487 cfile Xtest
2488 caddfile Xtest
2489 cgetfile Xtest
2490 cfile Xempty
2491 caddfile Xempty
2492 cgetfile Xempty
2493 silent! cfile do_not_exist
2494 silent! caddfile do_not_exist
2495 silent! cgetfile do_not_exist
2496 let l = ['precfile',
2497 \ 'postcfile',
2498 \ 'precaddfile',
2499 \ 'postcaddfile',
2500 \ 'precgetfile',
2501 \ 'postcgetfile',
2502 \ 'precfile',
2503 \ 'postcfile',
2504 \ 'precaddfile',
2505 \ 'postcaddfile',
2506 \ 'precgetfile',
2507 \ 'postcgetfile',
2508 \ 'precfile',
2509 \ 'postcfile',
2510 \ 'precaddfile',
2511 \ 'postcaddfile',
2512 \ 'precgetfile',
2513 \ 'postcgetfile']
2514 call assert_equal(l, g:acmds)
2515
2516 let g:acmds = []
2517 helpgrep quickfix
2518 silent! helpgrep non_existing_help_topic
2519 vimgrep test Xtest
2520 vimgrepadd test Xtest
2521 silent! vimgrep non_existing_test Xtest
2522 silent! vimgrepadd non_existing_test Xtest
2523 set makeprg=
2524 silent! make
2525 set makeprg&
2526 let l = ['prehelpgrep',
2527 \ 'posthelpgrep',
2528 \ 'prehelpgrep',
2529 \ 'posthelpgrep',
2530 \ 'previmgrep',
2531 \ 'postvimgrep',
2532 \ 'previmgrepadd',
2533 \ 'postvimgrepadd',
2534 \ 'previmgrep',
2535 \ 'postvimgrep',
2536 \ 'previmgrepadd',
2537 \ 'postvimgrepadd',
2538 \ 'premake',
2539 \ 'postmake']
2540 call assert_equal(l, g:acmds)
2541
2542 if has('unix')
2543 " Run this test only on Unix-like systems. The grepprg may not be set on
2544 " non-Unix systems.
2545 " The following lines are used for the grep test. Don't remove.
2546 " Grep_Autocmd_Text: Match 1
2547 " GrepAdd_Autocmd_Text: Match 2
2548 let g:acmds = []
2549 silent grep Grep_Autocmd_Text test_quickfix.vim
2550 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2551 silent grep abc123def Xtest
2552 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002553 set grepprg=internal
2554 silent grep Grep_Autocmd_Text test_quickfix.vim
2555 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2556 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2557 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2558 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002559 let l = ['pregrep',
2560 \ 'postgrep',
2561 \ 'pregrepadd',
2562 \ 'postgrepadd',
2563 \ 'pregrep',
2564 \ 'postgrep',
2565 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002566 \ 'postgrepadd',
2567 \ 'pregrep',
2568 \ 'postgrep',
2569 \ 'pregrepadd',
2570 \ 'postgrepadd',
2571 \ 'prelgrep',
2572 \ 'postlgrep',
2573 \ 'prelgrepadd',
2574 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002575 call assert_equal(l, g:acmds)
2576 endif
2577
2578 call delete('Xtest')
2579 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002580 au! QuickFixCmdPre
2581 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002582endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002583
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002584func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002585 set efm=%m
2586 lgetexpr '?'
2587
2588 try
2589 call DoesNotExit()
2590 catch
2591 lgetexpr '1'
2592 finally
2593 lgetexpr '1'
2594 endtry
2595
2596 call assert_equal('1', getloclist(0)[0].text)
2597
2598 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002599endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002600
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002601func Test_caddbuffer_wrong()
2602 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002603 let save_efm = &efm
2604 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2605 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2606 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002607 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002608 bwipe!
2609endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002610
2611func Test_caddexpr_wrong()
2612 " This used to cause a memory access in freed memory.
2613 cbuffer
2614 cbuffer
2615 copen
2616 let save_efm = &efm
2617 set efm=%
2618 call assert_fails('caddexpr ""', 'E376:')
2619 let &efm = save_efm
2620endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002621
2622func Test_dirstack_cleanup()
2623 " This used to cause a memory access in freed memory.
2624 let save_efm = &efm
2625 lexpr '0'
2626 lopen
2627 fun X(c)
2628 let save_efm=&efm
2629 set efm=%D%f
2630 if a:c == 'c'
2631 caddexpr '::'
2632 else
2633 laddexpr ':0:0'
2634 endif
2635 let &efm=save_efm
2636 endfun
2637 call X('c')
2638 call X('l')
2639 call setqflist([], 'r')
2640 caddbuffer
2641 let &efm = save_efm
2642endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002643
2644" Tests for jumping to entries from the location list window and quickfix
2645" window
2646func Test_cwindow_jump()
2647 set efm=%f%%%l%%%m
2648 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2649 lopen | only
2650 lfirst
2651 call assert_true(winnr('$') == 2)
2652 call assert_true(winnr() == 1)
2653 " Location list for the new window should be set
2654 call assert_true(getloclist(0)[2].text == 'Line 30')
2655
2656 " Open a scratch buffer
2657 " Open a new window and create a location list
2658 " Open the location list window and close the other window
2659 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002660 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002661 " should not be used.
2662 enew | only
2663 set buftype=nofile
2664 below new
2665 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2666 lopen
2667 2wincmd c
2668 lnext
2669 call assert_true(winnr('$') == 3)
2670 call assert_true(winnr() == 2)
2671
2672 " Open two windows with two different location lists
2673 " Open the location list window and close the previous window
2674 " Jump to an entry in the location list window
2675 " Should open the file in the first window and not set the location list.
2676 enew | only
2677 lgetexpr ["F1%5%Line 5"]
2678 below new
2679 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2680 lopen
2681 2wincmd c
2682 lnext
2683 call assert_true(winnr() == 1)
2684 call assert_true(getloclist(0)[0].text == 'Line 5')
2685
2686 enew | only
2687 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2688 copen
2689 cnext
2690 call assert_true(winnr('$') == 2)
2691 call assert_true(winnr() == 1)
2692
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002693 " open the quickfix buffer in two windows and jump to an entry. Should open
2694 " the file in the first quickfix window.
2695 enew | only
2696 copen
2697 let bnum = bufnr('')
2698 exe 'sbuffer ' . bnum
2699 wincmd b
2700 cfirst
2701 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002702 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002703 enew | only
2704 exe 'sb' bnum
2705 exe 'botright sb' bnum
2706 wincmd t
2707 clast
2708 call assert_equal(2, winnr())
2709 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2710 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2711
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002712 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002713 " window by wrapping around the window list.
2714 enew | only
2715 call setloclist(0, [], 'f')
2716 new | new
2717 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2718 lopen
2719 1close
2720 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2721 lnext
2722 call assert_equal(3, winnr())
2723 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2724
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002725 enew | only
2726 set efm&vim
2727endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002728
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002729func Test_cwindow_highlight()
2730 CheckScreendump
2731
2732 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002733 call setline(1, ['some', 'text', 'with', 'matches'])
2734 write XCwindow
2735 vimgrep e XCwindow
2736 redraw
2737 cwindow 4
2738 END
2739 call writefile(lines, 'XtestCwindow')
2740 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2741 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2742
2743 call term_sendkeys(buf, ":cnext\<CR>")
2744 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2745
2746 " clean up
2747 call StopVimInTerminal(buf)
2748 call delete('XtestCwindow')
2749 call delete('XCwindow')
2750endfunc
2751
Bram Moolenaaree85df32017-03-19 14:19:50 +01002752func XvimgrepTests(cchar)
2753 call s:setup_commands(a:cchar)
2754
2755 call writefile(['Editor:VIM vim',
2756 \ 'Editor:Emacs EmAcS',
2757 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2758 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2759
2760 " Error cases
2761 call assert_fails('Xvimgrep /abc *', 'E682:')
2762
2763 let @/=''
2764 call assert_fails('Xvimgrep // *', 'E35:')
2765
2766 call assert_fails('Xvimgrep abc', 'E683:')
2767 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2768 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2769
2770 Xexpr ""
2771 Xvimgrepadd Notepad Xtestfile1
2772 Xvimgrepadd MacOS Xtestfile2
2773 let l = g:Xgetlist()
2774 call assert_equal(2, len(l))
2775 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2776
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002777 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002778 let l = g:Xgetlist()
2779 call assert_equal(2, len(l))
2780 call assert_equal(8, l[0].col)
2781 call assert_equal(12, l[1].col)
2782
2783 1Xvimgrep ?Editor? Xtestfile*
2784 let l = g:Xgetlist()
2785 call assert_equal(1, len(l))
2786 call assert_equal('Editor:VIM vim', l[0].text)
2787
2788 edit +3 Xtestfile2
2789 Xvimgrep +\cemacs+j Xtestfile1
2790 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002791 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002792 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2793
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002794 " Test for unloading a buffer after vimgrep searched the buffer
2795 %bwipe
2796 Xvimgrep /Editor/j Xtestfile*
2797 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2798 call assert_equal([], getbufinfo('Xtestfile2'))
2799
Bram Moolenaaree85df32017-03-19 14:19:50 +01002800 call delete('Xtestfile1')
2801 call delete('Xtestfile2')
2802endfunc
2803
2804" Tests for the :vimgrep command
2805func Test_vimgrep()
2806 call XvimgrepTests('c')
2807 call XvimgrepTests('l')
2808endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002809
Bram Moolenaar1c299432018-10-28 14:36:09 +01002810" Test for incsearch highlighting of the :vimgrep pattern
2811" This test used to cause "E315: ml_get: invalid lnum" errors.
2812func Test_vimgrep_incsearch()
2813 enew
2814 set incsearch
2815 call test_override("char_avail", 1)
2816
2817 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2818 let l = getqflist()
2819 call assert_equal(2, len(l))
2820
2821 call test_override("ALL", 0)
2822 set noincsearch
2823endfunc
2824
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002825" Test vimgrep with the last search pattern not set
2826func Test_vimgrep_with_no_last_search_pat()
2827 let lines =<< trim [SCRIPT]
2828 call assert_fails('vimgrep // *', 'E35:')
2829 call writefile(v:errors, 'Xresult')
2830 qall!
2831 [SCRIPT]
2832 call writefile(lines, 'Xscript')
2833 if RunVim([], [], '--clean -S Xscript')
2834 call assert_equal([], readfile('Xresult'))
2835 endif
2836 call delete('Xscript')
2837 call delete('Xresult')
2838endfunc
2839
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002840func XfreeTests(cchar)
2841 call s:setup_commands(a:cchar)
2842
2843 enew | only
2844
2845 " Deleting the quickfix stack should work even When the current list is
2846 " somewhere in the middle of the stack
2847 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2848 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2849 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2850 Xolder
2851 call g:Xsetlist([], 'f')
2852 call assert_equal(0, len(g:Xgetlist()))
2853
2854 " After deleting the stack, adding a new list should create a stack with a
2855 " single list.
2856 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2857 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2858
2859 " Deleting the stack from a quickfix window should update/clear the
2860 " quickfix/location list window.
2861 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2862 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2863 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2864 Xolder
2865 Xwindow
2866 call g:Xsetlist([], 'f')
2867 call assert_equal(2, winnr('$'))
2868 call assert_equal(1, line('$'))
2869 Xclose
2870
2871 " Deleting the stack from a non-quickfix window should update/clear the
2872 " quickfix/location list window.
2873 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2874 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2875 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2876 Xolder
2877 Xwindow
2878 wincmd p
2879 call g:Xsetlist([], 'f')
2880 call assert_equal(0, len(g:Xgetlist()))
2881 wincmd p
2882 call assert_equal(2, winnr('$'))
2883 call assert_equal(1, line('$'))
2884
2885 " After deleting the location list stack, if the location list window is
2886 " opened, then a new location list should be created. So opening the
2887 " location list window again should not create a new window.
2888 if a:cchar == 'l'
2889 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2890 wincmd p
2891 lopen
2892 call assert_equal(2, winnr('$'))
2893 endif
2894 Xclose
2895endfunc
2896
Bram Moolenaar74240d32017-12-10 15:26:15 +01002897" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002898func Test_qf_free()
2899 call XfreeTests('c')
2900 call XfreeTests('l')
2901endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002902
2903" Test for buffer overflow when parsing lines and adding new entries to
2904" the quickfix list.
2905func Test_bufoverflow()
2906 set efm=%f:%l:%m
2907 cgetexpr ['File1:100:' . repeat('x', 1025)]
2908
2909 set efm=%+GCompiler:\ %.%#,%f:%l:%m
2910 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2911
2912 set efm=%DEntering\ directory\ %f,%f:%l:%m
2913 cgetexpr ['Entering directory ' . repeat('a', 1006),
2914 \ 'File1:10:Hello World']
2915 set efm&vim
2916endfunc
2917
Bram Moolenaar875feea2017-06-11 16:07:51 +02002918" Tests for getting the quickfix stack size
2919func XsizeTests(cchar)
2920 call s:setup_commands(a:cchar)
2921
2922 call g:Xsetlist([], 'f')
2923 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01002924 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2925 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02002926
2927 Xexpr "File1:10:Line1"
2928 Xexpr "File2:20:Line2"
2929 Xexpr "File3:30:Line3"
2930 Xolder | Xolder
2931 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2932 call g:Xsetlist([], 'f')
2933
2934 Xexpr "File1:10:Line1"
2935 Xexpr "File2:20:Line2"
2936 Xexpr "File3:30:Line3"
2937 Xolder | Xolder
2938 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2939 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2940endfunc
2941
2942func Test_Qf_Size()
2943 call XsizeTests('c')
2944 call XsizeTests('l')
2945endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02002946
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002947func Test_cclose_from_copen()
2948 augroup QF_Test
2949 au!
2950 au FileType qf :call assert_fails(':cclose', 'E788')
2951 augroup END
2952 copen
2953 augroup QF_Test
2954 au!
2955 augroup END
2956 augroup! QF_Test
2957endfunc
2958
Bram Moolenaar18141832017-06-25 21:17:25 +02002959func Test_cclose_in_autocmd()
2960 " Problem is only triggered if "starting" is zero, so that the OptionsSet
2961 " event will be triggered.
2962 call test_override('starting', 1)
2963 augroup QF_Test
2964 au!
2965 au FileType qf :call assert_fails(':cclose', 'E788')
2966 augroup END
2967 copen
2968 augroup QF_Test
2969 au!
2970 augroup END
2971 augroup! QF_Test
2972 call test_override('starting', 0)
2973endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002974
Bram Moolenaar379fb762018-08-30 15:58:28 +02002975" Check that ":file" without an argument is possible even when "curbuf_lock"
2976" is set.
2977func Test_file_from_copen()
2978 " Works without argument.
2979 augroup QF_Test
2980 au!
2981 au FileType qf file
2982 augroup END
2983 copen
2984
2985 augroup QF_Test
2986 au!
2987 augroup END
2988 cclose
2989
2990 " Fails with argument.
2991 augroup QF_Test
2992 au!
2993 au FileType qf call assert_fails(':file foo', 'E788')
2994 augroup END
2995 copen
2996 augroup QF_Test
2997 au!
2998 augroup END
2999 cclose
3000
3001 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003002endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003003
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003004func Test_resize_from_copen()
3005 augroup QF_Test
3006 au!
3007 au FileType qf resize 5
3008 augroup END
3009 try
3010 " This should succeed without any exception. No other buffers are
3011 " involved in the autocmd.
3012 copen
3013 finally
3014 augroup QF_Test
3015 au!
3016 augroup END
3017 augroup! QF_Test
3018 endtry
3019endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003020
3021" Tests for the quickfix buffer b:changedtick variable
3022func Xchangedtick_tests(cchar)
3023 call s:setup_commands(a:cchar)
3024
3025 new | only
3026
3027 Xexpr "" | Xexpr "" | Xexpr ""
3028
3029 Xopen
3030 Xolder
3031 Xolder
3032 Xaddexpr "F1:10:Line10"
3033 Xaddexpr "F2:20:Line20"
3034 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3035 call g:Xsetlist([], 'f')
3036 call assert_equal(8, getbufvar('%', 'changedtick'))
3037 Xclose
3038endfunc
3039
3040func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003041 call Xchangedtick_tests('c')
3042 call Xchangedtick_tests('l')
3043endfunc
3044
3045" Tests for parsing an expression using setqflist()
3046func Xsetexpr_tests(cchar)
3047 call s:setup_commands(a:cchar)
3048
3049 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003050 call g:Xsetlist([], ' ', {'lines' : t})
3051 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003052
3053 let l = g:Xgetlist()
3054 call assert_equal(3, len(l))
3055 call assert_equal(20, l[1].lnum)
3056 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003057 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003058 let l = g:Xgetlist()
3059 call assert_equal(1, len(l))
3060 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003061 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3062 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003063
3064 call g:Xsetlist([], 'f')
3065 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003066 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3067 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3068 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3069 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003070 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3071 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003072
3073 " Adding entries using a custom efm
3074 set efm&
3075 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3076 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3077 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3078 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3079 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3080 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3081 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3082 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003083endfunc
3084
3085func Test_setexpr()
3086 call Xsetexpr_tests('c')
3087 call Xsetexpr_tests('l')
3088endfunc
3089
3090" Tests for per quickfix/location list directory stack
3091func Xmultidirstack_tests(cchar)
3092 call s:setup_commands(a:cchar)
3093
3094 call g:Xsetlist([], 'f')
3095 Xexpr "" | Xexpr ""
3096
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003097 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3098 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3099 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3100 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003101
3102 let l1 = g:Xgetlist({'nr':1, 'items':1})
3103 let l2 = g:Xgetlist({'nr':2, 'items':1})
3104 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3105 call assert_equal(3, l1.items[1].lnum)
3106 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3107 call assert_equal(5, l2.items[1].lnum)
3108endfunc
3109
3110func Test_multidirstack()
3111 call mkdir('Xone/a', 'p')
3112 call mkdir('Xtwo/a', 'p')
3113 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3114 call writefile(lines, 'Xone/a/one.txt')
3115 call writefile(lines, 'Xtwo/a/two.txt')
3116 let save_efm = &efm
3117 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3118
3119 call Xmultidirstack_tests('c')
3120 call Xmultidirstack_tests('l')
3121
3122 let &efm = save_efm
3123 call delete('Xone', 'rf')
3124 call delete('Xtwo', 'rf')
3125endfunc
3126
3127" Tests for per quickfix/location list file stack
3128func Xmultifilestack_tests(cchar)
3129 call s:setup_commands(a:cchar)
3130
3131 call g:Xsetlist([], 'f')
3132 Xexpr "" | Xexpr ""
3133
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003134 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3135 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3136 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3137 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003138
3139 let l1 = g:Xgetlist({'nr':1, 'items':1})
3140 let l2 = g:Xgetlist({'nr':2, 'items':1})
3141 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3142 call assert_equal(3, l1.items[1].lnum)
3143 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3144 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003145
3146 " Test for start of a new error line in the same line where a previous
3147 " error line ends with a file stack.
3148 let efm_val = 'Error\ l%l\ in\ %f,'
3149 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3150 let l = g:Xgetlist({'lines' : [
3151 \ '(one.txt',
3152 \ 'Error l4 in one.txt',
3153 \ ') (two.txt',
3154 \ 'Error l6 in two.txt',
3155 \ ')',
3156 \ 'Error l8 in one.txt'
3157 \ ], 'efm' : efm_val})
3158 call assert_equal(3, len(l.items))
3159 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3160 call assert_equal(4, l.items[0].lnum)
3161 call assert_equal('one.txt', l.items[0].text)
3162 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3163 call assert_equal(6, l.items[1].lnum)
3164 call assert_equal('two.txt', l.items[1].text)
3165 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3166 call assert_equal(8, l.items[2].lnum)
3167 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003168endfunc
3169
3170func Test_multifilestack()
3171 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3172 call writefile(lines, 'one.txt')
3173 call writefile(lines, 'two.txt')
3174 let save_efm = &efm
3175 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3176
3177 call Xmultifilestack_tests('c')
3178 call Xmultifilestack_tests('l')
3179
3180 let &efm = save_efm
3181 call delete('one.txt')
3182 call delete('two.txt')
3183endfunc
3184
3185" Tests for per buffer 'efm' setting
3186func Test_perbuf_efm()
3187 call writefile(["File1-10-Line10"], 'one.txt')
3188 call writefile(["File2#20#Line20"], 'two.txt')
3189 set efm=%f#%l#%m
3190 new | only
3191 new
3192 setlocal efm=%f-%l-%m
3193 cfile one.txt
3194 wincmd w
3195 caddfile two.txt
3196
3197 let l = getqflist()
3198 call assert_equal(10, l[0].lnum)
3199 call assert_equal('Line20', l[1].text)
3200
3201 set efm&
3202 new | only
3203 call delete('one.txt')
3204 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003205endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003206
3207" Open multiple help windows using ":lhelpgrep
3208" This test used to crash Vim
3209func Test_Multi_LL_Help()
3210 new | only
3211 lhelpgrep window
3212 lopen
3213 e#
3214 lhelpgrep buffer
3215 call assert_equal(3, winnr('$'))
3216 call assert_true(len(getloclist(1)) != 0)
3217 call assert_true(len(getloclist(2)) != 0)
3218 new | only
3219endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003220
3221" Tests for adding new quickfix lists using setqflist()
3222func XaddQf_tests(cchar)
3223 call s:setup_commands(a:cchar)
3224
3225 " Create a new list using ' ' for action
3226 call g:Xsetlist([], 'f')
3227 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3228 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3229 call assert_equal(1, l.nr)
3230 call assert_equal('Test1', l.title)
3231
3232 " Create a new list using ' ' for action and '$' for 'nr'
3233 call g:Xsetlist([], 'f')
3234 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3235 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3236 call assert_equal(1, l.nr)
3237 call assert_equal('Test2', l.title)
3238
3239 " Create a new list using 'a' for action
3240 call g:Xsetlist([], 'f')
3241 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3242 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3243 call assert_equal(1, l.nr)
3244 call assert_equal('Test3', l.title)
3245
3246 " Create a new list using 'a' for action and '$' for 'nr'
3247 call g:Xsetlist([], 'f')
3248 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3249 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3250 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3251 call assert_equal(1, l.nr)
3252 call assert_equal('Test4', l.title)
3253
3254 " Adding a quickfix list should remove all the lists following the current
3255 " list.
3256 Xexpr "" | Xexpr "" | Xexpr ""
3257 silent! 10Xolder
3258 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3259 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3260 call assert_equal(2, l.nr)
3261 call assert_equal('Test5', l.title)
3262
3263 " Add a quickfix list using '$' as the list number.
3264 let lastqf = g:Xgetlist({'nr':'$'}).nr
3265 silent! 99Xolder
3266 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3267 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3268 call assert_equal(lastqf + 1, l.nr)
3269 call assert_equal('Test6', l.title)
3270
3271 " Add a quickfix list using 'nr' set to one more than the quickfix
3272 " list size.
3273 let lastqf = g:Xgetlist({'nr':'$'}).nr
3274 silent! 99Xolder
3275 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3276 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3277 call assert_equal(lastqf + 1, l.nr)
3278 call assert_equal('Test7', l.title)
3279
3280 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3281 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3282 silent! 99Xolder
3283 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3284 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3285 call assert_equal(10, l.nr)
3286 call assert_equal('Test8', l.title)
3287
3288 " Add a quickfix list using 'nr' set to a value greater than 10
3289 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3290
3291 " Try adding a quickfix list with 'nr' set to a value greater than the
3292 " quickfix list size but less than 10.
3293 call g:Xsetlist([], 'f')
3294 Xexpr "" | Xexpr "" | Xexpr ""
3295 silent! 99Xolder
3296 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3297
3298 " Add a quickfix list using 'nr' set to a some string or list
3299 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3300endfunc
3301
3302func Test_add_qf()
3303 call XaddQf_tests('c')
3304 call XaddQf_tests('l')
3305endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003306
3307" Test for getting the quickfix list items from some text without modifying
3308" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003309func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003310 call s:setup_commands(a:cchar)
3311 call g:Xsetlist([], 'f')
3312
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003313 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003314 call assert_equal(2, len(l))
3315 call assert_equal(30, l[1].lnum)
3316
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003317 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3318 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3319 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3320 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003321
Bram Moolenaar36538222017-09-02 19:51:44 +02003322 " Parse text using a custom efm
3323 set efm&
3324 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3325 call assert_equal('Line30', l[0].text)
3326 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3327 call assert_equal('File3:30:Line30', l[0].text)
3328 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3329 call assert_equal({}, l)
3330 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3331 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3332
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003333 " Make sure that the quickfix stack is not modified
3334 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3335endfunc
3336
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003337func Test_get_list_from_lines()
3338 call XgetListFromLines('c')
3339 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003340endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003341
3342" Tests for the quickfix list id
3343func Xqfid_tests(cchar)
3344 call s:setup_commands(a:cchar)
3345
3346 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003347 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003348 Xexpr ''
3349 let start_id = g:Xgetlist({'id' : 0}).id
3350 Xexpr '' | Xexpr ''
3351 Xolder
3352 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3353 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3354 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003355 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003356 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003357 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3358 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003359
3360 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3361 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003362 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003363 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3364 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3365 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3366
3367 let qfid = g:Xgetlist({'id':0, 'nr':0})
3368 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003369 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003370endfunc
3371
3372func Test_qf_id()
3373 call Xqfid_tests('c')
3374 call Xqfid_tests('l')
3375endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003376
3377func Xqfjump_tests(cchar)
3378 call s:setup_commands(a:cchar)
3379
3380 call writefile(["Line1\tFoo", "Line2"], 'F1')
3381 call writefile(["Line1\tBar", "Line2"], 'F2')
3382 call writefile(["Line1\tBaz", "Line2"], 'F3')
3383
3384 call g:Xsetlist([], 'f')
3385
3386 " Tests for
3387 " Jumping to a line using a pattern
3388 " Jumping to a column greater than the last column in a line
3389 " Jumping to a line greater than the last line in the file
3390 let l = []
3391 for i in range(1, 7)
3392 call add(l, {})
3393 endfor
3394 let l[0].filename='F1'
3395 let l[0].pattern='Line1'
3396 let l[1].filename='F2'
3397 let l[1].pattern='Line1'
3398 let l[2].filename='F3'
3399 let l[2].pattern='Line1'
3400 let l[3].filename='F3'
3401 let l[3].lnum=1
3402 let l[3].col=9
3403 let l[3].vcol=1
3404 let l[4].filename='F3'
3405 let l[4].lnum=99
3406 let l[5].filename='F3'
3407 let l[5].lnum=1
3408 let l[5].col=99
3409 let l[5].vcol=1
3410 let l[6].filename='F3'
3411 let l[6].pattern='abcxyz'
3412
3413 call g:Xsetlist([], ' ', {'items' : l})
3414 Xopen | only
3415 2Xnext
3416 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003417 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003418 Xnext
3419 call assert_equal(7, col('.'))
3420 Xnext
3421 call assert_equal(2, line('.'))
3422 Xnext
3423 call assert_equal(9, col('.'))
3424 2
3425 Xnext
3426 call assert_equal(2, line('.'))
3427
3428 if a:cchar == 'l'
3429 " When jumping to a location list entry in the location list window and
3430 " no usable windows are available, then a new window should be opened.
3431 enew! | new | only
3432 call g:Xsetlist([], 'f')
3433 setlocal buftype=nofile
3434 new
3435 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']})
3436 Xopen
3437 let winid = win_getid()
3438 wincmd p
3439 close
3440 call win_gotoid(winid)
3441 Xnext
3442 call assert_equal(3, winnr('$'))
3443 call assert_equal(1, winnr())
3444 call assert_equal(2, line('.'))
3445
3446 " When jumping to an entry in the location list window and the window
3447 " associated with the location list is not present and a window containing
3448 " the file is already present, then that window should be used.
3449 close
3450 belowright new
3451 call g:Xsetlist([], 'f')
3452 edit F3
3453 call win_gotoid(winid)
3454 Xlast
3455 call assert_equal(3, winnr())
3456 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3457 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3458 endif
3459
3460 " Cleanup
3461 enew!
3462 new | only
3463
3464 call delete('F1')
3465 call delete('F2')
3466 call delete('F3')
3467endfunc
3468
3469func Test_qfjump()
3470 call Xqfjump_tests('c')
3471 call Xqfjump_tests('l')
3472endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003473
3474" Tests for the getqflist() and getloclist() functions when the list is not
3475" present or is empty
3476func Xgetlist_empty_tests(cchar)
3477 call s:setup_commands(a:cchar)
3478
3479 " Empty quickfix stack
3480 call g:Xsetlist([], 'f')
3481 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3482 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3483 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3484 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3485 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3486 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3487 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3488 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003489 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003490 if a:cchar == 'c'
3491 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003492 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003493 \ 'title' : '', 'winid' : 0, 'changedtick': 0},
3494 \ g:Xgetlist({'all' : 0}))
3495 else
3496 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3497 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003498 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
3499 \ 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003500 \ g:Xgetlist({'all' : 0}))
3501 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003502
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003503 " Quickfix window with empty stack
3504 silent! Xopen
3505 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003506 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003507 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3508 Xclose
3509
Bram Moolenaara6d48492017-12-12 22:45:31 +01003510 " Empty quickfix list
3511 Xexpr ""
3512 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3513 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3514 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3515 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3516 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3517 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3518 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3519 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003520 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003521
3522 let qfid = g:Xgetlist({'id' : 0}).id
3523 call g:Xsetlist([], 'f')
3524
3525 " Non-existing quickfix identifier
3526 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3527 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3528 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3529 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3530 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3531 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3532 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3533 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003534 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003535 if a:cchar == 'c'
3536 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3537 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003538 \ 'qfbufnr' : qfbufnr,
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003539 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3540 else
3541 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3542 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003543 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003544 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3545 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003546
3547 " Non-existing quickfix list number
3548 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3549 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3550 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3551 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3552 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3553 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3554 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3555 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003556 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003557 if a:cchar == 'c'
3558 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3559 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003560 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr},
3561 \ g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003562 else
3563 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3564 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003565 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003566 \ g:Xgetlist({'nr' : 5, 'all' : 0}))
3567 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003568endfunc
3569
3570func Test_getqflist()
3571 call Xgetlist_empty_tests('c')
3572 call Xgetlist_empty_tests('l')
3573endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003574
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003575func Test_getqflist_invalid_nr()
3576 " The following commands used to crash Vim
3577 cexpr ""
3578 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3579
3580 " Cleanup
3581 call setqflist([], 'r')
3582endfunc
3583
Bram Moolenaarb254af32017-12-18 19:48:58 +01003584" Tests for the quickfix/location list changedtick
3585func Xqftick_tests(cchar)
3586 call s:setup_commands(a:cchar)
3587
3588 call g:Xsetlist([], 'f')
3589
3590 Xexpr "F1:10:Line10"
3591 let qfid = g:Xgetlist({'id' : 0}).id
3592 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3593 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3594 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3595 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3596 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3597 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3598 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3599 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3600 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3601
3602 enew!
3603 call append(0, ["F5:50:L50", "F6:60:L60"])
3604 Xaddbuffer
3605 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3606 enew!
3607
3608 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3609 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3610 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3611 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3612 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3613 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3614 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3615 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3616 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3617 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3618 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3619
3620 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3621 Xfile Xone
3622 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3623 Xaddfile Xone
3624 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3625
3626 " Test case for updating a non-current quickfix list
3627 call g:Xsetlist([], 'f')
3628 Xexpr "F1:1:L1"
3629 Xexpr "F2:2:L2"
3630 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3631 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3632 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3633
3634 call delete("Xone")
3635endfunc
3636
3637func Test_qf_tick()
3638 call Xqftick_tests('c')
3639 call Xqftick_tests('l')
3640endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003641
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003642" Test helpgrep with lang specifier
3643func Xtest_helpgrep_with_lang_specifier(cchar)
3644 call s:setup_commands(a:cchar)
3645 Xhelpgrep Vim@en
3646 call assert_equal('help', &filetype)
3647 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3648 new | only
3649endfunc
3650
3651func Test_helpgrep_with_lang_specifier()
3652 call Xtest_helpgrep_with_lang_specifier('c')
3653 call Xtest_helpgrep_with_lang_specifier('l')
3654endfunc
3655
Bram Moolenaar12237442017-12-19 12:38:52 +01003656" The following test used to crash Vim.
3657" Open the location list window and close the regular window associated with
3658" the location list. When the garbage collection runs now, it incorrectly
3659" marks the location list context as not in use and frees the context.
3660func Test_ll_window_ctx()
3661 call setloclist(0, [], 'f')
3662 call setloclist(0, [], 'a', {'context' : []})
3663 lopen | only
3664 call test_garbagecollect_now()
3665 echo getloclist(0, {'context' : 1}).context
3666 enew | only
3667endfunc
3668
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003669" The following test used to crash vim
3670func Test_lfile_crash()
3671 sp Xtest
3672 au QuickFixCmdPre * bw
3673 call assert_fails('lfile', 'E40')
3674 au! QuickFixCmdPre
3675endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003676
3677" The following test used to crash vim
3678func Test_lbuffer_crash()
3679 sv Xtest
3680 augroup QF_Test
3681 au!
3682 au * * bw
3683 augroup END
3684 lbuffer
3685 augroup QF_Test
3686 au!
3687 augroup END
3688endfunc
3689
3690" The following test used to crash vim
3691func Test_lexpr_crash()
3692 augroup QF_Test
3693 au!
3694 au * * call setloclist(0, [], 'f')
3695 augroup END
3696 lexpr ""
3697 augroup QF_Test
3698 au!
3699 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003700
Bram Moolenaar3c097222017-12-21 20:54:49 +01003701 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003702 augroup QF_Test
3703 au!
3704 au BufNew * call setloclist(0, [], 'f')
3705 augroup END
3706 lexpr 'x:1:x'
3707 augroup QF_Test
3708 au!
3709 augroup END
3710
3711 enew | only
3712 lexpr ''
3713 lopen
3714 augroup QF_Test
3715 au!
3716 au FileType * call setloclist(0, [], 'f')
3717 augroup END
3718 lexpr ''
3719 augroup QF_Test
3720 au!
3721 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003722endfunc
3723
3724" The following test used to crash Vim
3725func Test_lvimgrep_crash()
3726 sv Xtest
3727 augroup QF_Test
3728 au!
3729 au * * call setloclist(0, [], 'f')
3730 augroup END
3731 lvimgrep quickfix test_quickfix.vim
3732 augroup QF_Test
3733 au!
3734 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003735
3736 new | only
3737 augroup QF_Test
3738 au!
3739 au BufEnter * call setloclist(0, [], 'r')
3740 augroup END
3741 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3742 augroup QF_Test
3743 au!
3744 augroup END
3745
Bram Moolenaar3c097222017-12-21 20:54:49 +01003746 enew | only
3747endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003748
Bram Moolenaar2573af32020-03-14 17:21:34 +01003749func Test_lvimgrep_crash2()
3750 au BufNewFile x sfind
3751 call assert_fails('lvimgrep x x', 'E480:')
3752 call assert_fails('lvimgrep x x x', 'E480:')
3753
3754 au! BufNewFile
3755endfunc
3756
Bram Moolenaarde046542017-12-26 13:53:11 +01003757" Test for the position of the quickfix and location list window
3758func Test_qfwin_pos()
3759 " Open two windows
3760 new | only
3761 new
3762 cexpr ['F1:10:L10']
3763 copen
3764 " Quickfix window should be the bottom most window
3765 call assert_equal(3, winnr())
3766 close
3767 " Open at the very top
3768 wincmd t
3769 topleft copen
3770 call assert_equal(1, winnr())
3771 close
3772 " open left of the current window
3773 wincmd t
3774 below new
3775 leftabove copen
3776 call assert_equal(2, winnr())
3777 close
3778 " open right of the current window
3779 rightbelow copen
3780 call assert_equal(3, winnr())
3781 close
3782endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003783
3784" Tests for quickfix/location lists changed by autocommands when
3785" :vimgrep/:lvimgrep commands are running.
3786func Test_vimgrep_autocmd()
3787 call setqflist([], 'f')
3788 call writefile(['stars'], 'Xtest1.txt')
3789 call writefile(['stars'], 'Xtest2.txt')
3790
3791 " Test 1:
3792 " When searching for a pattern using :vimgrep, if the quickfix list is
3793 " changed by an autocmd, the results should be added to the correct quickfix
3794 " list.
3795 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3796 silent vimgrep stars Xtest*.txt
3797 call assert_equal(1, getqflist({'nr' : 0}).nr)
3798 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3799 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3800 au! BufRead Xtest2.txt
3801
3802 " Test 2:
3803 " When searching for a pattern using :vimgrep, if the quickfix list is
3804 " freed, then a error should be given.
3805 silent! %bwipe!
3806 call setqflist([], 'f')
3807 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3808 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3809 au! BufRead Xtest2.txt
3810
3811 " Test 3:
3812 " When searching for a pattern using :lvimgrep, if the location list is
3813 " freed, then the command should error out.
3814 silent! %bwipe!
3815 let g:save_winid = win_getid()
3816 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3817 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3818 au! BufRead Xtest2.txt
3819
3820 call delete('Xtest1.txt')
3821 call delete('Xtest2.txt')
3822 call setqflist([], 'f')
3823endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003824
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003825" Test for an autocmd changing the current directory when running vimgrep
3826func Xvimgrep_autocmd_cd(cchar)
3827 call s:setup_commands(a:cchar)
3828
3829 %bwipe
3830 let save_cwd = getcwd()
3831
3832 augroup QF_Test
3833 au!
3834 autocmd BufRead * silent cd %:p:h
3835 augroup END
3836
3837 10Xvimgrep /vim/ Xdir/**
3838 let l = g:Xgetlist()
3839 call assert_equal('f1.txt', bufname(l[0].bufnr))
3840 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
3841
3842 augroup QF_Test
3843 au!
3844 augroup END
3845
3846 exe 'cd ' . save_cwd
3847endfunc
3848
3849func Test_vimgrep_autocmd_cd()
3850 call mkdir('Xdir/a', 'p')
3851 call mkdir('Xdir/b', 'p')
3852 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
3853 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
3854 call Xvimgrep_autocmd_cd('c')
3855 call Xvimgrep_autocmd_cd('l')
3856 %bwipe
3857 call delete('Xdir', 'rf')
3858endfunc
3859
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003860" The following test used to crash Vim
3861func Test_lhelpgrep_autocmd()
3862 lhelpgrep quickfix
3863 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3864 lhelpgrep buffer
3865 call assert_equal('help', &filetype)
3866 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3867 lhelpgrep tabpage
3868 call assert_equal('help', &filetype)
3869 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3870 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003871
3872 new | only
3873 augroup QF_Test
3874 au!
3875 au BufEnter * call setqflist([], 'f')
3876 augroup END
3877 call assert_fails('helpgrep quickfix', 'E925:')
3878 augroup QF_Test
3879 au! BufEnter
3880 augroup END
3881
3882 new | only
3883 augroup QF_Test
3884 au!
3885 au BufEnter * call setqflist([], 'r')
3886 augroup END
3887 call assert_fails('helpgrep quickfix', 'E925:')
3888 augroup QF_Test
3889 au! BufEnter
3890 augroup END
3891
3892 new | only
3893 augroup QF_Test
3894 au!
3895 au BufEnter * call setloclist(0, [], 'r')
3896 augroup END
3897 call assert_fails('lhelpgrep quickfix', 'E926:')
3898 augroup QF_Test
3899 au! BufEnter
3900 augroup END
3901
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003902 new | only
3903endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02003904
3905" Test for shortening/simplifying the file name when opening the
3906" quickfix window or when displaying the quickfix list
3907func Test_shorten_fname()
3908 if !has('unix')
3909 return
3910 endif
3911 %bwipe
3912 " Create a quickfix list with a absolute path filename
3913 let fname = getcwd() . '/test_quickfix.vim'
3914 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3915 call assert_equal(fname, bufname('test_quickfix.vim'))
3916 " Opening the quickfix window should simplify the file path
3917 cwindow
3918 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3919 cclose
3920 %bwipe
3921 " Create a quickfix list with a absolute path filename
3922 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3923 call assert_equal(fname, bufname('test_quickfix.vim'))
3924 " Displaying the quickfix list should simplify the file path
3925 silent! clist
3926 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3927endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02003928
3929" Quickfix title tests
3930" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3931" Otherwise due to indentation, the title is set with spaces at the beginning
3932" of the command.
3933func Test_qftitle()
3934 call writefile(["F1:1:Line1"], 'Xerr')
3935
3936 " :cexpr
3937 exe "cexpr readfile('Xerr')"
3938 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3939
3940 " :cgetexpr
3941 exe "cgetexpr readfile('Xerr')"
3942 call assert_equal(":cgetexpr readfile('Xerr')",
3943 \ getqflist({'title' : 1}).title)
3944
3945 " :caddexpr
3946 call setqflist([], 'f')
3947 exe "caddexpr readfile('Xerr')"
3948 call assert_equal(":caddexpr readfile('Xerr')",
3949 \ getqflist({'title' : 1}).title)
3950
3951 " :cbuffer
3952 new Xerr
3953 exe "cbuffer"
3954 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3955
3956 " :cgetbuffer
3957 edit Xerr
3958 exe "cgetbuffer"
3959 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3960
3961 " :caddbuffer
3962 call setqflist([], 'f')
3963 edit Xerr
3964 exe "caddbuffer"
3965 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3966
3967 " :cfile
3968 exe "cfile Xerr"
3969 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
3970
3971 " :cgetfile
3972 exe "cgetfile Xerr"
3973 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
3974
3975 " :caddfile
3976 call setqflist([], 'f')
3977 exe "caddfile Xerr"
3978 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
3979
3980 " :grep
3981 set grepprg=internal
3982 exe "grep F1 Xerr"
3983 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
3984
3985 " :grepadd
3986 call setqflist([], 'f')
3987 exe "grepadd F1 Xerr"
3988 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
3989 set grepprg&vim
3990
3991 " :vimgrep
3992 exe "vimgrep F1 Xerr"
3993 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
3994
3995 " :vimgrepadd
3996 call setqflist([], 'f')
3997 exe "vimgrepadd F1 Xerr"
3998 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
3999
4000 call setqflist(['F1:10:L10'], ' ')
4001 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4002
4003 call setqflist([], 'f')
4004 call setqflist(['F1:10:L10'], 'a')
4005 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4006
4007 call setqflist([], 'f')
4008 call setqflist(['F1:10:L10'], 'r')
4009 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4010
4011 close
4012 call delete('Xerr')
4013
4014 call setqflist([], ' ', {'title' : 'Errors'})
4015 copen
4016 call assert_equal('Errors', w:quickfix_title)
4017 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4018 call assert_equal('Errors', w:quickfix_title)
4019 cclose
4020endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004021
4022func Test_lbuffer_with_bwipe()
4023 new
4024 new
4025 augroup nasty
4026 au * * bwipe
4027 augroup END
4028 lbuffer
4029 augroup nasty
4030 au!
4031 augroup END
4032endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004033
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004034" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4035" running
4036func Xexpr_acmd_freelist(cchar)
4037 call s:setup_commands(a:cchar)
4038
Bram Moolenaar0366c012018-06-18 20:52:13 +02004039 " This was using freed memory.
4040 augroup nasty
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004041 au * * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004042 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004043 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004044 augroup nasty
4045 au!
4046 augroup END
4047endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004048
4049func Test_cexpr_acmd_freelist()
4050 call Xexpr_acmd_freelist('c')
4051 call Xexpr_acmd_freelist('l')
4052endfunc
4053
4054" Test for commands that create a new quickfix/location list and jump to the
4055" first error automatically.
4056func Xjumpto_first_error_test(cchar)
4057 call s:setup_commands(a:cchar)
4058
4059 call s:create_test_file('Xtestfile1')
4060 call s:create_test_file('Xtestfile2')
4061 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4062
4063 " Test for cexpr/lexpr
4064 enew
4065 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004066 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004067 call assert_equal(2, line('.'))
4068
4069 " Test for cfile/lfile
4070 enew
4071 call writefile(l, 'Xerr')
4072 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004073 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004074 call assert_equal(2, line('.'))
4075
4076 " Test for cbuffer/lbuffer
4077 edit Xerr
4078 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004079 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004080 call assert_equal(2, line('.'))
4081
4082 call delete('Xerr')
4083 call delete('Xtestfile1')
4084 call delete('Xtestfile2')
4085endfunc
4086
4087func Test_jumpto_first_error()
4088 call Xjumpto_first_error_test('c')
4089 call Xjumpto_first_error_test('l')
4090endfunc
4091
4092" Test for a quickfix autocmd changing the quickfix/location list before
4093" jumping to the first error in the new list.
4094func Xautocmd_changelist(cchar)
4095 call s:setup_commands(a:cchar)
4096
4097 " Test for cfile/lfile
4098 call s:create_test_file('Xtestfile1')
4099 call s:create_test_file('Xtestfile2')
4100 Xexpr 'Xtestfile1:2:Line2'
4101 autocmd QuickFixCmdPost * Xolder
4102 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4103 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004104 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004105 call assert_equal(4, line('.'))
4106 autocmd! QuickFixCmdPost
4107
4108 " Test for cbuffer/lbuffer
4109 call g:Xsetlist([], 'f')
4110 Xexpr 'Xtestfile1:2:Line2'
4111 autocmd QuickFixCmdPost * Xolder
4112 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4113 edit Xerr
4114 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004115 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004116 call assert_equal(4, line('.'))
4117 autocmd! QuickFixCmdPost
4118
4119 " Test for cexpr/lexpr
4120 call g:Xsetlist([], 'f')
4121 Xexpr 'Xtestfile1:2:Line2'
4122 autocmd QuickFixCmdPost * Xolder
4123 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004124 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004125 call assert_equal(4, line('.'))
4126 autocmd! QuickFixCmdPost
4127
Bram Moolenaar851332e2018-07-03 19:16:00 +02004128 " The grepprg may not be set on non-Unix systems
4129 if has('unix')
4130 " Test for grep/lgrep
4131 call g:Xsetlist([], 'f')
4132 Xexpr 'Xtestfile1:2:Line2'
4133 autocmd QuickFixCmdPost * Xolder
4134 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004135 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004136 call assert_equal(5, line('.'))
4137 autocmd! QuickFixCmdPost
4138 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004139
4140 " Test for vimgrep/lvimgrep
4141 call g:Xsetlist([], 'f')
4142 Xexpr 'Xtestfile1:2:Line2'
4143 autocmd QuickFixCmdPost * Xolder
4144 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004145 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004146 call assert_equal(5, line('.'))
4147 autocmd! QuickFixCmdPost
4148
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004149 " Test for autocommands clearing the quickfix list before jumping to the
4150 " first error. This should not result in an error
4151 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4152 let v:errmsg = ''
4153 " Test for cfile/lfile
4154 Xfile Xerr
4155 call assert_true(v:errmsg !~# 'E42:')
4156 " Test for cbuffer/lbuffer
4157 edit Xerr
4158 Xbuffer
4159 call assert_true(v:errmsg !~# 'E42:')
4160 " Test for cexpr/lexpr
4161 Xexpr 'Xtestfile2:4:Line4'
4162 call assert_true(v:errmsg !~# 'E42:')
4163 " Test for grep/lgrep
4164 " The grepprg may not be set on non-Unix systems
4165 if has('unix')
4166 silent Xgrep Line5 Xtestfile2
4167 call assert_true(v:errmsg !~# 'E42:')
4168 endif
4169 " Test for vimgrep/lvimgrep
4170 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4171 autocmd! QuickFixCmdPost
4172
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004173 call delete('Xerr')
4174 call delete('Xtestfile1')
4175 call delete('Xtestfile2')
4176endfunc
4177
4178func Test_autocmd_changelist()
4179 call Xautocmd_changelist('c')
4180 call Xautocmd_changelist('l')
4181endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004182
4183" Tests for the ':filter /pat/ clist' command
4184func Test_filter_clist()
4185 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4186 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4187 \ split(execute('filter /Line 15/ clist'), "\n"))
4188 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4189 \ split(execute('filter /Xfile1/ clist'), "\n"))
4190 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4191
4192 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4193 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4194 call assert_equal([' 2 pqr:pat2: '],
4195 \ split(execute('filter /pqr/ clist'), "\n"))
4196 call assert_equal([' 1 abc:pat1: '],
4197 \ split(execute('filter /pat1/ clist'), "\n"))
4198endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004199
4200" Tests for the "CTRL-W <CR>" command.
4201func Xview_result_split_tests(cchar)
4202 call s:setup_commands(a:cchar)
4203
4204 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4205 call g:Xsetlist([])
4206 Xopen
4207 let l:win_count = winnr('$')
4208 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
4209 call assert_equal(l:win_count, winnr('$'))
4210 Xclose
4211endfunc
4212
4213func Test_view_result_split()
4214 call Xview_result_split_tests('c')
4215 call Xview_result_split_tests('l')
4216endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004217
4218" Test that :cc sets curswant
4219func Test_curswant()
4220 helpgrep quickfix
4221 normal! llll
4222 1cc
4223 call assert_equal(getcurpos()[4], virtcol('.'))
4224 cclose | helpclose
4225endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004226
4227" Test for opening a file from the quickfix window using CTRL-W <Enter>
4228" doesn't leave an empty buffer around.
4229func Test_splitview()
4230 call s:create_test_file('Xtestfile1')
4231 call s:create_test_file('Xtestfile2')
4232 new | only
4233 let last_bufnr = bufnr('Test_sv_1', 1)
4234 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4235 cgetexpr l
4236 copen
4237 let numbufs = len(getbufinfo())
4238 exe "normal \<C-W>\<CR>"
4239 copen
4240 exe "normal j\<C-W>\<CR>"
4241 " Make sure new empty buffers are not created
4242 call assert_equal(numbufs, len(getbufinfo()))
4243 " Creating a new buffer should use the next available buffer number
4244 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4245 bwipe Test_sv_1
4246 bwipe Test_sv_2
4247 new | only
4248
4249 " When split opening files from location list window, make sure that two
4250 " windows doesn't refer to the same location list
4251 lgetexpr l
4252 let locid = getloclist(0, {'id' : 0}).id
4253 lopen
4254 exe "normal \<C-W>\<CR>"
4255 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4256 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4257 new | only
4258
4259 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004260 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004261 lhelpgrep window
4262 let locid = getloclist(0, {'id' : 0}).id
4263 lwindow
4264 exe "normal j\<C-W>\<CR>"
4265 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4266 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4267 new | only
4268
Bram Moolenaar406cd902020-02-18 21:54:41 +01004269 " Using :split or :vsplit from a quickfix window should behave like a :new
4270 " or a :vnew command
4271 copen
4272 split
4273 call assert_equal(3, winnr('$'))
4274 let l = getwininfo()
4275 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4276 close
4277 copen
4278 vsplit
4279 let l = getwininfo()
4280 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4281 new | only
4282
Bram Moolenaarb2443732018-11-11 22:50:27 +01004283 call delete('Xtestfile1')
4284 call delete('Xtestfile2')
4285endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004286
4287" Test for parsing entries using visual screen column
4288func Test_viscol()
4289 enew
4290 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4291 edit Xfile1
4292
4293 " Use byte offset for column number
4294 set efm&
4295 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4296 call assert_equal([5, 8], [col('.'), virtcol('.')])
4297 cnext
4298 call assert_equal([9, 12], [col('.'), virtcol('.')])
4299 cnext
4300 call assert_equal([14, 20], [col('.'), virtcol('.')])
4301
4302 " Use screen column offset for column number
4303 set efm=%f:%l:%v:%m
4304 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4305 call assert_equal([5, 8], [col('.'), virtcol('.')])
4306 cnext
4307 call assert_equal([9, 12], [col('.'), virtcol('.')])
4308 cnext
4309 call assert_equal([14, 20], [col('.'), virtcol('.')])
4310 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4311 call assert_equal([5, 8], [col('.'), virtcol('.')])
4312 cnext
4313 call assert_equal([10, 16], [col('.'), virtcol('.')])
4314 cnext
4315 call assert_equal([14, 20], [col('.'), virtcol('.')])
4316
4317 enew
4318 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4319
4320 " Use byte offset for column number
4321 set efm&
4322 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4323 call assert_equal([8, 10], [col('.'), virtcol('.')])
4324 cnext
4325 call assert_equal([11, 17], [col('.'), virtcol('.')])
4326 cnext
4327 call assert_equal([16, 25], [col('.'), virtcol('.')])
4328
4329 " Use screen column offset for column number
4330 set efm=%f:%l:%v:%m
4331 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4332 call assert_equal([8, 10], [col('.'), virtcol('.')])
4333 cnext
4334 call assert_equal([11, 17], [col('.'), virtcol('.')])
4335 cnext
4336 call assert_equal([16, 25], [col('.'), virtcol('.')])
4337
4338 enew | only
4339 set efm&
4340 call delete('Xfile1')
4341endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004342
4343" Test for the quickfix window buffer
4344func Xqfbuf_test(cchar)
4345 call s:setup_commands(a:cchar)
4346
4347 " Quickfix buffer should be reused across closing and opening a quickfix
4348 " window
4349 Xexpr "F1:10:Line10"
4350 Xopen
4351 let qfbnum = bufnr('')
4352 Xclose
4353 " Even after the quickfix window is closed, the buffer should be loaded
4354 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004355 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004356 Xopen
4357 " Buffer should be reused when opening the window again
4358 call assert_equal(qfbnum, bufnr(''))
4359 Xclose
4360
4361 if a:cchar == 'l'
4362 %bwipe
4363 " For a location list, when both the file window and the location list
4364 " window for the list are closed, then the buffer should be freed.
4365 new | only
4366 lexpr "F1:10:Line10"
4367 let wid = win_getid()
4368 lopen
4369 let qfbnum = bufnr('')
4370 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4371 close
4372 " When the location list window is closed, the buffer name should not
4373 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004374 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004375 call assert_true(bufloaded(qfbnum))
4376
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004377 " After deleting a location list buffer using ":bdelete", opening the
4378 " location list window should mark the buffer as a location list buffer.
4379 exe "bdelete " . qfbnum
4380 lopen
4381 call assert_equal("quickfix", &buftype)
4382 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4383 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4384 call assert_false(&swapfile)
4385 lclose
4386
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004387 " When the location list is cleared for the window, the buffer should be
4388 " removed
4389 call setloclist(0, [], 'f')
4390 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004391 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004392
4393 " When the location list is freed with the location list window open, the
4394 " location list buffer should not be lost. It should be reused when the
4395 " location list is again populated.
4396 lexpr "F1:10:Line10"
4397 lopen
4398 let wid = win_getid()
4399 let qfbnum = bufnr('')
4400 wincmd p
4401 call setloclist(0, [], 'f')
4402 lexpr "F1:10:Line10"
4403 lopen
4404 call assert_equal(wid, win_getid())
4405 call assert_equal(qfbnum, bufnr(''))
4406 lclose
4407
4408 " When the window with the location list is closed, the buffer should be
4409 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004410 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004411 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004412 endif
4413endfunc
4414
4415func Test_qfbuf()
4416 call Xqfbuf_test('c')
4417 call Xqfbuf_test('l')
4418endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004419
4420" If there is an autocmd to use only one window, then opening the location
4421" list window used to crash Vim.
4422func Test_winonly_autocmd()
4423 call s:create_test_file('Xtest1')
4424 " Autocmd to show only one Vim window at a time
4425 autocmd WinEnter * only
4426 new
4427 " Load the location list
4428 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4429 let loclistid = getloclist(0, {'id' : 0}).id
4430 " Open the location list window. Only this window will be shown and the file
4431 " window is closed.
4432 lopen
4433 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4434 " Jump to an entry in the location list and make sure that the cursor is
4435 " positioned correctly.
4436 ll 3
4437 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004438 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004439 call assert_equal(15, line('.'))
4440 " Cleanup
4441 autocmd! WinEnter
4442 new | only
4443 call delete('Xtest1')
4444endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004445
4446" Test to make sure that an empty quickfix buffer is not reused for loading
4447" a normal buffer.
4448func Test_empty_qfbuf()
4449 enew | only
4450 call writefile(["Test"], 'Xfile1')
4451 call setqflist([], 'f')
4452 copen | only
4453 let qfbuf = bufnr('')
4454 edit Xfile1
4455 call assert_notequal(qfbuf, bufnr(''))
4456 enew
4457 call delete('Xfile1')
4458endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004459
4460" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004461" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004462func Xtest_below(cchar)
4463 call s:setup_commands(a:cchar)
4464
4465 " No quickfix/location list
4466 call assert_fails('Xbelow', 'E42:')
4467 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004468 call assert_fails('Xbefore', 'E42:')
4469 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004470
4471 " Empty quickfix/location list
4472 call g:Xsetlist([])
4473 call assert_fails('Xbelow', 'E42:')
4474 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004475 call assert_fails('Xbefore', 'E42:')
4476 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004477
4478 call s:create_test_file('X1')
4479 call s:create_test_file('X2')
4480 call s:create_test_file('X3')
4481 call s:create_test_file('X4')
4482
4483 " Invalid entries
4484 edit X1
4485 call g:Xsetlist(["E1", "E2"])
4486 call assert_fails('Xbelow', 'E42:')
4487 call assert_fails('Xabove', 'E42:')
4488 call assert_fails('3Xbelow', 'E42:')
4489 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004490 call assert_fails('Xbefore', 'E42:')
4491 call assert_fails('Xafter', 'E42:')
4492 call assert_fails('3Xbefore', 'E42:')
4493 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004494
4495 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004496 Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"]
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004497 edit +7 X2
4498 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004499 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004500 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004501 normal 7G
4502 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004503 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004504 call assert_fails('Xbefore', 'E553:')
4505
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004506 normal 2j
4507 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004508 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004509 normal 7G
4510 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004511 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004512
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004513 " Last error in this file
4514 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004515 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004516 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004517 normal gg
4518 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004519 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004520 call assert_fails('Xafter', 'E553:')
4521
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004522 " First error in this file
4523 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004524 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004525 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004526 normal G
4527 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004528 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004529 call assert_fails('Xbefore', 'E553:')
4530
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004531 normal gg
4532 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004533 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004534 normal gg
4535 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004536 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004537
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004538 normal G
4539 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004540 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004541 normal G
4542 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004543 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004544
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004545 edit X4
4546 call assert_fails('Xabove', 'E42:')
4547 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004548 call assert_fails('Xbefore', 'E42:')
4549 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004550 if a:cchar == 'l'
4551 " If a buffer has location list entries from some other window but not
4552 " from the current window, then the commands should fail.
4553 edit X1 | split | call setloclist(0, [], 'f')
4554 call assert_fails('Xabove', 'E776:')
4555 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004556 call assert_fails('Xbefore', 'E776:')
4557 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004558 close
4559 endif
4560
4561 " Test for lines with multiple quickfix entries
4562 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4563 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4564 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4565 edit +1 X2
4566 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004567 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004568 normal 1G
4569 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004570 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004571
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004572 normal gg
4573 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004574 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004575 normal gg
4576 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004577 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004578
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004579 normal G
4580 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004581 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004582 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004583 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004584 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004585
4586 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004587 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004588 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004589 normal G
4590 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004591 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004592
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004593 normal 10G
4594 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004595 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004596 normal 10G$
4597 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004598 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004599
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004600 normal 10G
4601 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004602 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004603 normal 9G
4604 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004605 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004606
4607 " Invalid range
4608 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004609 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004610 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004611 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004612 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004613 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004614 endif
4615
4616 call delete('X1')
4617 call delete('X2')
4618 call delete('X3')
4619 call delete('X4')
4620endfunc
4621
4622func Test_cbelow()
4623 call Xtest_below('c')
4624 call Xtest_below('l')
4625endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004626
4627func Test_quickfix_count()
4628 let commands = [
4629 \ 'cNext',
4630 \ 'cNfile',
4631 \ 'cabove',
4632 \ 'cbelow',
4633 \ 'cfirst',
4634 \ 'clast',
4635 \ 'cnewer',
4636 \ 'cnext',
4637 \ 'cnfile',
4638 \ 'colder',
4639 \ 'cprevious',
4640 \ 'crewind',
4641 \
4642 \ 'lNext',
4643 \ 'lNfile',
4644 \ 'labove',
4645 \ 'lbelow',
4646 \ 'lfirst',
4647 \ 'llast',
4648 \ 'lnewer',
4649 \ 'lnext',
4650 \ 'lnfile',
4651 \ 'lolder',
4652 \ 'lprevious',
4653 \ 'lrewind',
4654 \ ]
4655 for cmd in commands
4656 call assert_fails('-1' .. cmd, 'E16:')
4657 call assert_fails('.' .. cmd, 'E16:')
4658 call assert_fails('%' .. cmd, 'E16:')
4659 call assert_fails('$' .. cmd, 'E16:')
4660 endfor
4661endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004662
4663" Test for aborting quickfix commands using QuickFixCmdPre
4664func Xtest_qfcmd_abort(cchar)
4665 call s:setup_commands(a:cchar)
4666
4667 call g:Xsetlist([], 'f')
4668
4669 " cexpr/lexpr
4670 let e = ''
4671 try
4672 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4673 catch /.*/
4674 let e = v:exception
4675 endtry
4676 call assert_equal('AbortCmd', e)
4677 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4678
4679 " cfile/lfile
4680 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4681 let e = ''
4682 try
4683 Xfile Xfile1
4684 catch /.*/
4685 let e = v:exception
4686 endtry
4687 call assert_equal('AbortCmd', e)
4688 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4689 call delete('Xfile1')
4690
4691 " cgetbuffer/lgetbuffer
4692 enew!
4693 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4694 let e = ''
4695 try
4696 Xgetbuffer
4697 catch /.*/
4698 let e = v:exception
4699 endtry
4700 call assert_equal('AbortCmd', e)
4701 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4702 enew!
4703
4704 " vimgrep/lvimgrep
4705 let e = ''
4706 try
4707 Xvimgrep /func/ test_quickfix.vim
4708 catch /.*/
4709 let e = v:exception
4710 endtry
4711 call assert_equal('AbortCmd', e)
4712 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4713
4714 " helpgrep/lhelpgrep
4715 let e = ''
4716 try
4717 Xhelpgrep quickfix
4718 catch /.*/
4719 let e = v:exception
4720 endtry
4721 call assert_equal('AbortCmd', e)
4722 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4723
4724 " grep/lgrep
4725 if has('unix')
4726 let e = ''
4727 try
4728 silent Xgrep func test_quickfix.vim
4729 catch /.*/
4730 let e = v:exception
4731 endtry
4732 call assert_equal('AbortCmd', e)
4733 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4734 endif
4735endfunc
4736
4737func Test_qfcmd_abort()
4738 augroup QF_Test
4739 au!
4740 autocmd QuickFixCmdPre * throw "AbortCmd"
4741 augroup END
4742
4743 call Xtest_qfcmd_abort('c')
4744 call Xtest_qfcmd_abort('l')
4745
4746 augroup QF_Test
4747 au!
4748 augroup END
4749endfunc
4750
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004751" Test for using a file in one of the parent directories.
4752func Test_search_in_dirstack()
4753 call mkdir('Xtestdir/a/b/c', 'p')
4754 let save_cwd = getcwd()
4755 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4756 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4757 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4758 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4759
4760 let lines = "Entering dir Xtestdir\n" .
4761 \ "Entering dir a\n" .
4762 \ "Entering dir b\n" .
4763 \ "Xfile2:2:X2_L2\n" .
4764 \ "Leaving dir a\n" .
4765 \ "Xfile1:2:X1_L2\n" .
4766 \ "Xfile3:1:X3_L1\n" .
4767 \ "Entering dir c\n" .
4768 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004769 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004770 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004771 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004772 call assert_equal(11, getqflist({'size' : 0}).size)
4773 call assert_equal(4, getqflist({'idx' : 0}).idx)
4774 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004775 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004776 cnext
4777 call assert_equal(6, getqflist({'idx' : 0}).idx)
4778 call assert_equal('X1_L2', getline('.'))
4779 cnext
4780 call assert_equal(7, getqflist({'idx' : 0}).idx)
4781 call assert_equal(1, line('$'))
4782 call assert_equal('', getline(1))
4783 cnext
4784 call assert_equal(9, getqflist({'idx' : 0}).idx)
4785 call assert_equal(1, line('$'))
4786 call assert_equal('', getline(1))
4787
4788 set efm&
4789 exe 'cd ' . save_cwd
4790 call delete('Xtestdir', 'rf')
4791endfunc
4792
Bram Moolenaar1860bde2020-01-06 21:47:21 +01004793" Test for :cquit
4794func Test_cquit()
4795 " Exit Vim with a non-zero value
4796 if RunVim([], ["cquit 7"], '')
4797 call assert_equal(7, v:shell_error)
4798 endif
4799
4800 if RunVim([], ["50cquit"], '')
4801 call assert_equal(50, v:shell_error)
4802 endif
4803
4804 " Exit Vim with default value
4805 if RunVim([], ["cquit"], '')
4806 call assert_equal(1, v:shell_error)
4807 endif
4808
4809 " Exit Vim with zero value
4810 if RunVim([], ["cquit 0"], '')
4811 call assert_equal(0, v:shell_error)
4812 endif
4813
4814 " Exit Vim with negative value
4815 call assert_fails('-3cquit', 'E16:')
4816endfunc
4817
Bram Moolenaar858ba062020-05-31 23:11:59 +02004818" Test for getting a specific item from a quickfix list
4819func Xtest_getqflist_by_idx(cchar)
4820 call s:setup_commands(a:cchar)
4821 " Empty list
4822 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
4823 Xexpr ['F1:10:L10', 'F1:20:L20']
4824 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
4825 call assert_equal(bufnr('F1'), l[0].bufnr)
4826 call assert_equal(20, l[0].lnum)
4827 call assert_equal('L20', l[0].text)
4828 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
4829 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
4830 %bwipe!
4831endfunc
4832
4833func Test_getqflist_by_idx()
4834 call Xtest_getqflist_by_idx('c')
4835 call Xtest_getqflist_by_idx('l')
4836endfunc
4837
4838" Test for the 'quickfixtextfunc' setting
4839func Tqfexpr(info)
4840 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004841 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004842 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004843 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004844 endif
4845
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004846 let l = []
4847 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4848 let e = qfl[idx]
4849 let s = ''
4850 if e.bufnr != 0
4851 let bname = bufname(e.bufnr)
4852 let s ..= fnamemodify(bname, ':.')
4853 endif
4854 let s ..= '-'
4855 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
4856 let s ..= e.text
4857 call add(l, s)
4858 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02004859
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004860 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004861endfunc
4862
4863func Xtest_qftextfunc(cchar)
4864 call s:setup_commands(a:cchar)
4865
4866 set efm=%f:%l:%c:%m
4867 set quickfixtextfunc=Tqfexpr
4868 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4869 Xwindow
4870 call assert_equal('F1-L10C2-green', getline(1))
4871 call assert_equal('F1-L20C4-blue', getline(2))
4872 Xclose
4873 set quickfixtextfunc&vim
4874 Xwindow
4875 call assert_equal('F1|10 col 2| green', getline(1))
4876 call assert_equal('F1|20 col 4| blue', getline(2))
4877 Xclose
4878 set efm&
4879 set quickfixtextfunc&
4880
4881 " Test for per list 'quickfixtextfunc' setting
4882 func PerQfText(info)
4883 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004884 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004885 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004886 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004887 endif
4888 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004889 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02004890 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004891 let l = []
4892 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4893 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
4894 endfor
4895 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004896 endfunc
4897 set quickfixtextfunc=Tqfexpr
4898 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
4899 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
4900 Xwindow
4901 call assert_equal('Line 10, Col 2', getline(1))
4902 call assert_equal('Line 20, Col 4', getline(2))
4903 Xclose
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02004904 " Add entries to the list when the quickfix buffer is hidden
4905 Xaddexpr ['F1:30:6:red']
4906 Xwindow
4907 call assert_equal('Line 30, Col 6', getline(3))
4908 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02004909 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
4910 set quickfixtextfunc&
4911 delfunc PerQfText
4912
4913 " Non-existing function
4914 set quickfixtextfunc=Tabc
4915 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4916 call assert_fails("Xwindow", 'E117:')
4917 Xclose
4918 set quickfixtextfunc&
4919
4920 " set option to a non-function
4921 set quickfixtextfunc=[10,\ 20]
4922 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4923 call assert_fails("Xwindow", 'E117:')
4924 Xclose
4925 set quickfixtextfunc&
4926
4927 " set option to a function with different set of arguments
4928 func Xqftext(a, b, c)
4929 return a:a .. a:b .. a:c
4930 endfunc
4931 set quickfixtextfunc=Xqftext
4932 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
4933 call assert_fails("Xwindow", 'E119:')
4934 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004935
4936 " set option to a function that returns a list with non-strings
4937 func Xqftext2(d)
4938 return ['one', [], 'two']
4939 endfunc
4940 set quickfixtextfunc=Xqftext2
4941 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
4942 \ 'E730:')
4943 call assert_fails('Xwindow', 'E730:')
4944 call assert_equal(['one', 'F1|20 col 4| blue', 'two'], getline(1, '$'))
4945 Xclose
4946
Bram Moolenaar858ba062020-05-31 23:11:59 +02004947 set quickfixtextfunc&
4948 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004949 delfunc Xqftext2
Bram Moolenaar858ba062020-05-31 23:11:59 +02004950endfunc
4951
4952func Test_qftextfunc()
4953 call Xtest_qftextfunc('c')
4954 call Xtest_qftextfunc('l')
4955endfunc
4956
Bram Moolenaarec98e932020-06-08 19:35:59 +02004957" Running :lhelpgrep command more than once in a help window, doesn't jump to
4958" the help topic
4959func Test_lhelpgrep_from_help_window()
4960 call mkdir('Xtestdir/doc', 'p')
4961 call writefile(['window'], 'Xtestdir/doc/a.txt')
4962 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
4963 let save_rtp = &rtp
4964 let &rtp = 'Xtestdir'
4965 lhelpgrep window
4966 lhelpgrep buffer
4967 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
4968 lhelpgrep window
4969 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
4970 let &rtp = save_rtp
4971 call delete('Xtestdir', 'rf')
4972 new | only!
4973endfunc
4974
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004975" vim: shiftwidth=2 sts=2 expandtab