blob: bc180fc04ce8146dfdd1c6a733750963e275bef9 [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
Bram Moolenaar62aec932022-01-29 21:45:34 +00004import './vim9.vim' as v9
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020046 let g:Xgetlist = function('getqflist')
47 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020048 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020049 else
50 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
51 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020052 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020053 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020054 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010055 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020057 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xclose <mods>lclose <args>
59 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
60 command! -nargs=* Xgetfile <mods>lgetfile <args>
61 command! -nargs=* Xaddfile <mods>laddfile <args>
62 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
63 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
64 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
65 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020066 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
67 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020068 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
69 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020070 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020071 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020072 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020073 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010074 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020075 command! -nargs=* Xgrep <mods> lgrep <args>
76 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
77 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010078 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020079 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
80 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020081 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
82 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020083 let g:Xgetlist = function('getloclist', [0])
84 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020085 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020086 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010087endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088
Bram Moolenaara5d78d12021-12-15 12:28:22 +000089" This must be run before any error lists are created.
90func Test_AA_cc_no_errors()
91 call assert_fails('cc', 'E42:')
92 call assert_fails('ll', 'E42:')
93endfunc
94
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010096func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020097 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020099 if a:cchar == 'l'
100 call assert_fails('llist', 'E776:')
101 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200103 Xgetexpr []
104 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100105 call assert_true(v:errmsg ==# 'E42: No Errors')
106
107 " Populate the list and then try
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100108 let lines =<< trim END
109 non-error 1
110 Xtestfile1:1:3:Line1
111 non-error 2
112 Xtestfile2:2:2:Line2
113 non-error| 3
114 Xtestfile3:3:1:Line3
115 END
116 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100117
118 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100119 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100120 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
121 \ ' 4 Xtestfile2:2 col 2: Line2',
122 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
123
124 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
127 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100128 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100129
130 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100131 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100132 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
133 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
134
Bram Moolenaaree85df32017-03-19 14:19:50 +0100135 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100136 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
137
Bram Moolenaaree85df32017-03-19 14:19:50 +0100138 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100139 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
140
Bram Moolenaaree85df32017-03-19 14:19:50 +0100141 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100142 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
143 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100144
145 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100146 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100147 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
148 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100149
thinca6864efa2021-06-19 20:45:20 +0200150 " Ranged entries
151 call g:Xsetlist([{'lnum':10,'text':'Line1'},
152 \ {'lnum':20,'col':10,'text':'Line2'},
153 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
154 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
155 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
156 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
157 let l = split(execute('Xlist', ""), "\n")
158 call assert_equal([' 1:10: Line1',
159 \ ' 2:20 col 10: Line2',
160 \ ' 3:30 col 15-20: Line3',
161 \ ' 4:40-45: Line4',
162 \ ' 5:50-55 col 15: Line5',
163 \ ' 6:60-65 col 25-35: Line6'], l)
164
Bram Moolenaaree85df32017-03-19 14:19:50 +0100165 " Different types of errors
166 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
167 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
168 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
169 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
170 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
171 let l = split(execute('Xlist', ""), "\n")
172 call assert_equal([' 1:10 col 5 warning 11: Warning',
173 \ ' 2:20 col 10 error 22: Error',
174 \ ' 3:30 col 15 info 33: Info',
175 \ ' 4:40 col 20 x 44: Other',
176 \ ' 5:50 col 25 55: one'], l)
177
Bram Moolenaard76ce852018-05-01 15:02:04 +0200178 " Test for module names, one needs to explicitly set `'valid':v:true` so
179 call g:Xsetlist([
180 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
181 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
182 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
183 let l = split(execute('Xlist', ""), "\n")
184 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
185 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
186 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
187
Bram Moolenaar5f30e262022-07-28 11:56:01 +0100188 " Very long line should be displayed.
189 let text = 'Line' .. repeat('1234567890', 130)
190 let lines = ['Xtestfile9:2:9:' .. text]
191 Xgetexpr lines
192
193 let l = split(execute('Xlist', ''), "\n")
194 call assert_equal([' 1 Xtestfile9:2 col 9: ' .. text] , l)
195
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100196 " For help entries in the quickfix list, only the filename without directory
197 " should be displayed
198 Xhelpgrep setqflist()
199 let l = split(execute('Xlist 1', ''), "\n")
200 call assert_match('^ 1 [^\\/]\{-}:', l[0])
201
Bram Moolenaaree85df32017-03-19 14:19:50 +0100202 " Error cases
203 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100204endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100205
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100206func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100207 call XlistTests('c')
208 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100209endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100210
211" Tests for the :colder, :cnewer, :lolder and :lnewer commands
212" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100213" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100214func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200215 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100216
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200217 if a:cchar == 'l'
218 " No location list for the current window
219 call assert_fails('lolder', 'E776:')
220 call assert_fails('lnewer', 'E776:')
221 endif
222
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200223 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200224 call g:Xsetlist(list)
225
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100226 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200227 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100228 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
229
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100231 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
232
233 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200234 Xgetexpr ['Xtestfile1:1:3:Line1']
235 Xgetexpr ['Xtestfile2:2:2:Line2']
236 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237
238 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200239 Xolder
240 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100241 call assert_equal('Line2', l[0].text)
242
243 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200244 Xnewer
245 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100246 call assert_equal('Line3', l[0].text)
247
248 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200249 Xolder 2
250 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100251 call assert_equal('Line1', l[0].text)
252
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200253 Xnewer 2
254 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100255 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100256endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100257
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100258func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100259 call XageTests('c')
260 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100261endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100262
263" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
264" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100265func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200266 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100267
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200268 " Opening the location list window without any errors should fail
269 if a:cchar == 'l'
270 call assert_fails('lopen', 'E776:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000271 call assert_fails('lwindow', 'E776:')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200272 endif
273
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100274 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200275 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Quickfix/Location window should not open 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)
280
281 " Create a list with valid entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100282 let lines =<< trim END
283 Xtestfile1:1:3:Line1
284 Xtestfile2:2:2:Line2
285 Xtestfile3:3:1:Line3
286 END
287 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100288
289 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200290 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100291 call assert_true(winnr('$') == 2 && winnr() == 2 &&
292 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200293 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100294
295 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200296 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100297 call assert_true(winnr('$') == 1)
298
299 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200300 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100301
302 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200303 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100304 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200305 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100306
307 " Opening the window again, should move the cursor to that window
308 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200309 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100310 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200311 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100312 \ getline('.') ==# '|| non-error 1')
313
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100314 " :cnext in quickfix window should move to the next entry
315 Xnext
316 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100317
318 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200319 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100320 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200321
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100322 " Specifying the width should adjust the width for a vertically split
323 " quickfix window.
324 vert Xopen
325 call assert_equal(10, winwidth(0))
326 vert Xopen 12
327 call assert_equal(12, winwidth(0))
328 Xclose
329
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200330 " Horizontally or vertically splitting the quickfix window should create a
331 " normal window/buffer
332 Xopen
333 wincmd s
334 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
335 call assert_equal(0, getwininfo(win_getid())[0].loclist)
336 call assert_notequal('quickfix', &buftype)
337 close
338 Xopen
339 wincmd v
340 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
341 call assert_equal(0, getwininfo(win_getid())[0].loclist)
342 call assert_notequal('quickfix', &buftype)
343 close
344 Xopen
345 Xclose
346
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200347 if a:cchar == 'c'
348 " Opening the quickfix window in multiple tab pages should reuse the
349 " quickfix buffer
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100350 let lines =<< trim END
351 Xtestfile1:1:3:Line1
352 Xtestfile2:2:2:Line2
353 Xtestfile3:3:1:Line3
354 END
355 Xgetexpr lines
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200356 Xopen
357 let qfbufnum = bufnr('%')
358 tabnew
359 Xopen
360 call assert_equal(qfbufnum, bufnr('%'))
361 new | only | tabonly
362 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100363endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100364
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100365func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100366 call XwindowTests('c')
367 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100368endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100369
Bram Moolenaar36d50222019-05-02 20:17:40 +0200370func Test_copenHeight()
371 copen
372 wincmd H
373 let height = winheight(0)
374 copen 10
375 call assert_equal(height, winheight(0))
376 quit
377endfunc
378
Bram Moolenaar1142a312019-10-16 14:51:39 +0200379func Test_copenHeight_tabline()
380 set tabline=foo showtabline=2
381 copen
382 wincmd H
383 let height = winheight(0)
384 copen 10
385 call assert_equal(height, winheight(0))
386 quit
387 set tabline& showtabline&
388endfunc
389
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100390" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
391" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100392func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200393 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100394
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100395 let lines =<< trim END
396 Xtestfile1:700:10:Line 700
397 Xtestfile2:800:15:Line 800
398 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100399 call writefile(lines, 'Xqftestfile1', 'D')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100400
401 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200402 Xfile Xqftestfile1
403 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100404 call assert_true(len(l) == 2 &&
405 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
406 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
407
Bram Moolenaar049cba92016-06-26 14:38:04 +0200408 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200409 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200410
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411 " Run cfile/lfile from a modified buffer
412 enew!
413 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200414 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100415 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
416
417 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200418 Xaddfile Xqftestfile1
419 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420 call assert_true(len(l) == 3 &&
421 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
422
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100423 let lines =<< trim END
424 Xtestfile1:222:77:Line 222
425 Xtestfile2:333:88:Line 333
426 END
427 call writefile(lines, 'Xqftestfile1')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100428
429 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200430 Xgetfile Xqftestfile1
431 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100432 call assert_true(len(l) == 2 &&
433 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
434 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
435
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100436 " Test for a file with a long line and without a newline at the end
437 let text = repeat('x', 1024)
438 let t = 'a.txt:18:' . text
439 call writefile([t], 'Xqftestfile1', 'b')
440 silent! Xfile Xqftestfile1
441 call assert_equal(text, g:Xgetlist()[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100442endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100443
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100444func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100445 call XfileTests('c')
446 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100447endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100448
449" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
450" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100451func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200452 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100453
454 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100455 let lines =<< trim END
456 Xtestfile7:700:10:Line 700
457 Xtestfile8:800:15:Line 800
458 END
459 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200460 Xbuffer!
461 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100462 call assert_true(len(l) == 2 &&
463 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
464 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
465
466 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100467 let lines =<< trim END
468 Xtestfile9:900:55:Line 900
469 Xtestfile10:950:66:Line 950
470 END
471 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200472 Xgetbuffer
473 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100474 call assert_true(len(l) == 2 &&
475 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
476 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
477
478 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100479 let lines =<< trim END
480 Xtestfile11:700:20:Line 700
481 Xtestfile12:750:25:Line 750
482 END
483 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200484 Xaddbuffer
485 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100486 call assert_true(len(l) == 4 &&
487 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
488 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
489 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200490 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100491
Bram Moolenaaree85df32017-03-19 14:19:50 +0100492 " Check for invalid buffer
493 call assert_fails('Xbuffer 199', 'E474:')
494
495 " Check for unloaded buffer
496 edit Xtestfile1
497 let bnr = bufnr('%')
498 enew!
499 call assert_fails('Xbuffer ' . bnr, 'E681:')
500
501 " Check for invalid range
502 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
503 " commands. So directly call the commands.
504 if (a:cchar == 'c')
505 call assert_fails('900,999cbuffer', 'E16:')
506 else
507 call assert_fails('900,999lbuffer', 'E16:')
508 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100509endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100510
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100511func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100512 call XbufferTests('c')
513 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100514endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100515
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100516func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200517 call s:setup_commands(a:cchar)
518
519 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100520endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200521
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100522func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200523 call XexprTests('c')
524 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100525endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200526
527" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100528func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200529 call s:setup_commands(a:cchar)
530
Bram Moolenaar74240d32017-12-10 15:26:15 +0100531 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200532 " Jumping to first or next location list entry without any error should
533 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100534 if a:cchar == 'c'
535 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100536 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100537 else
538 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100539 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200540 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100541 call assert_fails('Xnext', err)
542 call assert_fails('Xprev', err)
543 call assert_fails('Xnfile', err)
544 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100545 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200546
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100547 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100548 call assert_fails(cmd, 'E42:')
549
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200550 call s:create_test_file('Xqftestfile1')
551 call s:create_test_file('Xqftestfile2')
552
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100553 let lines =<< trim END
554 Xqftestfile1:5:Line5
555 Xqftestfile1:6:Line6
556 Xqftestfile2:10:Line10
557 Xqftestfile2:11:Line11
558 RegularLine1
559 RegularLine2
560 END
561 Xgetexpr lines
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200562
563 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100564 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200565 call assert_fails('Xprev', 'E553:')
566 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200567 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200568 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200569 call assert_equal(10, line('.'))
570 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200571 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200572 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100573 5Xcc
574 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
575 2Xcc
576 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100577 if a:cchar == 'c'
578 cc
579 else
580 ll
581 endif
582 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100583 10Xcc
584 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200585 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200586 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200587 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200588 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200589 call assert_fails('Xnext', 'E553:')
590 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100591 " To process the range using quickfix list entries, directly use the
592 " quickfix commands (don't use the user defined commands)
593 if a:cchar == 'c'
594 $cc
595 else
596 $ll
597 endif
598 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200599 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200600 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200601 call assert_equal(5, line('.'))
602
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200603 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200604 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200605 call assert_equal(11, line('.'))
606 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200607 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200608 call assert_equal(5, line('.'))
609
Bram Moolenaar74240d32017-12-10 15:26:15 +0100610 " Jumping to an error from the error window using cc command
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100611 let lines =<< trim END
612 Xqftestfile1:5:Line5
613 Xqftestfile1:6:Line6
614 Xqftestfile2:10:Line10
615 Xqftestfile2:11:Line11
616 END
617 Xgetexpr lines
Bram Moolenaar74240d32017-12-10 15:26:15 +0100618 Xopen
619 10Xcc
620 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200621 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100622 Xopen
623 call cursor(2, 1)
624 if a:cchar == 'c'
625 .cc
626 else
627 .ll
628 endif
629 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200630 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100631
632 " Jumping to an error from the error window (when only the error window is
633 " present)
634 Xopen | only
635 Xlast 1
636 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200637 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100638
Bram Moolenaaree85df32017-03-19 14:19:50 +0100639 Xexpr ""
640 call assert_fails('Xnext', 'E42:')
641
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200642 call delete('Xqftestfile1')
643 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200644
645 " Should be able to use next/prev with invalid entries
646 Xexpr ""
647 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
648 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100649 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200650 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
651 Xlast
652 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
653 Xfirst
654 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
655 2Xnext
656 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100657endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200658
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100659func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200660 call Xtest_browse('c')
661 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100662endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200663
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000664" Test for memory allocation failures
665func Xnomem_tests(cchar)
666 call s:setup_commands(a:cchar)
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100667
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000668 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
669 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
670
671 call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
672 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100673
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200674 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000675 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100676
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200677 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000678 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100679
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200680 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000681 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100682
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000683 call test_alloc_fail(GetAllocId('qf_efm_fmtstr'), 0, 0)
684 set efm=%f
685 call assert_fails('Xexpr ["Xfile1"]', 'E342:')
686 set efm&
687
688 call test_alloc_fail(GetAllocId('qf_efm_fmtpart'), 0, 0)
689 set efm=%f:%l:%m,%f-%l-%m
690 call assert_fails('Xaddexpr ["Xfile2", "Xfile3"]', 'E342:')
691 set efm&
692
693 call test_alloc_fail(GetAllocId('qf_title'), 0, 0)
694 call assert_fails('Xexpr ""', 'E342:')
695 call assert_equal('', g:Xgetlist({'all': 1}).title)
696
697 call test_alloc_fail(GetAllocId('qf_mef_name'), 0, 0)
698 set makeef=Xtmp##.err
699 call assert_fails('Xgrep needle haystack', 'E342:')
700 set makeef&
701
702 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
703 call assert_fails('Xexpr "Xfile1:10:Line10"', 'E342:')
704
705 if a:cchar == 'l'
706 for id in ['qf_qfline', 'qf_qfinfo']
707 lgetexpr ["Xfile1:10:L10", "Xfile2:20:L20"]
708 call test_alloc_fail(GetAllocId(id), 0, 0)
709 call assert_fails('new', 'E342:')
710 call assert_equal(2, winnr('$'))
711 call assert_equal([], getloclist(0))
712 %bw!
713 endfor
714 endif
715
716 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
717 try
718 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
719 catch /^Vim:Interrupt$/
720 endtry
721
722 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
723 try
724 call assert_fails('Xvimgrep /vim/f runtest.vim', 'E342:')
725 catch /^Vim:Interrupt$/
726 endtry
727
728 let l = getqflist({"lines": ["Xfile1:10:L10"]})
729 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
730 call assert_fails('call g:Xsetlist(l.items)', 'E342:')
731
732 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
733 try
734 call assert_fails('Xhelpgrep quickfix', 'E342:')
735 catch /^Vim:Interrupt$/
736 endtry
737
738 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
739 call assert_fails('let l = g:Xgetlist({"lines": ["Xfile1:10:L10"]})', 'E342:')
740 call assert_equal(#{items: []}, l)
741
742 if a:cchar == 'l'
743 call setqflist([], 'f')
744 call setloclist(0, [], 'f')
745 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
746 call assert_fails('lhelpgrep quickfix', 'E342:')
747 call assert_equal([], getloclist(0))
748
749 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
750 call assert_fails('lvimgrep vim runtest.vim', 'E342:')
751
752 let l = getqflist({"lines": ["Xfile1:10:L10"]})
753 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
754 call assert_fails('call setloclist(0, l.items)', 'E342:')
755
756 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
757 call assert_fails('lbuffer', 'E342:')
758
759 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
760 call assert_fails('lexpr ["Xfile1:10:L10", "Xfile2:20:L20"]', 'E342:')
761
762 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
763 call assert_fails('lfile runtest.vim', 'E342:')
764 endif
765
766 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
767 set efm=%DEntering\ dir\ %f,%f:%l:%m
768 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E342:')
769 set efm&
770
771 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
772 set efm=%+P[%f],(%l)%m
773 call assert_fails('Xexpr ["[runtest.vim]", "(1)Hello"]', 'E342:')
774 set efm&
775
776 call test_alloc_fail(GetAllocId('qf_multiline_pfx'), 0, 0)
777 set efm=%EError,%Cline\ %l,%Z%m
778 call assert_fails('Xexpr ["Error", "line 1", "msg"]', 'E342:')
779 set efm&
780
781 call test_alloc_fail(GetAllocId('qf_makecmd'), 0, 0)
782 call assert_fails('Xgrep vim runtest.vim', 'E342:')
783
784 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
785 call assert_fails('Xexpr repeat("a", 8192)', 'E342:')
786
787 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
788 call assert_fails('Xexpr [repeat("a", 8192)]', 'E342:')
789
790 new
791 call setline(1, repeat('a', 8192))
792 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
793 call assert_fails('Xbuffer', 'E342:')
794 %bw!
795
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100796 call writefile([repeat('a', 8192)], 'Xtest', 'D')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000797 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
798 call assert_fails('Xfile Xtest', 'E342:')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000799endfunc
800
801func Test_nomem()
802 call Xnomem_tests('c')
803 call Xnomem_tests('l')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100804endfunc
805
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100806func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200807 call s:setup_commands(a:cchar)
808 Xhelpgrep quickfix
809 Xopen
810 if a:cchar == 'c'
811 let title_text = ':helpgrep quickfix'
812 else
813 let title_text = ':lhelpgrep quickfix'
814 endif
815 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200816
817 " Jumping to a help topic should open the help window
818 only
819 Xnext
820 call assert_true(&buftype == 'help')
821 call assert_true(winnr('$') == 2)
822 " Jumping to the next match should reuse the help window
823 Xnext
824 call assert_true(&buftype == 'help')
825 call assert_true(winnr() == 1)
826 call assert_true(winnr('$') == 2)
827 " Jumping to the next match from the quickfix window should reuse the help
828 " window
829 Xopen
830 Xnext
831 call assert_true(&buftype == 'help')
832 call assert_true(winnr() == 1)
833 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200834 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200835
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100836 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200837 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100838
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100839 " When the current window is vertically split, jumping to a help match
840 " should open the help window at the top.
841 only | enew
842 let w1 = win_getid()
843 vert new
844 let w2 = win_getid()
845 Xnext
846 let w3 = win_getid()
847 call assert_true(&buftype == 'help')
848 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100849 " See jump_to_help_window() for details
850 let w2_width = winwidth(w2)
851 if w2_width != &columns && w2_width < 80
852 call assert_equal(['col', [['leaf', w3],
853 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
854 else
855 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
856 \ ['leaf', w1]]] , winlayout())
857 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100858
859 new | only
860 set buftype=help
861 set modified
862 call assert_fails('Xnext', 'E37:')
863 set nomodified
864 new | only
865
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200866 if a:cchar == 'l'
867 " When a help window is present, running :lhelpgrep should reuse the
868 " help window and not the current window
869 new | only
870 call g:Xsetlist([], 'f')
871 help index.txt
872 wincmd w
873 lhelpgrep quickfix
874 call assert_equal(1, winnr())
875 call assert_notequal([], getloclist(1))
876 call assert_equal([], getloclist(2))
877 endif
878
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200879 new | only
880
Bram Moolenaaree85df32017-03-19 14:19:50 +0100881 " Search for non existing help string
882 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200883 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200884 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100885endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200886
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100887func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200888 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200889 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200890 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100891endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100892
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100893def Test_helpgrep_vim9_restore_cpo()
894 assert_equal('aABceFs', &cpo)
895
896 var rtp_save = &rtp
897 var dir = 'Xruntime/after'
898 &rtp ..= ',' .. dir
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100899 mkdir(dir .. '/ftplugin', 'pR')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100900 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100901 filetype plugin on
902 silent helpgrep grail
903 cwindow
904 silent helpgrep grail
905
906 assert_equal('aABceFs', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100907 &rtp = rtp_save
908 cclose
909 helpclose
910enddef
911
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000912" When running the :helpgrep command, if an autocmd modifies the 'cpoptions'
913" value, then Vim crashes. (issue fixed by 7.2b-004 and 8.2.4453)
Bram Moolenaar4791fcd2022-02-23 12:06:00 +0000914func Test_helpgrep_restore_cpo_aucmd()
915 let save_cpo = &cpo
916 augroup QF_Test
917 au!
918 autocmd BufNew * set cpo=acd
919 augroup END
920
921 helpgrep quickfix
922 call assert_equal('acd', &cpo)
923 %bw!
924
925 set cpo&vim
926 augroup QF_Test
927 au!
928 autocmd BufReadPost * set cpo=
929 augroup END
930
931 helpgrep buffer
932 call assert_equal('', &cpo)
933
934 augroup QF_Test
935 au!
936 augroup END
937 %bw!
938 let &cpo = save_cpo
939endfunc
940
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200941def Test_vim9_cexpr()
942 var text = 'somefile:95:error'
943 cexpr text
944 var l = getqflist()
945 assert_equal(1, l->len())
946 assert_equal(95, l[0].lnum)
947 assert_equal('error', l[0].text)
948
949 text = 'somefile:77:warning'
950 caddexpr text
951 l = getqflist()
952 assert_equal(2, l->len())
953 assert_equal(77, l[1].lnum)
954 assert_equal('warning', l[1].text)
955enddef
956
Bram Moolenaar6920c722016-01-22 22:44:10 +0100957func Test_errortitle()
958 augroup QfBufWinEnter
959 au!
960 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
961 augroup END
962 copen
963 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'')'}]
964 call setqflist(a)
965 call assert_equal(':setqflist()', g:a)
966 augroup QfBufWinEnter
967 au!
968 augroup END
969 augroup! QfBufWinEnter
970endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100971
Bram Moolenaar5584df62016-03-18 21:00:51 +0100972func Test_vimgreptitle()
973 augroup QfBufWinEnter
974 au!
975 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
976 augroup END
977 try
978 vimgrep /pattern/j file
979 catch /E480/
980 endtry
981 copen
982 call assert_equal(': vimgrep /pattern/j file', g:a)
983 augroup QfBufWinEnter
984 au!
985 augroup END
986 augroup! QfBufWinEnter
987endfunc
988
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100989func Test_bufwinenter_once()
990 augroup QfBufWinEnter
991 au!
992 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
993 augroup END
994 let g:got_afile = ''
995 copen
996 call assert_equal('got quickfix', g:got_afile)
997
998 cclose
999 unlet g:got_afile
1000 augroup QfBufWinEnter
1001 au!
1002 augroup END
1003 augroup! QfBufWinEnter
1004endfunc
1005
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001006func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001007 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +01001008
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001009 Xgetexpr ['file:1:1:message']
1010 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001011 if a:cchar == 'c'
1012 call setqflist(l, 'r')
1013 else
1014 call setloclist(0, l, 'r')
1015 endif
1016
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001017 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +01001018 if a:cchar == 'c'
1019 let title = ':setqflist()'
1020 else
1021 let title = ':setloclist()'
1022 endif
1023 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001024 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001025endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001026
1027" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001028func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001029 call XqfTitleTests('c')
1030 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001031endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001032
1033" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001034func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001035 let save_efm = &efm
1036 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
1037 cgetexpr ['WWWW', 'EEEE', 'CCCC']
1038 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1039 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1040 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
1041 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1042 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1043 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
1044 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1045 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
1046 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001047endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001048
1049" This will test for problems in quickfix:
1050" A. incorrectly copying location lists which caused the location list to show
1051" a different name than the file that was actually being displayed.
1052" B. not reusing the window for which the location list window is opened but
1053" instead creating new windows.
1054" C. make sure that the location list window is not reused instead of the
1055" window it belongs to.
1056"
1057" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001058func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001059 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
1060 let word = substitute(base, '\v(.*)\..*', '\1', '')
1061
1062 setl modifiable
1063 setl noreadonly
1064 setl noswapfile
1065 setl bufhidden=delete
1066 %del _
1067 " For problem 2:
1068 " 'buftype' has to be set to reproduce the constant opening of new windows
1069 setl buftype=nofile
1070
1071 call setline(1, word)
1072
1073 setl nomodified
1074 setl nomodifiable
1075 setl readonly
1076 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001077endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001078
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001079func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001080 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001081
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001082 augroup testgroup
1083 au!
1084 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
1085 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001086
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001087 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001088
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001089 let qflist = []
1090 for word in words
1091 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
1092 " NOTE: problem 1:
1093 " intentionally not setting 'lnum' so that the quickfix entries are not
1094 " valid
1095 eval qflist->setloclist(0, ' ')
1096 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001097
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001098 " Test A
1099 lrewind
1100 enew
1101 lopen
1102 4lnext
1103 vert split
1104 wincmd L
1105 lopen
1106 wincmd p
1107 lnext
1108 let fileName = expand("%")
1109 wincmd p
1110 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
1111 let fileName = substitute(fileName, '\\', '/', 'g')
1112 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
1113 call assert_equal("test://bar.txt", fileName)
1114 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001115
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001116 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001117
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001118 " Test B:
1119 lrewind
1120 lopen
1121 2
1122 exe "normal \<CR>"
1123 wincmd p
1124 3
1125 exe "normal \<CR>"
1126 wincmd p
1127 4
1128 exe "normal \<CR>"
1129 call assert_equal(2, winnr('$'))
1130 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001131
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001132 " Test C:
1133 lrewind
1134 lopen
1135 " Let's move the location list window to the top to check whether it (the
1136 " first window found) will be reused when we try to open new windows:
1137 wincmd K
1138 2
1139 exe "normal \<CR>"
1140 wincmd p
1141 3
1142 exe "normal \<CR>"
1143 wincmd p
1144 4
1145 exe "normal \<CR>"
1146 1wincmd w
1147 call assert_equal('quickfix', &buftype)
1148 2wincmd w
1149 let bufferName = expand("%")
1150 let bufferName = substitute(bufferName, '\\', '/', 'g')
1151 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001152
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001153 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001154
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001155 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +01001156endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001157
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001158func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001159 augroup testgroup
1160 au!
1161 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
1162 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +01001163
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001164 func! R(n)
1165 quit
1166 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001167
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001168 new
1169 let q = []
1170 call add(q, {'filename': 'test_curwin.txt' })
1171 call setloclist(0, q)
1172 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001173
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001174 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001175 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001176endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001177
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001178func Test_locationlist_cross_tab_jump()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001179 call writefile(['loclistfoo'], 'loclistfoo', 'D')
1180 call writefile(['loclistbar'], 'loclistbar', 'D')
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001181 set switchbuf=usetab
1182
1183 edit loclistfoo
1184 tabedit loclistbar
1185 silent lgrep loclistfoo loclist*
1186 call assert_equal(1, tabpagenr())
1187
1188 enew | only | tabonly
1189 set switchbuf&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001190endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001191
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001192" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001193func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001194 " The 'errorformat' setting is different on non-Unix systems.
1195 " This test works only on Unix-like systems.
1196 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001197
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001198 let l =<< trim [DATA]
1199 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1200 "Xtestfile", line 6 col 19; this is an error
1201 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1202 Xtestfile:9: parse error before `asd'
1203 make: *** [vim] Error 1
1204 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001205
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001206 2 returned
1207 "Xtestfile", line 11 col 1; this is an error
1208 "Xtestfile", line 12 col 2; this is another error
1209 "Xtestfile", line 14:10; this is an error in column 10
1210 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1211 "Xtestfile", linenr 16: yet another problem
1212 Error in "Xtestfile" at line 17:
1213 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001214 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001215 ^
1216 Error in "Xtestfile" at line 18:
1217 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001218 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001219 .............^
1220 Error in "Xtestfile" at line 19:
1221 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001222 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001223 --------------^
1224 Error in "Xtestfile" at line 20:
1225 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001226 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1227 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001228
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001229 Does anyone know what is the problem and how to correction it?
1230 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1231 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1232 [DATA]
1233
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001234 call writefile(l, 'Xerrorfile1', 'D')
1235 call delete('loclistbar')
1236 call writefile(l[:-2], 'Xerrorfile2', 'D')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001237
1238 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001239 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1240 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1241 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1242 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1243 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1244 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1245 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1246 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1247 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1248 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1249 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1250 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1251 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1252 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1253 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1254 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1255 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1256 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1257 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1258 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1259 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1260[DATA]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001261 call writefile(m, 'Xtestfile', 'D')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001262
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001263 let save_efm = &efm
1264 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1265 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001266
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001267 exe 'cf Xerrorfile2'
1268 clast
1269 copen
1270 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1271 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001272
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001273 exe 'cf Xerrorfile1'
1274 call assert_equal([4, 12], [line('.'), col('.')])
1275 cn
1276 call assert_equal([6, 19], [line('.'), col('.')])
1277 cn
1278 call assert_equal([9, 2], [line('.'), col('.')])
1279 cn
1280 call assert_equal([10, 2], [line('.'), col('.')])
1281 cn
1282 call assert_equal([11, 1], [line('.'), col('.')])
1283 cn
1284 call assert_equal([12, 2], [line('.'), col('.')])
1285 cn
1286 call assert_equal([14, 10], [line('.'), col('.')])
1287 cn
1288 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1289 cn
1290 call assert_equal([16, 2], [line('.'), col('.')])
1291 cn
1292 call assert_equal([17, 6], [line('.'), col('.')])
1293 cn
1294 call assert_equal([18, 7], [line('.'), col('.')])
1295 cn
1296 call assert_equal([19, 8], [line('.'), col('.')])
1297 cn
1298 call assert_equal([20, 9], [line('.'), col('.')])
1299 clast
1300 cprev
1301 cprev
1302 wincmd w
1303 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1304 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001305
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001306 let &efm = save_efm
Bram Moolenaaree85df32017-03-19 14:19:50 +01001307endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001308
Bram Moolenaarab47c612016-06-14 22:02:26 +02001309" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001310func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001311 call s:setup_commands(a:cchar)
1312
Bram Moolenaarab47c612016-06-14 22:02:26 +02001313 let save_efm=&efm
1314 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1315
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001316 let lines =<< trim END
1317 Entering dir 'dir1/a'
1318 habits2.txt:1:Nine Healthy Habits
1319 Entering dir 'b'
1320 habits3.txt:2:0 Hours of television
1321 habits2.txt:7:5 Small meals
1322 Entering dir 'dir1/c'
1323 habits4.txt:3:1 Hour of exercise
1324 Leaving dir 'dir1/c'
1325 Leaving dir 'dir1/a'
1326 habits1.txt:4:2 Liters of water
1327 Entering dir 'dir2'
1328 habits5.txt:5:3 Cups of hot green tea
1329 Leaving dir 'dir2'
1330 END
Bram Moolenaarab47c612016-06-14 22:02:26 +02001331
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001332 Xexpr ""
1333 for l in lines
1334 Xaddexpr l
1335 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001336
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001337 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001338
1339 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1340 call assert_equal(1, qf[1].lnum)
1341 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1342 call assert_equal(2, qf[3].lnum)
1343 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1344 call assert_equal(7, qf[4].lnum)
1345 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1346 call assert_equal(3, qf[6].lnum)
1347 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1348 call assert_equal(4, qf[9].lnum)
1349 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1350 call assert_equal(5, qf[11].lnum)
1351
1352 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001353endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001354
1355" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001356func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001357 " Create the directory stack and files
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001358 call mkdir('dir1', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001359 call mkdir('dir1/a')
1360 call mkdir('dir1/a/b')
1361 call mkdir('dir1/c')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001362 call mkdir('dir2', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001363
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001364 let lines =<< trim END
1365 Nine Healthy Habits
1366 0 Hours of television
1367 1 Hour of exercise
1368 2 Liters of water
1369 3 Cups of hot green tea
1370 4 Short mental breaks
1371 5 Small meals
1372 6 AM wake up time
1373 7 Minutes of laughter
1374 8 Hours of sleep (at least)
1375 9 PM end of the day and off to bed
1376 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001377 call writefile(lines, 'habits1.txt', 'D')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001378 call writefile(lines, 'dir1/a/habits2.txt')
1379 call writefile(lines, 'dir1/a/b/habits3.txt')
1380 call writefile(lines, 'dir1/c/habits4.txt')
1381 call writefile(lines, 'dir2/habits5.txt')
1382
1383 call s:dir_stack_tests('c')
1384 call s:dir_stack_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001385endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001386
Bram Moolenaar9b457942016-10-09 16:10:05 +02001387" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001388func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001389 call s:setup_commands(a:cchar)
1390
1391 let save_efm = &efm
1392
1393 let &efm =
1394 \ '%Eerror %m %l,' .
1395 \ '%-Wignored %m %l,' .
1396 \ '%+Cmore ignored %m %l,' .
1397 \ '%Zignored end'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001398 let lines =<< trim END
1399 ignored warning 1
1400 more ignored continuation 2
1401 ignored end
1402 error resync 4
1403 END
1404 Xgetexpr lines
Bram Moolenaar9b457942016-10-09 16:10:05 +02001405 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1406 call assert_equal([['resync', 1, 4, 'E']], l)
1407
1408 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001409endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001410
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001411func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001412 call Xefm_ignore_continuations('c')
1413 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001414endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001415
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001416" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001417func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001418 call s:setup_commands(a:cchar)
1419
Bram Moolenaar049cba92016-06-26 14:38:04 +02001420 let save_efm = &efm
1421
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001422 set efm=%f:%l:%m,%f:%f:%l:%m
1423 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1424
1425 set efm=%f:%l:%m,%f:%l:%r:%m
1426 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1427
1428 set efm=%f:%l:%m,%O:%f:%l:%m
1429 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1430
1431 set efm=%f:%l:%m,%f:%l:%*[^a-z
1432 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1433
1434 set efm=%f:%l:%m,%f:%l:%*c
1435 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1436
1437 set efm=%f:%l:%m,%L%M%N
1438 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1439
1440 set efm=%f:%l:%m,%f:%l:%m:%R
1441 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1442
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001443 " Invalid regular expression
1444 set efm=%\\%%k
1445 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1446
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001447 set efm=
1448 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1449
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001450 " Empty directory name. When there is an error in parsing new entries, make
1451 " sure the previous quickfix list is made the current list.
1452 set efm&
1453 cexpr ["one", "two"]
1454 let qf_id = getqflist(#{id: 0}).id
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001455 set efm=%DEntering\ dir\ abc,%f:%l:%m
1456 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001457 call assert_equal(qf_id, getqflist(#{id: 0}).id)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001458
1459 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001460endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001461
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001462func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001463 call Xinvalid_efm_Tests('c')
1464 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001465endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001466
1467" TODO:
1468" Add tests for the following formats in 'errorformat'
1469" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001470func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001471 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001472
1473 " Test for %s format in efm
1474 set efm=%f:%s
1475 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001476 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001477 call assert_equal('^\VLine search text\$', l[0].pattern)
1478 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001479
Bram Moolenaaree85df32017-03-19 14:19:50 +01001480 let l = split(execute('clist', ''), "\n")
1481 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1482
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001483 " Test for a long line
1484 cexpr 'Xtestfile:' . repeat('a', 1026)
1485 let l = getqflist()
1486 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1487
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001488 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001489 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001490 [Xtestfile1]
1491 (1,17) error: ';' missing
1492 (21,2) warning: variable 'z' not defined
1493 (67,3) error: end of file found before string ended
1494 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001495
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001496 [Xtestfile2]
1497 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001498
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001499 [Xtestfile3]
1500 NEW compiler v1.1
1501 (2,2) warning: variable 'x' not defined
1502 (67,3) warning: 's' already defined
1503 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001504 [DATA]
1505
Bram Moolenaaree85df32017-03-19 14:19:50 +01001506 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001507 " To exercise the push/pop file functionality in quickfix, the test files
1508 " need to be created.
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001509 call writefile(['Line1'], 'Xtestfile1', 'D')
1510 call writefile(['Line2'], 'Xtestfile2', 'D')
1511 call writefile(['Line3'], 'Xtestfile3', 'D')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001512 cexpr ""
1513 for l in lines
1514 caddexpr l
1515 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001516 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001517 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001518 call assert_equal(21, l[2].lnum)
1519 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001520 call assert_equal('w', l[2].type)
1521 call assert_equal('e', l[3].type)
1522
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001523 " Test for %P, %Q with non-existing files
1524 cexpr lines
1525 let l = getqflist()
1526 call assert_equal(14, len(l))
1527 call assert_equal('[Xtestfile1]', l[0].text)
1528 call assert_equal('[Xtestfile2]', l[6].text)
1529 call assert_equal('[Xtestfile3]', l[9].text)
1530
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001531 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001532 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001533 Error 275
1534 line 42
1535 column 3
1536 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001537 [DATA]
1538
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001539 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1540 cgetexpr lines
1541 let l = getqflist()
1542 call assert_equal(275, l[0].nr)
1543 call assert_equal(42, l[0].lnum)
1544 call assert_equal(3, l[0].col)
1545 call assert_equal('E', l[0].type)
1546 call assert_equal("\n' ' expected after '--'", l[0].text)
1547
1548 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001549 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001550 Error in line 147 of foo.c:
1551 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001552 [DATA]
1553
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001554 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1555 cgetexpr lines
1556 let l = getqflist()
1557 call assert_equal(147, l[0].lnum)
1558 call assert_equal('E', l[0].type)
1559 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001560
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001561 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001562 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001563 ==============================================================
1564 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1565 --------------------------------------------------------------
1566 Traceback (most recent call last):
1567 File "unittests/dbfacadeTest.py", line 89, in testFoo
1568 self.assertEquals(34, dtid)
1569 File "/usr/lib/python2.2/unittest.py", line 286, in
1570 failUnlessEqual
1571 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001572 W:AssertionError: 34 != 33
Bram Moolenaar94722c52023-01-28 19:19:03 +00001573
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001574 --------------------------------------------------------------
1575 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001576 [DATA]
1577
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001578 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001579 cgetexpr lines
1580 let l = getqflist()
1581 call assert_equal(8, len(l))
1582 call assert_equal(89, l[4].lnum)
1583 call assert_equal(1, l[4].valid)
1584 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001585 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001586
Bram Moolenaard76ce852018-05-01 15:02:04 +02001587 " Test for %o
1588 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001589 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001590 call writefile(['Line1'], 'Xotestfile', 'D')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001591 let l = getqflist()
1592 call assert_equal(1, len(l), string(l))
1593 call assert_equal('Language.PureScript.Types', l[0].module)
1594 copen
1595 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1596 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001597 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001598 cclose
1599 bd
Bram Moolenaard76ce852018-05-01 15:02:04 +02001600
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001601 " Test for a long module name
1602 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1603 let l = getqflist()
1604 call assert_equal(repeat('m', 1024), l[0].module)
1605 call assert_equal(15, l[0].lnum)
1606 call assert_equal('message', l[0].text)
1607
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001608 " The following sequence of commands used to crash Vim
1609 set efm=%W%m
1610 cgetexpr ['msg1']
1611 let l = getqflist()
1612 call assert_equal(1, len(l), string(l))
1613 call assert_equal('msg1', l[0].text)
1614 set efm=%C%m
1615 lexpr 'msg2'
1616 let l = getloclist(0)
1617 call assert_equal(1, len(l), string(l))
1618 call assert_equal('msg2', l[0].text)
1619 lopen
1620 call setqflist([], 'r')
1621 caddbuf
1622 let l = getqflist()
1623 call assert_equal(1, len(l), string(l))
1624 call assert_equal('|| msg2', l[0].text)
1625
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001626 " When matching error lines, case should be ignored. Test for this.
1627 set noignorecase
1628 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1629 call assert_equal(10, l.items[0].lnum)
1630 call assert_equal('Line 20', l.items[0].text)
1631 set ignorecase&
1632
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001633 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001634 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001635endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001636
Bram Moolenaare9283662020-06-07 14:10:47 +02001637" Test for '%t' (error type) field in 'efm'
1638func Test_efm_error_type()
1639 let save_efm = &efm
1640
1641 " error type
1642 set efm=%f:%l:%t:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001643 let lines =<< trim END
1644 Xfile1:10:E:msg1
1645 Xfile1:20:W:msg2
1646 Xfile1:30:I:msg3
1647 Xfile1:40:N:msg4
1648 Xfile1:50:R:msg5
1649 END
1650 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001651 let output = split(execute('clist'), "\n")
1652 call assert_equal([
1653 \ ' 1 Xfile1:10 error: msg1',
1654 \ ' 2 Xfile1:20 warning: msg2',
1655 \ ' 3 Xfile1:30 info: msg3',
1656 \ ' 4 Xfile1:40 note: msg4',
1657 \ ' 5 Xfile1:50 R: msg5'], output)
1658
1659 " error type and a error number
1660 set efm=%f:%l:%t:%n:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001661 let lines =<< trim END
1662 Xfile1:10:E:2:msg1
1663 Xfile1:20:W:4:msg2
1664 Xfile1:30:I:6:msg3
1665 Xfile1:40:N:8:msg4
1666 Xfile1:50:R:3:msg5
1667 END
1668 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001669 let output = split(execute('clist'), "\n")
1670 call assert_equal([
1671 \ ' 1 Xfile1:10 error 2: msg1',
1672 \ ' 2 Xfile1:20 warning 4: msg2',
1673 \ ' 3 Xfile1:30 info 6: msg3',
1674 \ ' 4 Xfile1:40 note 8: msg4',
1675 \ ' 5 Xfile1:50 R 3: msg5'], output)
1676 let &efm = save_efm
1677endfunc
1678
haya14busae023d492022-02-08 18:09:29 +00001679" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1680func Test_efm_end_lnum_col()
1681 let save_efm = &efm
1682
1683 " single line
1684 set efm=%f:%l-%e:%c-%k:%t:%m
1685 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1686 let output = split(execute('clist'), "\n")
1687 call assert_equal([
1688 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1689 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1690
1691 " multiple lines
1692 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001693 let lines =<< trim END
1694 1)msg1
1695 Xfile1:14-24:1-2
1696 2)msg2
1697 Xfile1:24-34:3-4
1698 END
1699 cexpr lines
haya14busae023d492022-02-08 18:09:29 +00001700 let output = split(execute('clist'), "\n")
1701 call assert_equal([
1702 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1703 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1704 let &efm = save_efm
1705endfunc
1706
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001707func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001708 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001709 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001710 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001711 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001712 colder
1713 cgetexpr []
1714 endfunc
1715 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001716 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001717 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001718 lolder
1719 lgetexpr []
1720 endfunc
1721 endif
1722
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001723 augroup QF_Test
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001724 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001725 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001726 augroup END
1727
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001728 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001729 let words = [ "a", "b" ]
1730 let qflist = []
1731 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001732 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001733 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001734 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001736
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001737 augroup QF_Test
1738 au!
1739 augroup END
1740
1741 if a:cchar == 'c'
1742 cexpr ["Xtest1:1:Line"]
1743 cwindow
1744 only
1745 augroup QF_Test
1746 au!
1747 autocmd WinEnter * call setqflist([], 'f')
1748 augroup END
1749 call assert_fails('exe "normal \<CR>"', 'E925:')
1750 augroup QF_Test
1751 au!
1752 augroup END
1753 endif
1754 %bw!
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001755endfunc
1756
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001758 call XquickfixChangedByAutocmd('c')
1759 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001760endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001761
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001762func Test_setloclist_in_autocommand()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001763 call writefile(['test1', 'test2'], 'Xfile', 'D')
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001764 edit Xfile
1765 let s:bufnr = bufnr()
1766 call setloclist(1,
1767 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1768 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1769
1770 augroup Test_LocList
1771 au!
1772 autocmd BufEnter * call setloclist(1,
1773 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1774 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1775 augroup END
1776
1777 lopen
1778 call assert_fails('exe "normal j\<CR>"', 'E926:')
1779
1780 augroup Test_LocList
1781 au!
1782 augroup END
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001783endfunc
1784
Bram Moolenaar8b201792016-03-25 15:01:10 +01001785func Test_caddbuffer_to_empty()
1786 helpgr quickfix
1787 call setqflist([], 'r')
1788 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001789 try
1790 cn
1791 catch
1792 " number of matches is unknown
1793 call assert_true(v:exception =~ 'E553:')
1794 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001795 quit!
1796endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001797
1798func Test_cgetexpr_works()
1799 " this must not crash Vim
1800 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001801 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001802endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001803
1804" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001805func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001806 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001807
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001808 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001809 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001810 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001811 call assert_equal(2, len(l))
1812 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001813 call assert_equal(3, l[1].end_lnum)
1814 call assert_equal(4, l[1].col)
1815 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001816
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001817 Xnext
1818 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1819 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001820 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001821 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001822 call assert_equal(3, line('.'))
1823
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001824 " Appending entries to the list should not change the cursor position
1825 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001826 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001827 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001828 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001829 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1830 call assert_equal(1, line('.'))
1831 close
1832
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001834 \ {'bufnr': a:bnum, 'lnum': 4},
1835 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001836 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001837 call assert_equal(3, len(l))
1838 call assert_equal(5, l[2].lnum)
1839
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001840 call g:Xsetlist([])
1841 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001842 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001843
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001844 " Tests for setting the 'valid' flag
1845 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1846 Xwindow
1847 call assert_equal(1, winnr('$'))
1848 let l = g:Xgetlist()
1849 call g:Xsetlist(l)
1850 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001851 " Adding a non-valid entry should not mark the list as having valid entries
1852 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1853 Xwindow
1854 call assert_equal(1, winnr('$'))
1855
1856 " :cnext/:cprev should still work even with invalid entries in the list
1857 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1858 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1859 call g:Xsetlist(l)
1860 Xnext
1861 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1862 Xprev
1863 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1864 " :cnext/:cprev should still work after appending invalid entries to an
1865 " empty list
1866 call g:Xsetlist([])
1867 call g:Xsetlist(l, 'a')
1868 Xnext
1869 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1870 Xprev
1871 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1872
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001873 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1874 Xwindow
1875 call assert_equal(2, winnr('$'))
1876 Xclose
1877 let save_efm = &efm
1878 set efm=%m
1879 Xgetexpr 'TestMessage'
1880 let l = g:Xgetlist()
1881 call g:Xsetlist(l)
1882 call assert_equal(1, g:Xgetlist()[0].valid)
1883 let &efm = save_efm
1884
Bram Moolenaaree85df32017-03-19 14:19:50 +01001885 " Error cases:
1886 " Refer to a non-existing buffer and pass a non-dictionary type
1887 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1888 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1889 call g:Xsetlist([[1, 2,3]])
1890 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001891 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001892 call g:Xsetlist([test_null_dict()])
1893 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001894endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001895
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001896func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001897 new Xtestfile | only
1898 let bnum = bufnr('%')
1899 call setline(1, range(1,5))
1900
1901 call SetXlistTests('c', bnum)
1902 call SetXlistTests('l', bnum)
1903
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001904 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001905 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001906endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001907
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001908func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001909 call s:setup_commands(a:cchar)
1910
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001911 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001912 let @/ = 'Test_'
1913 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001914 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001915 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001916 Xvimgrep empty test_quickfix.vim
1917 call assert_true(len(g:Xgetlist()) > 0)
1918 Xvimgrep matches test_quickfix.vim
1919 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001920 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001921 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001922 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001923 call g:Xsetlist([], 'r')
1924 call assert_true(len(g:Xgetlist()) == 0)
1925 Xolder
1926 call assert_equal(testlen, len(g:Xgetlist()))
1927 Xnewer
1928 Xnewer
1929 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001930endfunc
1931
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001932func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001933 call Xlist_empty_middle('c')
1934 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001935endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001936
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001937func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001938 call s:setup_commands(a:cchar)
1939
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001940 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001941 Xvimgrep one test_quickfix.vim
1942 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001943 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001944 Xvimgrep two test_quickfix.vim
1945 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001946 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001947 Xvimgrep three test_quickfix.vim
1948 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001949 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001950 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001951 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001952 call g:Xsetlist([], 'r')
1953 call assert_true(len(g:Xgetlist()) == 0)
1954 Xnewer
1955 call assert_equal(twolen, len(g:Xgetlist()))
1956 Xnewer
1957 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001958endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001959
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001960func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001961 call Xlist_empty_older('c')
1962 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001963endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001964
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001965func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001966 call s:setup_commands(a:cchar)
1967
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001968 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1969 \ {'filename': 'fnameB', 'text': 'B'}]
1970 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1971 \ {'filename': 'fnameD', 'text': 'D'},
1972 \ {'filename': 'fnameE', 'text': 'E'}]
1973
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001974 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001975 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001976 silent! Xnewer 99
1977 call g:Xsetlist(list1)
1978 call g:Xsetlist(list2)
1979 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001980 call assert_equal(3, len(li))
1981 call assert_equal('C', li[0]['text'])
1982 call assert_equal('D', li[1]['text'])
1983 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001984 silent! Xolder
1985 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001986 call assert_equal(2, len(li))
1987 call assert_equal('A', li[0]['text'])
1988 call assert_equal('B', li[1]['text'])
1989
1990 " {action} is specified ' '.
1991 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001992 silent! Xnewer 99
1993 call g:Xsetlist(list1)
1994 call g:Xsetlist(list2, ' ')
1995 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001996 call assert_equal(3, len(li))
1997 call assert_equal('C', li[0]['text'])
1998 call assert_equal('D', li[1]['text'])
1999 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002000 silent! Xolder
2001 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002002 call assert_equal(2, len(li))
2003 call assert_equal('A', li[0]['text'])
2004 call assert_equal('B', li[1]['text'])
2005
2006 " {action} is specified 'a'.
2007 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002008 silent! Xnewer 99
2009 call g:Xsetlist(list1)
2010 call g:Xsetlist(list2, 'a')
2011 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002012 call assert_equal(5, len(li))
2013 call assert_equal('A', li[0]['text'])
2014 call assert_equal('B', li[1]['text'])
2015 call assert_equal('C', li[2]['text'])
2016 call assert_equal('D', li[3]['text'])
2017 call assert_equal('E', li[4]['text'])
2018
2019 " {action} is specified 'r'.
2020 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002021 silent! Xnewer 99
2022 call g:Xsetlist(list1)
2023 call g:Xsetlist(list2, 'r')
2024 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002025 call assert_equal(3, len(li))
2026 call assert_equal('C', li[0]['text'])
2027 call assert_equal('D', li[1]['text'])
2028 call assert_equal('E', li[2]['text'])
2029
2030 " Test for wrong value.
2031 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002032 call assert_fails("call g:Xsetlist(0)", 'E714:')
2033 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
2034 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
2035 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
2036 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002037endfunc
2038
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002039func Test_setqflist_invalid_nr()
2040 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02002041 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002042endfunc
2043
Bram Moolenaar99234f22020-02-10 22:56:54 +01002044func Test_setqflist_user_sets_buftype()
2045 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
2046 set buftype=quickfix
2047 call setqflist([], 'a')
2048 enew
2049endfunc
2050
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002051func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002052 call XquickfixSetListWithAct('c')
2053 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002054endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002055
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002056func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002057 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002058
Bram Moolenaar049cba92016-06-26 14:38:04 +02002059 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002060 call assert_equal(1, l[0].lnum)
2061 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002062 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002063 call assert_equal(2, l[1].lnum)
2064 call assert_equal(1, l[1].col)
2065 call assert_equal(4070, len(l[1].text))
2066 call assert_equal(3, l[2].lnum)
2067 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002068 call assert_equal(4070, len(l[2].text))
2069 call assert_equal(4, l[3].lnum)
2070 call assert_equal(1, l[3].col)
2071 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002072
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002073 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002074endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002075
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002076func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002077 call s:setup_commands(a:cchar)
2078
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002079 let testfile = 'samples/quickfix.txt'
2080
2081 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002082 exe 'Xgetfile' testfile
2083 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002084
2085 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002086 Xexpr readfile(testfile)
2087 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002088
2089 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002090 Xexpr join(readfile(testfile), "\n")
2091 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002092
2093 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002094 exe 'edit' testfile
2095 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02002096 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002097endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002098
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002099func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002100 call s:long_lines_tests('c')
2101 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002102endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002103
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002104func Test_cgetfile_on_long_lines()
2105 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
2106 " are read at a time.
2107 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002108 let lines =<< trim END
2109 /tmp/file1:1:1:aaa
2110 /tmp/file2:1:1:%s
2111 /tmp/file3:1:1:bbb
2112 /tmp/file4:1:1:ccc
2113 END
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002114 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002115 call writefile(lines, 'Xcqetfile.txt', 'D')
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002116 cgetfile Xcqetfile.txt
2117 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
2118 endfor
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002119endfunc
2120
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002121func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002122 let l = []
2123 for i in range(1, 20)
2124 call add(l, 'Line' . i)
2125 endfor
2126 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002127endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002128
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002129func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002130 call s:create_test_file('Xqftestfile1')
2131 call s:create_test_file('Xqftestfile2')
2132 call s:create_test_file('Xqftestfile3')
2133
2134 new | only
2135 edit Xqftestfile1
2136 let file1_winid = win_getid()
2137 new Xqftestfile2
2138 let file2_winid = win_getid()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002139 let lines =<< trim END
2140 Xqftestfile1:5:Line5
2141 Xqftestfile1:6:Line6
2142 Xqftestfile2:10:Line10
2143 Xqftestfile2:11:Line11
2144 Xqftestfile3:15:Line15
2145 Xqftestfile3:16:Line16
2146 END
2147 cgetexpr lines
Bram Moolenaar049cba92016-06-26 14:38:04 +02002148
2149 new
2150 let winid = win_getid()
2151 cfirst | cnext
2152 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002153 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002154 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002155 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002156 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002157
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002158 " Test for 'switchbuf' set to search for files in windows in the current
2159 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002160 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002161 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02002162 cfirst | cnext
2163 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002164 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002165 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002166 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002167 call assert_equal(file2_winid, win_getid())
2168
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002169 " Test for 'switchbuf' set to search for files in tabpages and jump to an
2170 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002171 enew | only
2172 set switchbuf=usetab
2173 tabedit Xqftestfile1
2174 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01002175 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02002176 tabfirst
2177 cfirst | cnext
2178 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002179 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002180 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002181 6cnext
2182 call assert_equal(4, tabpagenr())
2183 2cpfile
2184 call assert_equal(2, tabpagenr())
2185 2cnfile
2186 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002187 tabfirst | tabonly | enew
2188
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002189 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002190 set switchbuf=split
2191 cfirst | cnext
2192 call assert_equal(1, winnr('$'))
2193 cnext | cnext
2194 call assert_equal(2, winnr('$'))
2195 cnext | cnext
2196 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002197
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002198 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002199 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002200 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002201 cfirst | cnext
2202 call assert_equal(1, tabpagenr('$'))
2203 cnext | cnext
2204 call assert_equal(2, tabpagenr('$'))
2205 cnext | cnext
2206 call assert_equal(3, tabpagenr('$'))
2207 tabfirst | enew | tabonly | only
2208
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002209 set switchbuf=uselast
2210 split
2211 let last_winid = win_getid()
2212 copen
2213 exe "normal 1G\<CR>"
2214 call assert_equal(last_winid, win_getid())
2215 enew | only
2216
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002217 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2218 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002219 set switchbuf=
2220 edit Xqftestfile1
2221 let file1_winid = win_getid()
2222 new Xqftestfile2
2223 let file2_winid = win_getid()
2224 copen
2225 exe "normal 1G\<CR>"
2226 call assert_equal(file1_winid, win_getid())
2227 copen
2228 exe "normal 3G\<CR>"
2229 call assert_equal(file2_winid, win_getid())
2230 copen | only
2231 exe "normal 5G\<CR>"
2232 call assert_equal(2, winnr('$'))
2233 call assert_equal(1, bufwinnr('Xqftestfile3'))
2234
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002235 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002236 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002237 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002238 set switchbuf=usetab
2239 tabedit Xqftestfile1
2240 tabedit Xqftestfile2
2241 tabedit Xqftestfile3
2242 tabfirst
2243 copen | only
2244 clast
2245 call assert_equal(4, tabpagenr())
2246 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002247
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002248 " Jumping to a file that is not present in any of the tabpages and the
2249 " current tabpage doesn't have any usable windows, should open it in a new
2250 " window in the current tabpage.
2251 copen | only
2252 cfirst
2253 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002254 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002255
2256 " If opening a file changes 'switchbuf', then the new value should be
2257 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002258 set modeline&vim
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002259 call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002260 enew | only
2261 set switchbuf&vim
2262 cexpr "Xqftestfile1:1:10"
2263 call assert_equal('split', &switchbuf)
2264 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2265 enew | only
2266 set switchbuf=useopen
2267 cexpr "Xqftestfile1:1:10"
2268 call assert_equal('usetab', &switchbuf)
2269 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2270 enew | only
2271 set switchbuf=useopen
2272 cexpr "Xqftestfile1:1:10"
2273 call assert_equal('', &switchbuf)
2274
Bram Moolenaar049cba92016-06-26 14:38:04 +02002275 call delete('Xqftestfile2')
2276 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002277 set switchbuf&vim
2278
2279 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002280endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002281
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002282func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002283 call s:setup_commands(a:cchar)
2284
2285 enew | only
2286
Bram Moolenaarc1542742016-07-20 21:44:37 +02002287 let fname = 'Xqftestfile' . a:cchar
2288 call s:create_test_file(fname)
2289 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002290
Bram Moolenaarc1542742016-07-20 21:44:37 +02002291 Xgetexpr [fname . ':5:Line5',
2292 \ fname . ':10:Line10',
2293 \ fname . ':15:Line15',
2294 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002295
2296 6,14delete
2297 call append(6, ['Buffer', 'Window'])
2298
2299 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002300 call assert_equal(5, l[0].lnum)
2301 call assert_equal(6, l[2].lnum)
2302 call assert_equal(13, l[3].lnum)
2303
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002304 " If a file doesn't have any quickfix entries, then deleting lines in the
2305 " file should not update the quickfix list
2306 call g:Xsetlist([], 'f')
2307 1,2delete
2308 call assert_equal([], g:Xgetlist())
2309
Bram Moolenaar049cba92016-06-26 14:38:04 +02002310 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002311 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002312endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002313
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002314func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002315 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002316 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002317 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002318 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002319endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002320
2321" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002322func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002323 call s:setup_commands(a:cchar)
2324
2325 " The following lines are used for the grep test. Don't remove.
2326 " Grep_Test_Text: Match 1
2327 " Grep_Test_Text: Match 2
2328 " GrepAdd_Test_Text: Match 1
2329 " GrepAdd_Test_Text: Match 2
2330 enew! | only
2331 set makeef&vim
2332 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002333 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002334 Xopen
2335 call assert_true(w:quickfix_title =~ '^:grep')
2336 Xclose
2337 enew
2338 set makeef=Temp_File_##
2339 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002340 call assert_true(len(g:Xgetlist()) == 9)
2341
2342 " Try with 'grepprg' set to 'internal'
2343 set grepprg=internal
2344 silent Xgrep Grep_Test_Text: test_quickfix.vim
2345 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2346 call assert_true(len(g:Xgetlist()) == 9)
2347 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002348
2349 call writefile(['Vim'], 'XtestTempFile')
2350 set makeef=XtestTempFile
2351 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002352 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002353 call assert_false(filereadable('XtestTempFile'))
2354 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002355endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002356
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002357func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002358 " The grepprg may not be set on non-Unix systems
2359 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002360
2361 call s:test_xgrep('c')
2362 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002363endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002364
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002365func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002366 " Use one 'errorformat' for two windows. Add an expression to each of them,
2367 " make sure they each keep their own state.
2368 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002369 call mkdir('Xone/a', 'pR')
2370 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002371 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2372 call writefile(lines, 'Xone/a/one.txt')
2373 call writefile(lines, 'Xtwo/a/two.txt')
2374
2375 new one
2376 let one_id = win_getid()
2377 lexpr ""
2378 new two
2379 let two_id = win_getid()
2380 lexpr ""
2381
2382 laddexpr "Entering dir 'Xtwo/a'"
2383 call win_gotoid(one_id)
2384 laddexpr "Entering dir 'Xone/a'"
2385 call win_gotoid(two_id)
2386 laddexpr 'two.txt:5:two two two'
2387 call win_gotoid(one_id)
2388 laddexpr 'one.txt:3:one one one'
2389
2390 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002391 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2392 call assert_equal(3, loc_one[1].lnum)
2393
2394 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002395 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2396 call assert_equal(5, loc_two[1].lnum)
2397
2398 call win_gotoid(one_id)
2399 bwipe!
2400 call win_gotoid(two_id)
2401 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002402endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002403
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002404func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002405 call s:setup_commands(a:cchar)
2406
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002407 " Calling lbottom without any errors should fail
2408 if a:cchar == 'l'
2409 call assert_fails('lbottom', 'E776:')
2410 endif
2411
Bram Moolenaar875feea2017-06-11 16:07:51 +02002412 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002413 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002414 let wid = win_getid()
2415 call assert_equal(1, line('.'))
2416 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002417 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002418 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002419 call win_gotoid(wid)
2420 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002421 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002422endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002423
2424" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002425func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002426 call XbottomTests('c')
2427 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002428endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002429
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002430func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002431 call s:setup_commands(a:cchar)
2432
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002433 " clear all lists after the first one, then replace the first one.
2434 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002435 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002436 let entry = {'filename': 'foo', 'lnum': 42}
2437 call g:Xsetlist([entry], 'r')
2438 call g:Xsetlist([entry, entry])
2439 call g:Xsetlist([entry, entry, entry])
2440 let res = split(execute(a:cchar . 'hist'), "\n")
2441 call assert_equal(3, len(res))
2442 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2443 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2444 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2445 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002446
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002447 " Test for changing the quickfix lists
2448 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2449 exe '1' . a:cchar . 'hist'
2450 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2451 exe '3' . a:cchar . 'hist'
2452 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2453 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2454 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2455
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002456 call g:Xsetlist([], 'f')
2457 let l = split(execute(a:cchar . 'hist'), "\n")
2458 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002459 if a:cchar == 'c'
2460 call assert_fails('4chist', 'E16:')
2461 else
2462 call assert_fails('4lhist', 'E776:')
2463 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002464
2465 " An empty list should still show the stack history
2466 call g:Xsetlist([])
2467 let res = split(execute(a:cchar . 'hist'), "\n")
2468 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2469
2470 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002471endfunc
2472
2473func Test_history()
2474 call HistoryTest('c')
2475 call HistoryTest('l')
2476endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002477
2478func Test_duplicate_buf()
2479 " make sure we can get the highest buffer number
2480 edit DoesNotExist
2481 edit DoesNotExist2
2482 let last_buffer = bufnr("$")
2483
2484 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002485 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002486 vimgrep one Xgrepthis
2487 vimgrep one Xgrepthis
2488 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002489endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002490
2491" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002492func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002493 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002494
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002495 " Error cases
2496 call assert_fails('call g:Xgetlist(99)', 'E715:')
2497 call assert_fails('call g:Xsetlist(99)', 'E714:')
2498 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002499
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002500 " Set and get the title
2501 call g:Xsetlist([])
2502 Xopen
2503 wincmd p
2504 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2505 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2506 call assert_equal(0, s)
2507 let d = g:Xgetlist({"title":1})
2508 call assert_equal('Sample', d.title)
2509 " Try setting title to a non-string value
2510 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2511 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2512
2513 Xopen
2514 call assert_equal('Sample', w:quickfix_title)
2515 Xclose
2516
2517 " Tests for action argument
2518 silent! Xolder 999
2519 let qfnr = g:Xgetlist({'all':1}).nr
2520 call g:Xsetlist([], 'r', {'title' : 'N1'})
2521 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2522 call g:Xsetlist([], ' ', {'title' : 'N2'})
2523 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2524
2525 let res = g:Xgetlist({'nr': 0})
2526 call assert_equal(qfnr + 1, res.nr)
2527 call assert_equal(['nr'], keys(res))
2528
2529 call g:Xsetlist([], ' ', {'title' : 'N3'})
2530 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2531
2532 " Changing the title of an earlier quickfix list
2533 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2534 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2535
2536 " Changing the title of an invalid quickfix list
2537 call assert_equal(-1, g:Xsetlist([], ' ',
2538 \ {'title' : 'SomeTitle', 'nr' : 99}))
2539 call assert_equal(-1, g:Xsetlist([], ' ',
2540 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2541
2542 if a:cchar == 'c'
2543 copen
2544 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2545 cclose
2546 endif
2547
2548 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002549 call assert_fails('call g:Xgetlist([])', 'E715:')
2550 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002551 let s = g:Xsetlist([], 'a', {'abc':1})
2552 call assert_equal(-1, s)
2553
2554 call assert_equal({}, g:Xgetlist({'abc':1}))
2555 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2556 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2557
2558 if a:cchar == 'l'
2559 call assert_equal({}, getloclist(99, {'title': 1}))
2560 endif
2561
2562 " Context related tests
2563 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2564 call assert_equal(0, s)
2565 call test_garbagecollect_now()
2566 let d = g:Xgetlist({'context':1})
2567 call assert_equal([1,2,3], d.context)
2568 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2569 let d = g:Xgetlist({'context':1})
2570 call assert_equal({'color':'green'}, d.context)
2571 call g:Xsetlist([], 'a', {'context':"Context info"})
2572 let d = g:Xgetlist({'context':1})
2573 call assert_equal("Context info", d.context)
2574 call g:Xsetlist([], 'a', {'context':246})
2575 let d = g:Xgetlist({'context':1})
2576 call assert_equal(246, d.context)
2577 " set other Vim data types as context
2578 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2579 if has('channel')
2580 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2581 endif
2582 if has('job')
2583 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2584 endif
2585 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2586 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2587 call g:Xsetlist([], 'a', {'context' : ''})
2588 call test_garbagecollect_now()
2589 if a:cchar == 'l'
2590 " Test for copying context across two different location lists
2591 new | only
2592 let w1_id = win_getid()
2593 let l = [1]
2594 call setloclist(0, [], 'a', {'context':l})
2595 new
2596 let w2_id = win_getid()
2597 call add(l, 2)
2598 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2599 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2600 unlet! l
2601 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2602 only
2603 call setloclist(0, [], 'f')
2604 call assert_equal('', getloclist(0, {'context':1}).context)
2605 endif
2606
2607 " Test for changing the context of previous quickfix lists
2608 call g:Xsetlist([], 'f')
2609 Xexpr "One"
2610 Xexpr "Two"
2611 Xexpr "Three"
2612 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2613 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2614 " Also, check for setting the context using quickfix list number zero.
2615 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2616 call test_garbagecollect_now()
2617 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2618 call assert_equal([1], l.context)
2619 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2620 call assert_equal([2], l.context)
2621 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2622 call assert_equal([3], l.context)
2623
2624 " Test for changing the context through reference and for garbage
2625 " collection of quickfix context
2626 let l = ["red"]
2627 call g:Xsetlist([], ' ', {'context' : l})
2628 call add(l, "blue")
2629 let x = g:Xgetlist({'context' : 1})
2630 call add(x.context, "green")
2631 call assert_equal(["red", "blue", "green"], l)
2632 call assert_equal(["red", "blue", "green"], x.context)
2633 unlet l
2634 call test_garbagecollect_now()
2635 let m = g:Xgetlist({'context' : 1})
2636 call assert_equal(["red", "blue", "green"], m.context)
2637
2638 " Test for setting/getting items
2639 Xexpr ""
2640 let qfprev = g:Xgetlist({'nr':0})
2641 let s = g:Xsetlist([], ' ', {'title':'Green',
2642 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2643 call assert_equal(0, s)
2644 let qfcur = g:Xgetlist({'nr':0})
2645 call assert_true(qfcur.nr == qfprev.nr + 1)
2646 let l = g:Xgetlist({'items':1})
2647 call assert_equal('F1', bufname(l.items[0].bufnr))
2648 call assert_equal(10, l.items[0].lnum)
2649 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2650 \ {'filename':'F2', 'lnum':30}]})
2651 let l = g:Xgetlist({'items':1})
2652 call assert_equal('F2', bufname(l.items[2].bufnr))
2653 call assert_equal(30, l.items[2].lnum)
2654 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2655 let l = g:Xgetlist({'items':1})
2656 call assert_equal('F3', bufname(l.items[0].bufnr))
2657 call assert_equal(40, l.items[0].lnum)
2658 call g:Xsetlist([], 'r', {'items' : []})
2659 let l = g:Xgetlist({'items':1})
2660 call assert_equal(0, len(l.items))
2661
2662 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2663 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2664 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2665 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2666
2667 " Test for getting id of window associated with a location list window
2668 if a:cchar == 'l'
2669 only
2670 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2671 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002672 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002673 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2674 wincmd w
2675 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2676 only
2677 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002678
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002679 " The following used to crash Vim with address sanitizer
2680 call g:Xsetlist([], 'f')
2681 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2682 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002683
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002684 " Try setting the items using a string
2685 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002686
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002687 " Save and restore the quickfix stack
2688 call g:Xsetlist([], 'f')
2689 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2690 Xexpr "File1:10:Line1"
2691 Xexpr "File2:20:Line2"
2692 Xexpr "File3:30:Line3"
2693 let last_qf = g:Xgetlist({'nr':'$'}).nr
2694 call assert_equal(3, last_qf)
2695 let qstack = []
2696 for i in range(1, last_qf)
2697 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2698 endfor
2699 call g:Xsetlist([], 'f')
2700 for i in range(len(qstack))
2701 call g:Xsetlist([], ' ', qstack[i])
2702 endfor
2703 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2704 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2705 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2706 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2707 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002708
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002709 " Swap two quickfix lists
2710 Xexpr "File1:10:Line10"
2711 Xexpr "File2:20:Line20"
2712 Xexpr "File3:30:Line30"
2713 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2714 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2715 let l1=g:Xgetlist({'nr':1,'all':1})
2716 let l2=g:Xgetlist({'nr':2,'all':1})
2717 let save_id = l1.id
2718 let l1.id=l2.id
2719 let l2.id=save_id
2720 call g:Xsetlist([], 'r', l1)
2721 call g:Xsetlist([], 'r', l2)
2722 let newl1=g:Xgetlist({'nr':1,'all':1})
2723 let newl2=g:Xgetlist({'nr':2,'all':1})
2724 call assert_equal('Fruits', newl1.title)
2725 call assert_equal(['Fruits'], newl1.context)
2726 call assert_equal('Line20', newl1.items[0].text)
2727 call assert_equal('Colors', newl2.title)
2728 call assert_equal(['Colors'], newl2.context)
2729 call assert_equal('Line10', newl2.items[0].text)
2730 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002731
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002732 " Cannot specify both a non-empty list argument and a dict argument
2733 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002734endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002735
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002736func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002737 call Xproperty_tests('c')
2738 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002739endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002740
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002741" Test for setting the current index in the location/quickfix list
2742func Xtest_setqfidx(cchar)
2743 call s:setup_commands(a:cchar)
2744
2745 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2746 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2747 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2748
2749 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2750 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2751 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2752 Xolder 2
2753 Xopen
2754 call assert_equal(3, line('.'))
2755 Xnewer
2756 call assert_equal(2, line('.'))
2757 Xnewer
2758 call assert_equal(2, line('.'))
2759 " Update the current index with the quickfix window open
2760 wincmd w
2761 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2762 Xopen
2763 call assert_equal(3, line('.'))
2764 Xclose
2765
2766 " Set the current index to the last entry
2767 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2768 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2769 " A large value should set the index to the last index
2770 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2771 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2772 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2773 " Invalid index values
2774 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2775 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2776 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2777 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2778 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2779 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2780 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2781
2782 call g:Xsetlist([], 'f')
2783 new | only
2784endfunc
2785
2786func Test_setqfidx()
2787 call Xtest_setqfidx('c')
2788 call Xtest_setqfidx('l')
2789endfunc
2790
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002791" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002792func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002793 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002794endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002795
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002796func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002797 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2798 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2799
2800 let g:acmds = []
2801 cexpr "F1:10:Line 10"
2802 caddexpr "F1:20:Line 20"
2803 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002804 cexpr ""
2805 caddexpr ""
2806 cgetexpr ""
2807 silent! cexpr non_existing_func()
2808 silent! caddexpr non_existing_func()
2809 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002810 let l =<< trim END
2811 precexpr
2812 postcexpr
2813 precaddexpr
2814 postcaddexpr
2815 precgetexpr
2816 postcgetexpr
2817 precexpr
2818 postcexpr
2819 precaddexpr
2820 postcaddexpr
2821 precgetexpr
2822 postcgetexpr
2823 precexpr
2824 precaddexpr
2825 precgetexpr
2826 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002827 call assert_equal(l, g:acmds)
2828
2829 let g:acmds = []
2830 enew! | call append(0, "F2:10:Line 10")
2831 cbuffer!
2832 enew! | call append(0, "F2:20:Line 20")
2833 cgetbuffer
2834 enew! | call append(0, "F2:30:Line 30")
2835 caddbuffer
2836 new
2837 let bnum = bufnr('%')
2838 bunload
2839 exe 'silent! cbuffer! ' . bnum
2840 exe 'silent! cgetbuffer ' . bnum
2841 exe 'silent! caddbuffer ' . bnum
2842 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002843 let l =<< trim END
2844 precbuffer
2845 postcbuffer
2846 precgetbuffer
2847 postcgetbuffer
2848 precaddbuffer
2849 postcaddbuffer
2850 precbuffer
2851 precgetbuffer
2852 precaddbuffer
2853 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002854 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002855
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002856 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2857 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002858 let g:acmds = []
2859 cfile Xtest
2860 caddfile Xtest
2861 cgetfile Xtest
2862 cfile Xempty
2863 caddfile Xempty
2864 cgetfile Xempty
2865 silent! cfile do_not_exist
2866 silent! caddfile do_not_exist
2867 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002868 let l =<< trim END
2869 precfile
2870 postcfile
2871 precaddfile
2872 postcaddfile
2873 precgetfile
2874 postcgetfile
2875 precfile
2876 postcfile
2877 precaddfile
2878 postcaddfile
2879 precgetfile
2880 postcgetfile
2881 precfile
2882 postcfile
2883 precaddfile
2884 postcaddfile
2885 precgetfile
2886 postcgetfile
2887 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002888 call assert_equal(l, g:acmds)
2889
2890 let g:acmds = []
2891 helpgrep quickfix
2892 silent! helpgrep non_existing_help_topic
2893 vimgrep test Xtest
2894 vimgrepadd test Xtest
2895 silent! vimgrep non_existing_test Xtest
2896 silent! vimgrepadd non_existing_test Xtest
2897 set makeprg=
2898 silent! make
2899 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002900 let l =<< trim END
2901 prehelpgrep
2902 posthelpgrep
2903 prehelpgrep
2904 posthelpgrep
2905 previmgrep
2906 postvimgrep
2907 previmgrepadd
2908 postvimgrepadd
2909 previmgrep
2910 postvimgrep
2911 previmgrepadd
2912 postvimgrepadd
2913 premake
2914 postmake
2915 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002916 call assert_equal(l, g:acmds)
2917
2918 if has('unix')
2919 " Run this test only on Unix-like systems. The grepprg may not be set on
2920 " non-Unix systems.
2921 " The following lines are used for the grep test. Don't remove.
2922 " Grep_Autocmd_Text: Match 1
2923 " GrepAdd_Autocmd_Text: Match 2
2924 let g:acmds = []
2925 silent grep Grep_Autocmd_Text test_quickfix.vim
2926 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2927 silent grep abc123def Xtest
2928 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002929 set grepprg=internal
2930 silent grep Grep_Autocmd_Text test_quickfix.vim
2931 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2932 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2933 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2934 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002935 let l =<< trim END
2936 pregrep
2937 postgrep
2938 pregrepadd
2939 postgrepadd
2940 pregrep
2941 postgrep
2942 pregrepadd
2943 postgrepadd
2944 pregrep
2945 postgrep
2946 pregrepadd
2947 postgrepadd
2948 prelgrep
2949 postlgrep
2950 prelgrepadd
2951 postlgrepadd
2952 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002953 call assert_equal(l, g:acmds)
2954 endif
2955
Bram Moolenaarb254af32017-12-18 19:48:58 +01002956 au! QuickFixCmdPre
2957 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002958endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002959
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002960func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002961 set efm=%m
2962 lgetexpr '?'
2963
2964 try
2965 call DoesNotExit()
2966 catch
2967 lgetexpr '1'
2968 finally
2969 lgetexpr '1'
2970 endtry
2971
2972 call assert_equal('1', getloclist(0)[0].text)
2973
2974 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002975endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002976
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002977func Test_caddbuffer_wrong()
2978 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002979 let save_efm = &efm
2980 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2981 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2982 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002983 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002984 bwipe!
2985endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002986
2987func Test_caddexpr_wrong()
2988 " This used to cause a memory access in freed memory.
2989 cbuffer
2990 cbuffer
2991 copen
2992 let save_efm = &efm
2993 set efm=%
2994 call assert_fails('caddexpr ""', 'E376:')
2995 let &efm = save_efm
2996endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002997
2998func Test_dirstack_cleanup()
2999 " This used to cause a memory access in freed memory.
3000 let save_efm = &efm
3001 lexpr '0'
3002 lopen
3003 fun X(c)
3004 let save_efm=&efm
3005 set efm=%D%f
3006 if a:c == 'c'
3007 caddexpr '::'
3008 else
3009 laddexpr ':0:0'
3010 endif
3011 let &efm=save_efm
3012 endfun
3013 call X('c')
3014 call X('l')
3015 call setqflist([], 'r')
3016 caddbuffer
3017 let &efm = save_efm
3018endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003019
3020" Tests for jumping to entries from the location list window and quickfix
3021" window
3022func Test_cwindow_jump()
3023 set efm=%f%%%l%%%m
3024 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3025 lopen | only
3026 lfirst
3027 call assert_true(winnr('$') == 2)
3028 call assert_true(winnr() == 1)
3029 " Location list for the new window should be set
3030 call assert_true(getloclist(0)[2].text == 'Line 30')
3031
3032 " Open a scratch buffer
3033 " Open a new window and create a location list
3034 " Open the location list window and close the other window
3035 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003036 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003037 " should not be used.
3038 enew | only
3039 set buftype=nofile
3040 below new
3041 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3042 lopen
3043 2wincmd c
3044 lnext
3045 call assert_true(winnr('$') == 3)
3046 call assert_true(winnr() == 2)
3047
3048 " Open two windows with two different location lists
3049 " Open the location list window and close the previous window
3050 " Jump to an entry in the location list window
3051 " Should open the file in the first window and not set the location list.
3052 enew | only
3053 lgetexpr ["F1%5%Line 5"]
3054 below new
3055 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3056 lopen
3057 2wincmd c
3058 lnext
3059 call assert_true(winnr() == 1)
3060 call assert_true(getloclist(0)[0].text == 'Line 5')
3061
3062 enew | only
3063 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3064 copen
3065 cnext
3066 call assert_true(winnr('$') == 2)
3067 call assert_true(winnr() == 1)
3068
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003069 " open the quickfix buffer in two windows and jump to an entry. Should open
3070 " the file in the first quickfix window.
3071 enew | only
3072 copen
3073 let bnum = bufnr('')
3074 exe 'sbuffer ' . bnum
3075 wincmd b
3076 cfirst
3077 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003078 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003079 enew | only
3080 exe 'sb' bnum
3081 exe 'botright sb' bnum
3082 wincmd t
3083 clast
3084 call assert_equal(2, winnr())
3085 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3086 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3087
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003088 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003089 " window by wrapping around the window list.
3090 enew | only
3091 call setloclist(0, [], 'f')
3092 new | new
3093 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3094 lopen
3095 1close
3096 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3097 lnext
3098 call assert_equal(3, winnr())
3099 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3100
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003101 enew | only
3102 set efm&vim
3103endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003104
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003105func Test_cwindow_highlight()
3106 CheckScreendump
3107
3108 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003109 call setline(1, ['some', 'text', 'with', 'matches'])
3110 write XCwindow
3111 vimgrep e XCwindow
3112 redraw
3113 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003114 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003115 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003116 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3117 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3118
3119 call term_sendkeys(buf, ":cnext\<CR>")
3120 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3121
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003122 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003123 call term_sendkeys(buf, ":\<CR>")
3124 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3125
3126 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3127 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003128 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3129
3130 call term_sendkeys(buf, "j")
3131 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3132
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003133 " clean up
3134 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003135 call delete('XCwindow')
3136endfunc
3137
Bram Moolenaaree85df32017-03-19 14:19:50 +01003138func XvimgrepTests(cchar)
3139 call s:setup_commands(a:cchar)
3140
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003141 let lines =<< trim END
3142 Editor:VIM vim
3143 Editor:Emacs EmAcS
3144 Editor:Notepad NOTEPAD
3145 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003146 call writefile(lines, 'Xtestfile1', 'D')
3147 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003148
3149 " Error cases
3150 call assert_fails('Xvimgrep /abc *', 'E682:')
3151
3152 let @/=''
3153 call assert_fails('Xvimgrep // *', 'E35:')
3154
3155 call assert_fails('Xvimgrep abc', 'E683:')
3156 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3157 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3158
3159 Xexpr ""
3160 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003161 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003162 let l = g:Xgetlist()
3163 call assert_equal(2, len(l))
3164 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3165
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003166 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003167 let l = g:Xgetlist()
3168 call assert_equal(2, len(l))
3169 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003170 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003171 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003172 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003173
3174 1Xvimgrep ?Editor? Xtestfile*
3175 let l = g:Xgetlist()
3176 call assert_equal(1, len(l))
3177 call assert_equal('Editor:VIM vim', l[0].text)
3178
3179 edit +3 Xtestfile2
3180 Xvimgrep +\cemacs+j Xtestfile1
3181 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003182 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003183 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3184
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003185 " Test for unloading a buffer after vimgrep searched the buffer
3186 %bwipe
3187 Xvimgrep /Editor/j Xtestfile*
3188 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3189 call assert_equal([], getbufinfo('Xtestfile2'))
3190
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003191 " Test for opening the dummy buffer used by vimgrep in a window. The new
3192 " window should be closed
3193 %bw!
3194 augroup QF_Test
3195 au!
3196 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3197 augroup END
3198 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3199 call assert_equal(1, winnr('$'))
3200 augroup QF_Test
3201 au!
3202 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003203endfunc
3204
3205" Tests for the :vimgrep command
3206func Test_vimgrep()
3207 call XvimgrepTests('c')
3208 call XvimgrepTests('l')
3209endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003210
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003211func Test_vimgrep_wildcards_expanded_once()
3212 new X[id-01] file.txt
3213 call setline(1, 'some text to search for')
3214 vimgrep text %
3215 bwipe!
3216endfunc
3217
Bram Moolenaar1c299432018-10-28 14:36:09 +01003218" Test for incsearch highlighting of the :vimgrep pattern
3219" This test used to cause "E315: ml_get: invalid lnum" errors.
3220func Test_vimgrep_incsearch()
3221 enew
3222 set incsearch
3223 call test_override("char_avail", 1)
3224
3225 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3226 let l = getqflist()
3227 call assert_equal(2, len(l))
3228
3229 call test_override("ALL", 0)
3230 set noincsearch
3231endfunc
3232
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003233" Test vimgrep with the last search pattern not set
3234func Test_vimgrep_with_no_last_search_pat()
3235 let lines =<< trim [SCRIPT]
3236 call assert_fails('vimgrep // *', 'E35:')
3237 call writefile(v:errors, 'Xresult')
3238 qall!
3239 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003240 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003241 if RunVim([], [], '--clean -S Xscript')
3242 call assert_equal([], readfile('Xresult'))
3243 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003244 call delete('Xresult')
3245endfunc
3246
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003247" Test vimgrep without swap file
3248func Test_vimgrep_without_swap_file()
3249 let lines =<< trim [SCRIPT]
3250 vimgrep grep test_c*
3251 call writefile(['done'], 'Xresult')
3252 qall!
3253 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003254 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003255 if RunVim([], [], '--clean -n -S Xscript Xscript')
3256 call assert_equal(['done'], readfile('Xresult'))
3257 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003258 call delete('Xresult')
3259endfunc
3260
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003261func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003262 call writefile(['match apple with apple'], 'Xapple', 'D')
3263 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003264 let g:foundSwap = 0
3265 let g:ignoreSwapExists = 1
3266 augroup grep
3267 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3268 augroup END
3269 vimgrep apple Xapple
3270 call assert_equal(1, g:foundSwap)
3271 call assert_match('.Xapple.swo', swapname(''))
3272
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003273 augroup grep
3274 au! SwapExists
3275 augroup END
3276 unlet g:ignoreSwapExists
3277endfunc
3278
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003279func XfreeTests(cchar)
3280 call s:setup_commands(a:cchar)
3281
3282 enew | only
3283
3284 " Deleting the quickfix stack should work even When the current list is
3285 " somewhere in the middle of the stack
3286 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3287 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3288 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3289 Xolder
3290 call g:Xsetlist([], 'f')
3291 call assert_equal(0, len(g:Xgetlist()))
3292
3293 " After deleting the stack, adding a new list should create a stack with a
3294 " single list.
3295 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3296 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3297
3298 " Deleting the stack from a quickfix window should update/clear the
3299 " quickfix/location list window.
3300 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3301 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3302 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3303 Xolder
3304 Xwindow
3305 call g:Xsetlist([], 'f')
3306 call assert_equal(2, winnr('$'))
3307 call assert_equal(1, line('$'))
3308 Xclose
3309
3310 " Deleting the stack from a non-quickfix window should update/clear the
3311 " quickfix/location list window.
3312 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3313 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3314 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3315 Xolder
3316 Xwindow
3317 wincmd p
3318 call g:Xsetlist([], 'f')
3319 call assert_equal(0, len(g:Xgetlist()))
3320 wincmd p
3321 call assert_equal(2, winnr('$'))
3322 call assert_equal(1, line('$'))
3323
3324 " After deleting the location list stack, if the location list window is
3325 " opened, then a new location list should be created. So opening the
3326 " location list window again should not create a new window.
3327 if a:cchar == 'l'
3328 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3329 wincmd p
3330 lopen
3331 call assert_equal(2, winnr('$'))
3332 endif
3333 Xclose
3334endfunc
3335
Bram Moolenaar74240d32017-12-10 15:26:15 +01003336" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003337func Test_qf_free()
3338 call XfreeTests('c')
3339 call XfreeTests('l')
3340endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003341
3342" Test for buffer overflow when parsing lines and adding new entries to
3343" the quickfix list.
3344func Test_bufoverflow()
3345 set efm=%f:%l:%m
3346 cgetexpr ['File1:100:' . repeat('x', 1025)]
3347
3348 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3349 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3350
3351 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003352 let lines =<< trim eval END
3353 Entering directory $"{repeat('a', 1006)}"
3354 File1:10:Hello World
3355 END
3356 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003357 set efm&vim
3358endfunc
3359
Bram Moolenaar875feea2017-06-11 16:07:51 +02003360" Tests for getting the quickfix stack size
3361func XsizeTests(cchar)
3362 call s:setup_commands(a:cchar)
3363
3364 call g:Xsetlist([], 'f')
3365 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003366 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3367 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003368
3369 Xexpr "File1:10:Line1"
3370 Xexpr "File2:20:Line2"
3371 Xexpr "File3:30:Line3"
3372 Xolder | Xolder
3373 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3374 call g:Xsetlist([], 'f')
3375
3376 Xexpr "File1:10:Line1"
3377 Xexpr "File2:20:Line2"
3378 Xexpr "File3:30:Line3"
3379 Xolder | Xolder
3380 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3381 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3382endfunc
3383
3384func Test_Qf_Size()
3385 call XsizeTests('c')
3386 call XsizeTests('l')
3387endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003388
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003389func Test_cclose_from_copen()
3390 augroup QF_Test
3391 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003392 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003393 augroup END
3394 copen
3395 augroup QF_Test
3396 au!
3397 augroup END
3398 augroup! QF_Test
3399endfunc
3400
Bram Moolenaar18141832017-06-25 21:17:25 +02003401func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003402 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003403 " event will be triggered.
3404 call test_override('starting', 1)
3405 augroup QF_Test
3406 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003407 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003408 augroup END
3409 copen
3410 augroup QF_Test
3411 au!
3412 augroup END
3413 augroup! QF_Test
3414 call test_override('starting', 0)
3415endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003416
Bram Moolenaar379fb762018-08-30 15:58:28 +02003417" Check that ":file" without an argument is possible even when "curbuf_lock"
3418" is set.
3419func Test_file_from_copen()
3420 " Works without argument.
3421 augroup QF_Test
3422 au!
3423 au FileType qf file
3424 augroup END
3425 copen
3426
3427 augroup QF_Test
3428 au!
3429 augroup END
3430 cclose
3431
3432 " Fails with argument.
3433 augroup QF_Test
3434 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003435 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003436 augroup END
3437 copen
3438 augroup QF_Test
3439 au!
3440 augroup END
3441 cclose
3442
3443 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003444endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003445
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003446func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003447 augroup QF_Test
3448 au!
3449 au FileType qf resize 5
3450 augroup END
3451 try
3452 " This should succeed without any exception. No other buffers are
3453 " involved in the autocmd.
3454 copen
3455 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003456 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003457 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003458 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003459 augroup! QF_Test
3460 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003461endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003462
Bram Moolenaard0fab102022-10-20 16:03:33 +01003463func Test_filetype_autocmd()
3464 " this changes the location list while it is in use to fill a buffer
3465 lexpr ''
3466 lopen
3467 augroup FT_loclist
3468 au FileType * call setloclist(0, [], 'f')
3469 augroup END
3470 silent! lolder
3471 lexpr ''
3472
3473 augroup FT_loclist
3474 au! FileType
3475 augroup END
3476endfunc
3477
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003478func Test_vimgrep_with_textlock()
3479 new
3480
zeertzjqcfe45652022-05-27 17:26:55 +01003481 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003482 " Check that vimgrep without jumping can be executed.
3483 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3484 normal ax
3485 let qflist = getqflist()
3486 call assert_true(len(qflist) > 0)
3487 call assert_match('RunTheTest', qflist[0].text)
3488 call setqflist([], 'r')
3489 au! InsertCharPre
3490
3491 " Check that vimgrepadd without jumping can be executed.
3492 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3493 normal ax
3494 let qflist = getqflist()
3495 call assert_true(len(qflist) > 0)
3496 call assert_match('RunTheTest', qflist[0].text)
3497 call setqflist([], 'r')
3498 au! InsertCharPre
3499
3500 " Check that lvimgrep without jumping can be executed.
3501 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3502 normal ax
3503 let qflist = getloclist(0)
3504 call assert_true(len(qflist) > 0)
3505 call assert_match('RunTheTest', qflist[0].text)
3506 call setloclist(0, [], 'r')
3507 au! InsertCharPre
3508
3509 " Check that lvimgrepadd without jumping can be executed.
3510 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3511 normal ax
3512 let qflist = getloclist(0)
3513 call assert_true(len(qflist) > 0)
3514 call assert_match('RunTheTest', qflist[0].text)
3515 call setloclist(0, [], 'r')
3516 au! InsertCharPre
3517
3518 " trying to jump will give an error
3519 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3520 call assert_fails('normal ax', 'E565:')
3521 au! InsertCharPre
3522
3523 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3524 call assert_fails('normal ax', 'E565:')
3525 au! InsertCharPre
3526
3527 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3528 call assert_fails('normal ax', 'E565:')
3529 au! InsertCharPre
3530
3531 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3532 call assert_fails('normal ax', 'E565:')
3533 au! InsertCharPre
3534
3535 bwipe!
3536endfunc
3537
Bram Moolenaara8788f42017-07-19 17:06:20 +02003538" Tests for the quickfix buffer b:changedtick variable
3539func Xchangedtick_tests(cchar)
3540 call s:setup_commands(a:cchar)
3541
3542 new | only
3543
3544 Xexpr "" | Xexpr "" | Xexpr ""
3545
3546 Xopen
3547 Xolder
3548 Xolder
3549 Xaddexpr "F1:10:Line10"
3550 Xaddexpr "F2:20:Line20"
3551 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3552 call g:Xsetlist([], 'f')
3553 call assert_equal(8, getbufvar('%', 'changedtick'))
3554 Xclose
3555endfunc
3556
3557func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003558 call Xchangedtick_tests('c')
3559 call Xchangedtick_tests('l')
3560endfunc
3561
3562" Tests for parsing an expression using setqflist()
3563func Xsetexpr_tests(cchar)
3564 call s:setup_commands(a:cchar)
3565
3566 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003567 call g:Xsetlist([], ' ', {'lines' : t})
3568 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003569
3570 let l = g:Xgetlist()
3571 call assert_equal(3, len(l))
3572 call assert_equal(20, l[1].lnum)
3573 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003574 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003575 let l = g:Xgetlist()
3576 call assert_equal(1, len(l))
3577 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003578 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3579 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003580
3581 call g:Xsetlist([], 'f')
3582 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003583 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3584 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3585 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3586 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003587 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3588 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003589
3590 " Adding entries using a custom efm
3591 set efm&
3592 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3593 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3594 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3595 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3596 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3597 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3598 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3599 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003600endfunc
3601
3602func Test_setexpr()
3603 call Xsetexpr_tests('c')
3604 call Xsetexpr_tests('l')
3605endfunc
3606
3607" Tests for per quickfix/location list directory stack
3608func Xmultidirstack_tests(cchar)
3609 call s:setup_commands(a:cchar)
3610
3611 call g:Xsetlist([], 'f')
3612 Xexpr "" | Xexpr ""
3613
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003614 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3615 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3616 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3617 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003618
3619 let l1 = g:Xgetlist({'nr':1, 'items':1})
3620 let l2 = g:Xgetlist({'nr':2, 'items':1})
3621 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3622 call assert_equal(3, l1.items[1].lnum)
3623 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3624 call assert_equal(5, l2.items[1].lnum)
3625endfunc
3626
3627func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003628 call mkdir('Xone/a', 'pR')
3629 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003630 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3631 call writefile(lines, 'Xone/a/one.txt')
3632 call writefile(lines, 'Xtwo/a/two.txt')
3633 let save_efm = &efm
3634 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3635
3636 call Xmultidirstack_tests('c')
3637 call Xmultidirstack_tests('l')
3638
3639 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003640endfunc
3641
3642" Tests for per quickfix/location list file stack
3643func Xmultifilestack_tests(cchar)
3644 call s:setup_commands(a:cchar)
3645
3646 call g:Xsetlist([], 'f')
3647 Xexpr "" | Xexpr ""
3648
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003649 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3650 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3651 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3652 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003653
3654 let l1 = g:Xgetlist({'nr':1, 'items':1})
3655 let l2 = g:Xgetlist({'nr':2, 'items':1})
3656 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3657 call assert_equal(3, l1.items[1].lnum)
3658 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3659 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003660
3661 " Test for start of a new error line in the same line where a previous
3662 " error line ends with a file stack.
3663 let efm_val = 'Error\ l%l\ in\ %f,'
3664 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003665 let lines =<< trim END
3666 (one.txt
3667 Error l4 in one.txt
3668 ) (two.txt
3669 Error l6 in two.txt
3670 )
3671 Error l8 in one.txt
3672 END
3673 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003674 call assert_equal(3, len(l.items))
3675 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3676 call assert_equal(4, l.items[0].lnum)
3677 call assert_equal('one.txt', l.items[0].text)
3678 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3679 call assert_equal(6, l.items[1].lnum)
3680 call assert_equal('two.txt', l.items[1].text)
3681 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3682 call assert_equal(8, l.items[2].lnum)
3683 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003684endfunc
3685
3686func Test_multifilestack()
3687 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003688 call writefile(lines, 'one.txt', 'D')
3689 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003690 let save_efm = &efm
3691 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3692
3693 call Xmultifilestack_tests('c')
3694 call Xmultifilestack_tests('l')
3695
3696 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003697endfunc
3698
3699" Tests for per buffer 'efm' setting
3700func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003701 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3702 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003703 set efm=%f#%l#%m
3704 new | only
3705 new
3706 setlocal efm=%f-%l-%m
3707 cfile one.txt
3708 wincmd w
3709 caddfile two.txt
3710
3711 let l = getqflist()
3712 call assert_equal(10, l[0].lnum)
3713 call assert_equal('Line20', l[1].text)
3714
3715 set efm&
3716 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003717endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003718
3719" Open multiple help windows using ":lhelpgrep
3720" This test used to crash Vim
3721func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003722 new | only
3723 lhelpgrep window
3724 lopen
3725 e#
3726 lhelpgrep buffer
3727 call assert_equal(3, winnr('$'))
3728 call assert_true(len(getloclist(1)) != 0)
3729 call assert_true(len(getloclist(2)) != 0)
3730 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003731endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003732
3733" Tests for adding new quickfix lists using setqflist()
3734func XaddQf_tests(cchar)
3735 call s:setup_commands(a:cchar)
3736
3737 " Create a new list using ' ' for action
3738 call g:Xsetlist([], 'f')
3739 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3740 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3741 call assert_equal(1, l.nr)
3742 call assert_equal('Test1', l.title)
3743
3744 " Create a new list using ' ' for action and '$' for 'nr'
3745 call g:Xsetlist([], 'f')
3746 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3747 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3748 call assert_equal(1, l.nr)
3749 call assert_equal('Test2', l.title)
3750
3751 " Create a new list using 'a' for action
3752 call g:Xsetlist([], 'f')
3753 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3754 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3755 call assert_equal(1, l.nr)
3756 call assert_equal('Test3', l.title)
3757
3758 " Create a new list using 'a' for action and '$' for 'nr'
3759 call g:Xsetlist([], 'f')
3760 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3761 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3762 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3763 call assert_equal(1, l.nr)
3764 call assert_equal('Test4', l.title)
3765
3766 " Adding a quickfix list should remove all the lists following the current
3767 " list.
3768 Xexpr "" | Xexpr "" | Xexpr ""
3769 silent! 10Xolder
3770 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3771 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3772 call assert_equal(2, l.nr)
3773 call assert_equal('Test5', l.title)
3774
3775 " Add a quickfix list using '$' as the list number.
3776 let lastqf = g:Xgetlist({'nr':'$'}).nr
3777 silent! 99Xolder
3778 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3779 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3780 call assert_equal(lastqf + 1, l.nr)
3781 call assert_equal('Test6', l.title)
3782
3783 " Add a quickfix list using 'nr' set to one more than the quickfix
3784 " list size.
3785 let lastqf = g:Xgetlist({'nr':'$'}).nr
3786 silent! 99Xolder
3787 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3788 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3789 call assert_equal(lastqf + 1, l.nr)
3790 call assert_equal('Test7', l.title)
3791
3792 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3793 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3794 silent! 99Xolder
3795 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3796 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3797 call assert_equal(10, l.nr)
3798 call assert_equal('Test8', l.title)
3799
3800 " Add a quickfix list using 'nr' set to a value greater than 10
3801 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3802
3803 " Try adding a quickfix list with 'nr' set to a value greater than the
3804 " quickfix list size but less than 10.
3805 call g:Xsetlist([], 'f')
3806 Xexpr "" | Xexpr "" | Xexpr ""
3807 silent! 99Xolder
3808 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3809
3810 " Add a quickfix list using 'nr' set to a some string or list
3811 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3812endfunc
3813
3814func Test_add_qf()
3815 call XaddQf_tests('c')
3816 call XaddQf_tests('l')
3817endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003818
3819" Test for getting the quickfix list items from some text without modifying
3820" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003821func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003822 call s:setup_commands(a:cchar)
3823 call g:Xsetlist([], 'f')
3824
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003825 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003826 call assert_equal(2, len(l))
3827 call assert_equal(30, l[1].lnum)
3828
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003829 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3830 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3831 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3832 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003833
Bram Moolenaar36538222017-09-02 19:51:44 +02003834 " Parse text using a custom efm
3835 set efm&
3836 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3837 call assert_equal('Line30', l[0].text)
3838 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3839 call assert_equal('File3:30:Line30', l[0].text)
3840 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3841 call assert_equal({}, l)
3842 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3843 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3844
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003845 " Make sure that the quickfix stack is not modified
3846 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3847endfunc
3848
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003849func Test_get_list_from_lines()
3850 call XgetListFromLines('c')
3851 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003852endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003853
3854" Tests for the quickfix list id
3855func Xqfid_tests(cchar)
3856 call s:setup_commands(a:cchar)
3857
3858 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003859 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003860 Xexpr ''
3861 let start_id = g:Xgetlist({'id' : 0}).id
3862 Xexpr '' | Xexpr ''
3863 Xolder
3864 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3865 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3866 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003867 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003868 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003869 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3870 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003871
3872 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3873 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003874 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003875 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3876 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3877 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3878
3879 let qfid = g:Xgetlist({'id':0, 'nr':0})
3880 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003881 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003882endfunc
3883
3884func Test_qf_id()
3885 call Xqfid_tests('c')
3886 call Xqfid_tests('l')
3887endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003888
3889func Xqfjump_tests(cchar)
3890 call s:setup_commands(a:cchar)
3891
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003892 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3893 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3894 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003895
3896 call g:Xsetlist([], 'f')
3897
3898 " Tests for
3899 " Jumping to a line using a pattern
3900 " Jumping to a column greater than the last column in a line
3901 " Jumping to a line greater than the last line in the file
3902 let l = []
3903 for i in range(1, 7)
3904 call add(l, {})
3905 endfor
3906 let l[0].filename='F1'
3907 let l[0].pattern='Line1'
3908 let l[1].filename='F2'
3909 let l[1].pattern='Line1'
3910 let l[2].filename='F3'
3911 let l[2].pattern='Line1'
3912 let l[3].filename='F3'
3913 let l[3].lnum=1
3914 let l[3].col=9
3915 let l[3].vcol=1
3916 let l[4].filename='F3'
3917 let l[4].lnum=99
3918 let l[5].filename='F3'
3919 let l[5].lnum=1
3920 let l[5].col=99
3921 let l[5].vcol=1
3922 let l[6].filename='F3'
3923 let l[6].pattern='abcxyz'
3924
3925 call g:Xsetlist([], ' ', {'items' : l})
3926 Xopen | only
3927 2Xnext
3928 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003929 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003930 Xnext
3931 call assert_equal(7, col('.'))
3932 Xnext
3933 call assert_equal(2, line('.'))
3934 Xnext
3935 call assert_equal(9, col('.'))
3936 2
3937 Xnext
3938 call assert_equal(2, line('.'))
3939
3940 if a:cchar == 'l'
3941 " When jumping to a location list entry in the location list window and
3942 " no usable windows are available, then a new window should be opened.
3943 enew! | new | only
3944 call g:Xsetlist([], 'f')
3945 setlocal buftype=nofile
3946 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003947 let lines =<< trim END
3948 F1:1:1:Line1
3949 F1:2:2:Line2
3950 F2:1:1:Line1
3951 F2:2:2:Line2
3952 F3:1:1:Line1
3953 F3:2:2:Line2
3954 END
3955 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003956 Xopen
3957 let winid = win_getid()
3958 wincmd p
3959 close
3960 call win_gotoid(winid)
3961 Xnext
3962 call assert_equal(3, winnr('$'))
3963 call assert_equal(1, winnr())
3964 call assert_equal(2, line('.'))
3965
3966 " When jumping to an entry in the location list window and the window
3967 " associated with the location list is not present and a window containing
3968 " the file is already present, then that window should be used.
3969 close
3970 belowright new
3971 call g:Xsetlist([], 'f')
3972 edit F3
3973 call win_gotoid(winid)
3974 Xlast
3975 call assert_equal(3, winnr())
3976 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3977 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3978 endif
3979
3980 " Cleanup
3981 enew!
3982 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01003983endfunc
3984
3985func Test_qfjump()
3986 call Xqfjump_tests('c')
3987 call Xqfjump_tests('l')
3988endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003989
3990" Tests for the getqflist() and getloclist() functions when the list is not
3991" present or is empty
3992func Xgetlist_empty_tests(cchar)
3993 call s:setup_commands(a:cchar)
3994
3995 " Empty quickfix stack
3996 call g:Xsetlist([], 'f')
3997 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3998 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3999 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4000 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4001 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4002 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4003 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4004 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004005 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004006 if a:cchar == 'c'
4007 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004008 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004009 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4010 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004011 else
4012 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4013 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004014 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004015 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004016 \ g:Xgetlist({'all' : 0}))
4017 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004018
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004019 " Quickfix window with empty stack
4020 silent! Xopen
4021 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004022 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004023 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4024 Xclose
4025
Bram Moolenaara6d48492017-12-12 22:45:31 +01004026 " Empty quickfix list
4027 Xexpr ""
4028 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4029 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4030 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4031 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4032 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4033 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4034 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4035 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004036 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004037
4038 let qfid = g:Xgetlist({'id' : 0}).id
4039 call g:Xsetlist([], 'f')
4040
4041 " Non-existing quickfix identifier
4042 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4043 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4044 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4045 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4046 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4047 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4048 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4049 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004050 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004051 if a:cchar == 'c'
4052 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4053 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004054 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004055 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4056 else
4057 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4058 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004059 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4060 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004061 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4062 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004063
4064 " Non-existing quickfix list number
4065 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4066 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4067 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4068 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4069 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4070 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4071 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4072 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004073 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004074 if a:cchar == 'c'
4075 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4076 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004077 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4078 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004079 else
4080 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4081 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004082 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4083 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004084 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004085endfunc
4086
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004087func Test_empty_list_quickfixtextfunc()
4088 " This was crashing. Can only reproduce by running it in a separate Vim
4089 " instance.
4090 let lines =<< trim END
4091 func s:Func(o)
4092 cgetexpr '0'
4093 endfunc
4094 cope
4095 let &quickfixtextfunc = 's:Func'
4096 cgetfile [ex
4097 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004098 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004099 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004100endfunc
4101
Bram Moolenaara6d48492017-12-12 22:45:31 +01004102func Test_getqflist()
4103 call Xgetlist_empty_tests('c')
4104 call Xgetlist_empty_tests('l')
4105endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004106
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004107func Test_getqflist_invalid_nr()
4108 " The following commands used to crash Vim
4109 cexpr ""
4110 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4111
4112 " Cleanup
4113 call setqflist([], 'r')
4114endfunc
4115
Bram Moolenaarb254af32017-12-18 19:48:58 +01004116" Tests for the quickfix/location list changedtick
4117func Xqftick_tests(cchar)
4118 call s:setup_commands(a:cchar)
4119
4120 call g:Xsetlist([], 'f')
4121
4122 Xexpr "F1:10:Line10"
4123 let qfid = g:Xgetlist({'id' : 0}).id
4124 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4125 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4126 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4127 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4128 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4129 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4130 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4131 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4132 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4133
4134 enew!
4135 call append(0, ["F5:50:L50", "F6:60:L60"])
4136 Xaddbuffer
4137 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4138 enew!
4139
4140 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4141 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4142 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4143 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4144 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4145 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4146 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4147 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4148 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4149 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4150 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4151
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004152 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004153 Xfile Xone
4154 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4155 Xaddfile Xone
4156 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4157
4158 " Test case for updating a non-current quickfix list
4159 call g:Xsetlist([], 'f')
4160 Xexpr "F1:1:L1"
4161 Xexpr "F2:2:L2"
4162 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4163 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4164 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004165endfunc
4166
4167func Test_qf_tick()
4168 call Xqftick_tests('c')
4169 call Xqftick_tests('l')
4170endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004171
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004172" Test helpgrep with lang specifier
4173func Xtest_helpgrep_with_lang_specifier(cchar)
4174 call s:setup_commands(a:cchar)
4175 Xhelpgrep Vim@en
4176 call assert_equal('help', &filetype)
4177 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4178 new | only
4179endfunc
4180
4181func Test_helpgrep_with_lang_specifier()
4182 call Xtest_helpgrep_with_lang_specifier('c')
4183 call Xtest_helpgrep_with_lang_specifier('l')
4184endfunc
4185
Bram Moolenaar12237442017-12-19 12:38:52 +01004186" The following test used to crash Vim.
4187" Open the location list window and close the regular window associated with
4188" the location list. When the garbage collection runs now, it incorrectly
4189" marks the location list context as not in use and frees the context.
4190func Test_ll_window_ctx()
4191 call setloclist(0, [], 'f')
4192 call setloclist(0, [], 'a', {'context' : []})
4193 lopen | only
4194 call test_garbagecollect_now()
4195 echo getloclist(0, {'context' : 1}).context
4196 enew | only
4197endfunc
4198
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004199" The following test used to crash vim
4200func Test_lfile_crash()
4201 sp Xtest
4202 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004203 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004204 au! QuickFixCmdPre
4205endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004206
4207" The following test used to crash vim
4208func Test_lbuffer_crash()
4209 sv Xtest
4210 augroup QF_Test
4211 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004212 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004213 augroup END
4214 lbuffer
4215 augroup QF_Test
4216 au!
4217 augroup END
4218endfunc
4219
4220" The following test used to crash vim
4221func Test_lexpr_crash()
4222 augroup QF_Test
4223 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004224 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004225 augroup END
4226 lexpr ""
4227 augroup QF_Test
4228 au!
4229 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004230
Bram Moolenaar3c097222017-12-21 20:54:49 +01004231 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004232 augroup QF_Test
4233 au!
4234 au BufNew * call setloclist(0, [], 'f')
4235 augroup END
4236 lexpr 'x:1:x'
4237 augroup QF_Test
4238 au!
4239 augroup END
4240
4241 enew | only
4242 lexpr ''
4243 lopen
4244 augroup QF_Test
4245 au!
4246 au FileType * call setloclist(0, [], 'f')
4247 augroup END
4248 lexpr ''
4249 augroup QF_Test
4250 au!
4251 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004252endfunc
4253
4254" The following test used to crash Vim
4255func Test_lvimgrep_crash()
4256 sv Xtest
4257 augroup QF_Test
4258 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004259 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004260 augroup END
4261 lvimgrep quickfix test_quickfix.vim
4262 augroup QF_Test
4263 au!
4264 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004265
4266 new | only
4267 augroup QF_Test
4268 au!
4269 au BufEnter * call setloclist(0, [], 'r')
4270 augroup END
4271 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4272 augroup QF_Test
4273 au!
4274 augroup END
4275
Bram Moolenaar3c097222017-12-21 20:54:49 +01004276 enew | only
4277endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004278
Bram Moolenaar2573af32020-03-14 17:21:34 +01004279func Test_lvimgrep_crash2()
4280 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004281 call assert_fails('lvimgrep x x', 'E471:')
4282 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004283
4284 au! BufNewFile
4285endfunc
4286
Bram Moolenaarde046542017-12-26 13:53:11 +01004287" Test for the position of the quickfix and location list window
4288func Test_qfwin_pos()
4289 " Open two windows
4290 new | only
4291 new
4292 cexpr ['F1:10:L10']
4293 copen
4294 " Quickfix window should be the bottom most window
4295 call assert_equal(3, winnr())
4296 close
4297 " Open at the very top
4298 wincmd t
4299 topleft copen
4300 call assert_equal(1, winnr())
4301 close
4302 " open left of the current window
4303 wincmd t
4304 below new
4305 leftabove copen
4306 call assert_equal(2, winnr())
4307 close
4308 " open right of the current window
4309 rightbelow copen
4310 call assert_equal(3, winnr())
4311 close
4312endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004313
4314" Tests for quickfix/location lists changed by autocommands when
4315" :vimgrep/:lvimgrep commands are running.
4316func Test_vimgrep_autocmd()
4317 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004318 call writefile(['stars'], 'Xtest1.txt', 'D')
4319 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004320
4321 " Test 1:
4322 " When searching for a pattern using :vimgrep, if the quickfix list is
4323 " changed by an autocmd, the results should be added to the correct quickfix
4324 " list.
4325 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4326 silent vimgrep stars Xtest*.txt
4327 call assert_equal(1, getqflist({'nr' : 0}).nr)
4328 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4329 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4330 au! BufRead Xtest2.txt
4331
4332 " Test 2:
4333 " When searching for a pattern using :vimgrep, if the quickfix list is
4334 " freed, then a error should be given.
4335 silent! %bwipe!
4336 call setqflist([], 'f')
4337 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4338 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4339 au! BufRead Xtest2.txt
4340
4341 " Test 3:
4342 " When searching for a pattern using :lvimgrep, if the location list is
4343 " freed, then the command should error out.
4344 silent! %bwipe!
4345 let g:save_winid = win_getid()
4346 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4347 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4348 au! BufRead Xtest2.txt
4349
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004350 call setqflist([], 'f')
4351endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004352
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004353" Test for an autocmd changing the current directory when running vimgrep
4354func Xvimgrep_autocmd_cd(cchar)
4355 call s:setup_commands(a:cchar)
4356
4357 %bwipe
4358 let save_cwd = getcwd()
4359
4360 augroup QF_Test
4361 au!
4362 autocmd BufRead * silent cd %:p:h
4363 augroup END
4364
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004365 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004366 let l = g:Xgetlist()
4367 call assert_equal('f1.txt', bufname(l[0].bufnr))
4368 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4369
4370 augroup QF_Test
4371 au!
4372 augroup END
4373
4374 exe 'cd ' . save_cwd
4375endfunc
4376
4377func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004378 call mkdir('Xgrepdir/a', 'pR')
4379 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004380 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4381 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004382 call Xvimgrep_autocmd_cd('c')
4383 call Xvimgrep_autocmd_cd('l')
4384 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004385endfunc
4386
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004387" The following test used to crash Vim
4388func Test_lhelpgrep_autocmd()
4389 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004390 augroup QF_Test
4391 au!
4392 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4393 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004394 lhelpgrep buffer
4395 call assert_equal('help', &filetype)
4396 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4397 lhelpgrep tabpage
4398 call assert_equal('help', &filetype)
4399 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004400 augroup QF_Test
4401 au!
4402 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004403
4404 new | only
4405 augroup QF_Test
4406 au!
4407 au BufEnter * call setqflist([], 'f')
4408 augroup END
4409 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004410 " run the test with a help window already open
4411 help
4412 wincmd w
4413 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004414 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004415 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004416 augroup END
4417
4418 new | only
4419 augroup QF_Test
4420 au!
4421 au BufEnter * call setqflist([], 'r')
4422 augroup END
4423 call assert_fails('helpgrep quickfix', 'E925:')
4424 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004425 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004426 augroup END
4427
4428 new | only
4429 augroup QF_Test
4430 au!
4431 au BufEnter * call setloclist(0, [], 'r')
4432 augroup END
4433 call assert_fails('lhelpgrep quickfix', 'E926:')
4434 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004435 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004436 augroup END
4437
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004438 " Replace the contents of a help window location list when it is still in
4439 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004440 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004441 lhelpgrep quickfix
4442 wincmd w
4443 augroup QF_Test
4444 au!
4445 autocmd WinEnter * call setloclist(0, [], 'r')
4446 augroup END
4447 call assert_fails('lhelpgrep win_getid', 'E926:')
4448 augroup QF_Test
4449 au!
4450 augroup END
4451
4452 %bw!
4453endfunc
4454
4455" The following test used to crash Vim
4456func Test_lhelpgrep_autocmd_free_loclist()
4457 %bw!
4458 lhelpgrep quickfix
4459 wincmd w
4460 augroup QF_Test
4461 au!
4462 autocmd WinEnter * call setloclist(0, [], 'f')
4463 augroup END
4464 lhelpgrep win_getid
4465 wincmd w
4466 wincmd w
4467 wincmd w
4468 augroup QF_Test
4469 au!
4470 augroup END
4471 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004472endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004473
4474" Test for shortening/simplifying the file name when opening the
4475" quickfix window or when displaying the quickfix list
4476func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004477 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004478 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004479 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004480 let fname = getcwd() . '/test_quickfix.vim'
4481 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4482 call assert_equal(fname, bufname('test_quickfix.vim'))
4483 " Opening the quickfix window should simplify the file path
4484 cwindow
4485 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4486 cclose
4487 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004488 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004489 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4490 call assert_equal(fname, bufname('test_quickfix.vim'))
4491 " Displaying the quickfix list should simplify the file path
4492 silent! clist
4493 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004494 " Add a few entries for the same file with different paths and check whether
4495 " the buffer name is shortened
4496 %bwipe
4497 call setqflist([], 'f')
4498 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4499 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4500 \ {'filename' : fname, 'lnum' : 30}], ' ')
4501 copen
4502 call assert_equal(['test_quickfix.vim|10| ',
4503 \ 'test_quickfix.vim|20| ',
4504 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4505 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004506endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004507
4508" Quickfix title tests
4509" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4510" Otherwise due to indentation, the title is set with spaces at the beginning
4511" of the command.
4512func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004513 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004514
4515 " :cexpr
4516 exe "cexpr readfile('Xerr')"
4517 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4518
4519 " :cgetexpr
4520 exe "cgetexpr readfile('Xerr')"
4521 call assert_equal(":cgetexpr readfile('Xerr')",
4522 \ getqflist({'title' : 1}).title)
4523
4524 " :caddexpr
4525 call setqflist([], 'f')
4526 exe "caddexpr readfile('Xerr')"
4527 call assert_equal(":caddexpr readfile('Xerr')",
4528 \ getqflist({'title' : 1}).title)
4529
4530 " :cbuffer
4531 new Xerr
4532 exe "cbuffer"
4533 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4534
4535 " :cgetbuffer
4536 edit Xerr
4537 exe "cgetbuffer"
4538 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4539
4540 " :caddbuffer
4541 call setqflist([], 'f')
4542 edit Xerr
4543 exe "caddbuffer"
4544 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4545
4546 " :cfile
4547 exe "cfile Xerr"
4548 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4549
4550 " :cgetfile
4551 exe "cgetfile Xerr"
4552 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4553
4554 " :caddfile
4555 call setqflist([], 'f')
4556 exe "caddfile Xerr"
4557 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4558
4559 " :grep
4560 set grepprg=internal
4561 exe "grep F1 Xerr"
4562 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4563
4564 " :grepadd
4565 call setqflist([], 'f')
4566 exe "grepadd F1 Xerr"
4567 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4568 set grepprg&vim
4569
4570 " :vimgrep
4571 exe "vimgrep F1 Xerr"
4572 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4573
4574 " :vimgrepadd
4575 call setqflist([], 'f')
4576 exe "vimgrepadd F1 Xerr"
4577 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4578
4579 call setqflist(['F1:10:L10'], ' ')
4580 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4581
4582 call setqflist([], 'f')
4583 call setqflist(['F1:10:L10'], 'a')
4584 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4585
4586 call setqflist([], 'f')
4587 call setqflist(['F1:10:L10'], 'r')
4588 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4589
4590 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004591
4592 call setqflist([], ' ', {'title' : 'Errors'})
4593 copen
4594 call assert_equal('Errors', w:quickfix_title)
4595 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4596 call assert_equal('Errors', w:quickfix_title)
4597 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004598
4599 " Switching to another quickfix list in one tab page should update the
4600 " quickfix window title and statusline in all the other tab pages also
4601 call setqflist([], 'f')
4602 %bw!
4603 cgetexpr ['file_one:1:1: error in the first quickfix list']
4604 call setqflist([], 'a', {'title': 'first quickfix list'})
4605 cgetexpr ['file_two:2:1: error in the second quickfix list']
4606 call setqflist([], 'a', {'title': 'second quickfix list'})
4607 copen
4608 wincmd t
4609 tabnew two
4610 copen
4611 wincmd t
4612 colder
4613 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4614 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4615 call assert_equal(1, tabpagewinnr(1))
4616 call assert_equal(1, tabpagewinnr(2))
4617 tabnew
4618 call setqflist([], 'a', {'title': 'new quickfix title'})
4619 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4620 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4621 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004622endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004623
4624func Test_lbuffer_with_bwipe()
4625 new
4626 new
4627 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004628 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004629 augroup END
4630 lbuffer
4631 augroup nasty
4632 au!
4633 augroup END
4634endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004635
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004636" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4637" running
4638func Xexpr_acmd_freelist(cchar)
4639 call s:setup_commands(a:cchar)
4640
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004641 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004642 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004643 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004644 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004645 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004646 augroup nasty
4647 au!
4648 augroup END
4649endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004650
4651func Test_cexpr_acmd_freelist()
4652 call Xexpr_acmd_freelist('c')
4653 call Xexpr_acmd_freelist('l')
4654endfunc
4655
4656" Test for commands that create a new quickfix/location list and jump to the
4657" first error automatically.
4658func Xjumpto_first_error_test(cchar)
4659 call s:setup_commands(a:cchar)
4660
4661 call s:create_test_file('Xtestfile1')
4662 call s:create_test_file('Xtestfile2')
4663 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4664
4665 " Test for cexpr/lexpr
4666 enew
4667 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004668 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004669 call assert_equal(2, line('.'))
4670
4671 " Test for cfile/lfile
4672 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004673 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004674 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004675 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004676 call assert_equal(2, line('.'))
4677
4678 " Test for cbuffer/lbuffer
4679 edit Xerr
4680 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004681 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004682 call assert_equal(2, line('.'))
4683
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004684 call delete('Xtestfile1')
4685 call delete('Xtestfile2')
4686endfunc
4687
4688func Test_jumpto_first_error()
4689 call Xjumpto_first_error_test('c')
4690 call Xjumpto_first_error_test('l')
4691endfunc
4692
4693" Test for a quickfix autocmd changing the quickfix/location list before
4694" jumping to the first error in the new list.
4695func Xautocmd_changelist(cchar)
4696 call s:setup_commands(a:cchar)
4697
4698 " Test for cfile/lfile
4699 call s:create_test_file('Xtestfile1')
4700 call s:create_test_file('Xtestfile2')
4701 Xexpr 'Xtestfile1:2:Line2'
4702 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004703 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004704 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004705 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004706 call assert_equal(4, line('.'))
4707 autocmd! QuickFixCmdPost
4708
4709 " Test for cbuffer/lbuffer
4710 call g:Xsetlist([], 'f')
4711 Xexpr 'Xtestfile1:2:Line2'
4712 autocmd QuickFixCmdPost * Xolder
4713 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4714 edit Xerr
4715 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004716 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004717 call assert_equal(4, line('.'))
4718 autocmd! QuickFixCmdPost
4719
4720 " Test for cexpr/lexpr
4721 call g:Xsetlist([], 'f')
4722 Xexpr 'Xtestfile1:2:Line2'
4723 autocmd QuickFixCmdPost * Xolder
4724 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004725 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004726 call assert_equal(4, line('.'))
4727 autocmd! QuickFixCmdPost
4728
Bram Moolenaar851332e2018-07-03 19:16:00 +02004729 " The grepprg may not be set on non-Unix systems
4730 if has('unix')
4731 " Test for grep/lgrep
4732 call g:Xsetlist([], 'f')
4733 Xexpr 'Xtestfile1:2:Line2'
4734 autocmd QuickFixCmdPost * Xolder
4735 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004736 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004737 call assert_equal(5, line('.'))
4738 autocmd! QuickFixCmdPost
4739 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004740
4741 " Test for vimgrep/lvimgrep
4742 call g:Xsetlist([], 'f')
4743 Xexpr 'Xtestfile1:2:Line2'
4744 autocmd QuickFixCmdPost * Xolder
4745 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004746 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004747 call assert_equal(5, line('.'))
4748 autocmd! QuickFixCmdPost
4749
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004750 " Test for autocommands clearing the quickfix list before jumping to the
4751 " first error. This should not result in an error
4752 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4753 let v:errmsg = ''
4754 " Test for cfile/lfile
4755 Xfile Xerr
4756 call assert_true(v:errmsg !~# 'E42:')
4757 " Test for cbuffer/lbuffer
4758 edit Xerr
4759 Xbuffer
4760 call assert_true(v:errmsg !~# 'E42:')
4761 " Test for cexpr/lexpr
4762 Xexpr 'Xtestfile2:4:Line4'
4763 call assert_true(v:errmsg !~# 'E42:')
4764 " Test for grep/lgrep
4765 " The grepprg may not be set on non-Unix systems
4766 if has('unix')
4767 silent Xgrep Line5 Xtestfile2
4768 call assert_true(v:errmsg !~# 'E42:')
4769 endif
4770 " Test for vimgrep/lvimgrep
4771 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4772 autocmd! QuickFixCmdPost
4773
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004774 call delete('Xtestfile1')
4775 call delete('Xtestfile2')
4776endfunc
4777
4778func Test_autocmd_changelist()
4779 call Xautocmd_changelist('c')
4780 call Xautocmd_changelist('l')
4781endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004782
4783" Tests for the ':filter /pat/ clist' command
4784func Test_filter_clist()
4785 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4786 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4787 \ split(execute('filter /Line 15/ clist'), "\n"))
4788 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4789 \ split(execute('filter /Xfile1/ clist'), "\n"))
4790 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4791
4792 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4793 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4794 call assert_equal([' 2 pqr:pat2: '],
4795 \ split(execute('filter /pqr/ clist'), "\n"))
4796 call assert_equal([' 1 abc:pat1: '],
4797 \ split(execute('filter /pat1/ clist'), "\n"))
4798endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004799
4800" Tests for the "CTRL-W <CR>" command.
4801func Xview_result_split_tests(cchar)
4802 call s:setup_commands(a:cchar)
4803
4804 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4805 call g:Xsetlist([])
4806 Xopen
4807 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004808 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004809 call assert_equal(l:win_count, winnr('$'))
4810 Xclose
4811endfunc
4812
4813func Test_view_result_split()
4814 call Xview_result_split_tests('c')
4815 call Xview_result_split_tests('l')
4816endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004817
4818" Test that :cc sets curswant
4819func Test_curswant()
4820 helpgrep quickfix
4821 normal! llll
4822 1cc
4823 call assert_equal(getcurpos()[4], virtcol('.'))
4824 cclose | helpclose
4825endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004826
4827" Test for opening a file from the quickfix window using CTRL-W <Enter>
4828" doesn't leave an empty buffer around.
4829func Test_splitview()
4830 call s:create_test_file('Xtestfile1')
4831 call s:create_test_file('Xtestfile2')
4832 new | only
4833 let last_bufnr = bufnr('Test_sv_1', 1)
4834 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4835 cgetexpr l
4836 copen
4837 let numbufs = len(getbufinfo())
4838 exe "normal \<C-W>\<CR>"
4839 copen
4840 exe "normal j\<C-W>\<CR>"
4841 " Make sure new empty buffers are not created
4842 call assert_equal(numbufs, len(getbufinfo()))
4843 " Creating a new buffer should use the next available buffer number
4844 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4845 bwipe Test_sv_1
4846 bwipe Test_sv_2
4847 new | only
4848
4849 " When split opening files from location list window, make sure that two
4850 " windows doesn't refer to the same location list
4851 lgetexpr l
4852 let locid = getloclist(0, {'id' : 0}).id
4853 lopen
4854 exe "normal \<C-W>\<CR>"
4855 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4856 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4857 new | only
4858
4859 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004860 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004861 lhelpgrep window
4862 let locid = getloclist(0, {'id' : 0}).id
4863 lwindow
4864 exe "normal j\<C-W>\<CR>"
4865 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4866 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4867 new | only
4868
Bram Moolenaar406cd902020-02-18 21:54:41 +01004869 " Using :split or :vsplit from a quickfix window should behave like a :new
4870 " or a :vnew command
4871 copen
4872 split
4873 call assert_equal(3, winnr('$'))
4874 let l = getwininfo()
4875 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4876 close
4877 copen
4878 vsplit
4879 let l = getwininfo()
4880 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4881 new | only
4882
Bram Moolenaarb2443732018-11-11 22:50:27 +01004883 call delete('Xtestfile1')
4884 call delete('Xtestfile2')
4885endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004886
4887" Test for parsing entries using visual screen column
4888func Test_viscol()
4889 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004890 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004891 edit Xfile1
4892
4893 " Use byte offset for column number
4894 set efm&
4895 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4896 call assert_equal([5, 8], [col('.'), virtcol('.')])
4897 cnext
4898 call assert_equal([9, 12], [col('.'), virtcol('.')])
4899 cnext
4900 call assert_equal([14, 20], [col('.'), virtcol('.')])
4901
4902 " Use screen column offset for column number
4903 set efm=%f:%l:%v:%m
4904 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4905 call assert_equal([5, 8], [col('.'), virtcol('.')])
4906 cnext
4907 call assert_equal([9, 12], [col('.'), virtcol('.')])
4908 cnext
4909 call assert_equal([14, 20], [col('.'), virtcol('.')])
4910 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4911 call assert_equal([5, 8], [col('.'), virtcol('.')])
4912 cnext
4913 call assert_equal([10, 16], [col('.'), virtcol('.')])
4914 cnext
4915 call assert_equal([14, 20], [col('.'), virtcol('.')])
4916
4917 enew
4918 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4919
4920 " Use byte offset for column number
4921 set efm&
4922 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4923 call assert_equal([8, 10], [col('.'), virtcol('.')])
4924 cnext
4925 call assert_equal([11, 17], [col('.'), virtcol('.')])
4926 cnext
4927 call assert_equal([16, 25], [col('.'), virtcol('.')])
4928
4929 " Use screen column offset for column number
4930 set efm=%f:%l:%v:%m
4931 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4932 call assert_equal([8, 10], [col('.'), virtcol('.')])
4933 cnext
4934 call assert_equal([11, 17], [col('.'), virtcol('.')])
4935 cnext
4936 call assert_equal([16, 25], [col('.'), virtcol('.')])
4937
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004938 " Use screen column number with a multi-line error message
4939 enew
4940 call writefile(["à test"], 'Xfile1')
4941 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4942 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4943 call assert_equal('Xfile1', @%)
4944 call assert_equal([0, 1, 4, 0], getpos('.'))
4945
4946 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4947 " does not break this
4948 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4949 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4950 call assert_equal('Xfile1', @%)
4951 call assert_equal([0, 1, 3, 0], getpos('.'))
4952
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004953 enew | only
4954 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004955endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004956
4957" Test for the quickfix window buffer
4958func Xqfbuf_test(cchar)
4959 call s:setup_commands(a:cchar)
4960
4961 " Quickfix buffer should be reused across closing and opening a quickfix
4962 " window
4963 Xexpr "F1:10:Line10"
4964 Xopen
4965 let qfbnum = bufnr('')
4966 Xclose
4967 " Even after the quickfix window is closed, the buffer should be loaded
4968 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004969 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004970 Xopen
4971 " Buffer should be reused when opening the window again
4972 call assert_equal(qfbnum, bufnr(''))
4973 Xclose
4974
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004975 " When quickfix buffer is wiped out, getqflist() should return 0
4976 %bw!
4977 Xexpr ""
4978 Xopen
4979 bw!
4980 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4981
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004982 if a:cchar == 'l'
4983 %bwipe
4984 " For a location list, when both the file window and the location list
4985 " window for the list are closed, then the buffer should be freed.
4986 new | only
4987 lexpr "F1:10:Line10"
4988 let wid = win_getid()
4989 lopen
4990 let qfbnum = bufnr('')
4991 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4992 close
4993 " When the location list window is closed, the buffer name should not
4994 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004995 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004996 call assert_true(bufloaded(qfbnum))
4997
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004998 " After deleting a location list buffer using ":bdelete", opening the
4999 " location list window should mark the buffer as a location list buffer.
5000 exe "bdelete " . qfbnum
5001 lopen
5002 call assert_equal("quickfix", &buftype)
5003 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5004 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5005 call assert_false(&swapfile)
5006 lclose
5007
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005008 " When the location list is cleared for the window, the buffer should be
5009 " removed
5010 call setloclist(0, [], 'f')
5011 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005012 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005013
5014 " When the location list is freed with the location list window open, the
5015 " location list buffer should not be lost. It should be reused when the
5016 " location list is again populated.
5017 lexpr "F1:10:Line10"
5018 lopen
5019 let wid = win_getid()
5020 let qfbnum = bufnr('')
5021 wincmd p
5022 call setloclist(0, [], 'f')
5023 lexpr "F1:10:Line10"
5024 lopen
5025 call assert_equal(wid, win_getid())
5026 call assert_equal(qfbnum, bufnr(''))
5027 lclose
5028
5029 " When the window with the location list is closed, the buffer should be
5030 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005031 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005032 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005033 endif
5034endfunc
5035
5036func Test_qfbuf()
5037 call Xqfbuf_test('c')
5038 call Xqfbuf_test('l')
5039endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005040
5041" If there is an autocmd to use only one window, then opening the location
5042" list window used to crash Vim.
5043func Test_winonly_autocmd()
5044 call s:create_test_file('Xtest1')
5045 " Autocmd to show only one Vim window at a time
5046 autocmd WinEnter * only
5047 new
5048 " Load the location list
5049 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5050 let loclistid = getloclist(0, {'id' : 0}).id
5051 " Open the location list window. Only this window will be shown and the file
5052 " window is closed.
5053 lopen
5054 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5055 " Jump to an entry in the location list and make sure that the cursor is
5056 " positioned correctly.
5057 ll 3
5058 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005059 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005060 call assert_equal(15, line('.'))
5061 " Cleanup
5062 autocmd! WinEnter
5063 new | only
5064 call delete('Xtest1')
5065endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005066
5067" Test to make sure that an empty quickfix buffer is not reused for loading
5068" a normal buffer.
5069func Test_empty_qfbuf()
5070 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005071 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005072 call setqflist([], 'f')
5073 copen | only
5074 let qfbuf = bufnr('')
5075 edit Xfile1
5076 call assert_notequal(qfbuf, bufnr(''))
5077 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005078endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005079
5080" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005081" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005082func Xtest_below(cchar)
5083 call s:setup_commands(a:cchar)
5084
5085 " No quickfix/location list
5086 call assert_fails('Xbelow', 'E42:')
5087 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005088 call assert_fails('Xbefore', 'E42:')
5089 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005090
5091 " Empty quickfix/location list
5092 call g:Xsetlist([])
5093 call assert_fails('Xbelow', 'E42:')
5094 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005095 call assert_fails('Xbefore', 'E42:')
5096 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005097
5098 call s:create_test_file('X1')
5099 call s:create_test_file('X2')
5100 call s:create_test_file('X3')
5101 call s:create_test_file('X4')
5102
5103 " Invalid entries
5104 edit X1
5105 call g:Xsetlist(["E1", "E2"])
5106 call assert_fails('Xbelow', 'E42:')
5107 call assert_fails('Xabove', 'E42:')
5108 call assert_fails('3Xbelow', 'E42:')
5109 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005110 call assert_fails('Xbefore', 'E42:')
5111 call assert_fails('Xafter', 'E42:')
5112 call assert_fails('3Xbefore', 'E42:')
5113 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005114
5115 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005116 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 +02005117 edit +7 X2
5118 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005119 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005120 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005121 normal 7G
5122 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005123 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005124 call assert_fails('Xbefore', 'E553:')
5125
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005126 normal 2j
5127 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005128 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005129 normal 7G
5130 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005131 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005132
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005133 " Last error in this file
5134 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005135 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005136 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005137 normal gg
5138 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005139 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005140 call assert_fails('Xafter', 'E553:')
5141
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005142 " First error in this file
5143 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005144 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005145 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005146 normal G
5147 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005148 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005149 call assert_fails('Xbefore', 'E553:')
5150
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005151 normal gg
5152 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005153 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005154 normal gg
5155 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005156 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005157
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005158 normal G
5159 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005160 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005161 normal G
5162 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005163 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005164
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005165 edit X4
5166 call assert_fails('Xabove', 'E42:')
5167 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005168 call assert_fails('Xbefore', 'E42:')
5169 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005170 if a:cchar == 'l'
5171 " If a buffer has location list entries from some other window but not
5172 " from the current window, then the commands should fail.
5173 edit X1 | split | call setloclist(0, [], 'f')
5174 call assert_fails('Xabove', 'E776:')
5175 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005176 call assert_fails('Xbefore', 'E776:')
5177 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005178 close
5179 endif
5180
5181 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005182 let lines =<< trim END
5183 X1:5:L5
5184 X2:5:1:L5_1
5185 X2:5:2:L5_2
5186 X2:5:3:L5_3
5187 X2:10:1:L10_1
5188 X2:10:2:L10_2
5189 X2:10:3:L10_3
5190 X2:15:1:L15_1
5191 X2:15:2:L15_2
5192 X2:15:3:L15_3
5193 X3:3:L3
5194 END
5195 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005196 edit +1 X2
5197 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005198 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005199 normal 1G
5200 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005201 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005202
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005203 normal gg
5204 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005205 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005206 normal gg
5207 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005208 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005209
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005210 normal G
5211 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005212 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005213 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005214 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005215 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005216
5217 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005218 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005219 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005220 normal G
5221 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005222 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005223
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005224 normal 10G
5225 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005226 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005227 normal 10G$
5228 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005229 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005230
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005231 normal 10G
5232 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005233 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005234 normal 9G
5235 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005236 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005237
5238 " Invalid range
5239 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005240 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005241 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005242 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005243 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005244 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005245 endif
5246
5247 call delete('X1')
5248 call delete('X2')
5249 call delete('X3')
5250 call delete('X4')
5251endfunc
5252
5253func Test_cbelow()
5254 call Xtest_below('c')
5255 call Xtest_below('l')
5256endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005257
5258func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005259 let commands =<< trim END
5260 cNext
5261 cNfile
5262 cabove
5263 cbelow
5264 cfirst
5265 clast
5266 cnewer
5267 cnext
5268 cnfile
5269 colder
5270 cprevious
5271 crewind
5272 lNext
5273 lNfile
5274 labove
5275 lbelow
5276 lfirst
5277 llast
5278 lnewer
5279 lnext
5280 lnfile
5281 lolder
5282 lprevious
5283 lrewind
5284 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005285 for cmd in commands
5286 call assert_fails('-1' .. cmd, 'E16:')
5287 call assert_fails('.' .. cmd, 'E16:')
5288 call assert_fails('%' .. cmd, 'E16:')
5289 call assert_fails('$' .. cmd, 'E16:')
5290 endfor
5291endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005292
5293" Test for aborting quickfix commands using QuickFixCmdPre
5294func Xtest_qfcmd_abort(cchar)
5295 call s:setup_commands(a:cchar)
5296
5297 call g:Xsetlist([], 'f')
5298
5299 " cexpr/lexpr
5300 let e = ''
5301 try
5302 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5303 catch /.*/
5304 let e = v:exception
5305 endtry
5306 call assert_equal('AbortCmd', e)
5307 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5308
5309 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005310 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005311 let e = ''
5312 try
5313 Xfile Xfile1
5314 catch /.*/
5315 let e = v:exception
5316 endtry
5317 call assert_equal('AbortCmd', e)
5318 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005319
5320 " cgetbuffer/lgetbuffer
5321 enew!
5322 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5323 let e = ''
5324 try
5325 Xgetbuffer
5326 catch /.*/
5327 let e = v:exception
5328 endtry
5329 call assert_equal('AbortCmd', e)
5330 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5331 enew!
5332
5333 " vimgrep/lvimgrep
5334 let e = ''
5335 try
5336 Xvimgrep /func/ test_quickfix.vim
5337 catch /.*/
5338 let e = v:exception
5339 endtry
5340 call assert_equal('AbortCmd', e)
5341 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5342
5343 " helpgrep/lhelpgrep
5344 let e = ''
5345 try
5346 Xhelpgrep quickfix
5347 catch /.*/
5348 let e = v:exception
5349 endtry
5350 call assert_equal('AbortCmd', e)
5351 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5352
5353 " grep/lgrep
5354 if has('unix')
5355 let e = ''
5356 try
5357 silent Xgrep func test_quickfix.vim
5358 catch /.*/
5359 let e = v:exception
5360 endtry
5361 call assert_equal('AbortCmd', e)
5362 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5363 endif
5364endfunc
5365
5366func Test_qfcmd_abort()
5367 augroup QF_Test
5368 au!
5369 autocmd QuickFixCmdPre * throw "AbortCmd"
5370 augroup END
5371
5372 call Xtest_qfcmd_abort('c')
5373 call Xtest_qfcmd_abort('l')
5374
5375 augroup QF_Test
5376 au!
5377 augroup END
5378endfunc
5379
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005380" Test for using a file in one of the parent directories.
5381func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005382 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005383 let save_cwd = getcwd()
5384 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5385 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5386 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5387 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5388
5389 let lines = "Entering dir Xtestdir\n" .
5390 \ "Entering dir a\n" .
5391 \ "Entering dir b\n" .
5392 \ "Xfile2:2:X2_L2\n" .
5393 \ "Leaving dir a\n" .
5394 \ "Xfile1:2:X1_L2\n" .
5395 \ "Xfile3:1:X3_L1\n" .
5396 \ "Entering dir c\n" .
5397 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005398 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005399 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005400 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005401 call assert_equal(11, getqflist({'size' : 0}).size)
5402 call assert_equal(4, getqflist({'idx' : 0}).idx)
5403 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005404 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005405 cnext
5406 call assert_equal(6, getqflist({'idx' : 0}).idx)
5407 call assert_equal('X1_L2', getline('.'))
5408 cnext
5409 call assert_equal(7, getqflist({'idx' : 0}).idx)
5410 call assert_equal(1, line('$'))
5411 call assert_equal('', getline(1))
5412 cnext
5413 call assert_equal(9, getqflist({'idx' : 0}).idx)
5414 call assert_equal(1, line('$'))
5415 call assert_equal('', getline(1))
5416
5417 set efm&
5418 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005419endfunc
5420
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005421" Test for :cquit
5422func Test_cquit()
5423 " Exit Vim with a non-zero value
5424 if RunVim([], ["cquit 7"], '')
5425 call assert_equal(7, v:shell_error)
5426 endif
5427
5428 if RunVim([], ["50cquit"], '')
5429 call assert_equal(50, v:shell_error)
5430 endif
5431
5432 " Exit Vim with default value
5433 if RunVim([], ["cquit"], '')
5434 call assert_equal(1, v:shell_error)
5435 endif
5436
5437 " Exit Vim with zero value
5438 if RunVim([], ["cquit 0"], '')
5439 call assert_equal(0, v:shell_error)
5440 endif
5441
5442 " Exit Vim with negative value
5443 call assert_fails('-3cquit', 'E16:')
5444endfunc
5445
Bram Moolenaar858ba062020-05-31 23:11:59 +02005446" Test for getting a specific item from a quickfix list
5447func Xtest_getqflist_by_idx(cchar)
5448 call s:setup_commands(a:cchar)
5449 " Empty list
5450 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5451 Xexpr ['F1:10:L10', 'F1:20:L20']
5452 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5453 call assert_equal(bufnr('F1'), l[0].bufnr)
5454 call assert_equal(20, l[0].lnum)
5455 call assert_equal('L20', l[0].text)
5456 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5457 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005458 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005459 %bwipe!
5460endfunc
5461
5462func Test_getqflist_by_idx()
5463 call Xtest_getqflist_by_idx('c')
5464 call Xtest_getqflist_by_idx('l')
5465endfunc
5466
5467" Test for the 'quickfixtextfunc' setting
5468func Tqfexpr(info)
5469 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005470 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005471 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005472 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005473 endif
5474
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005475 let l = []
5476 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5477 let e = qfl[idx]
5478 let s = ''
5479 if e.bufnr != 0
5480 let bname = bufname(e.bufnr)
5481 let s ..= fnamemodify(bname, ':.')
5482 endif
5483 let s ..= '-'
5484 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5485 let s ..= e.text
5486 call add(l, s)
5487 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005488
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005489 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005490endfunc
5491
5492func Xtest_qftextfunc(cchar)
5493 call s:setup_commands(a:cchar)
5494
5495 set efm=%f:%l:%c:%m
5496 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005497 call assert_equal('Tqfexpr', &quickfixtextfunc)
5498 call assert_equal('',
5499 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005500 call g:Xsetlist([
5501 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5502 \ 'end_col': 7, 'text': 'green'},
5503 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5504 \ 'end_col': 8, 'text': 'blue'},
5505 \ ])
5506
Bram Moolenaar858ba062020-05-31 23:11:59 +02005507 Xwindow
5508 call assert_equal('F1-L10C2-green', getline(1))
5509 call assert_equal('F1-L20C4-blue', getline(2))
5510 Xclose
5511 set quickfixtextfunc&vim
5512 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005513 call assert_equal('F1|10 col 2-7| green', getline(1))
5514 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005515 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005516
5517 set efm=%f:%l:%c:%m
5518 set quickfixtextfunc=Tqfexpr
5519 " Update the list with only the cwindow
5520 Xwindow
5521 only
5522 call g:Xsetlist([
5523 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5524 \ 'end_col': 7, 'text': 'red'}
5525 \ ])
5526 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5527 new
5528 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005529 set efm&
5530 set quickfixtextfunc&
5531
5532 " Test for per list 'quickfixtextfunc' setting
5533 func PerQfText(info)
5534 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005535 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005536 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005537 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005538 endif
5539 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005540 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005541 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005542 let l = []
5543 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5544 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5545 endfor
5546 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005547 endfunc
5548 set quickfixtextfunc=Tqfexpr
5549 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5550 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5551 Xwindow
5552 call assert_equal('Line 10, Col 2', getline(1))
5553 call assert_equal('Line 20, Col 4', getline(2))
5554 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005555 call assert_equal(function('PerQfText'),
5556 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005557 " Add entries to the list when the quickfix buffer is hidden
5558 Xaddexpr ['F1:30:6:red']
5559 Xwindow
5560 call assert_equal('Line 30, Col 6', getline(3))
5561 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005562 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005563 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005564 set quickfixtextfunc&
5565 delfunc PerQfText
5566
5567 " Non-existing function
5568 set quickfixtextfunc=Tabc
5569 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5570 call assert_fails("Xwindow", 'E117:')
5571 Xclose
5572 set quickfixtextfunc&
5573
5574 " set option to a non-function
5575 set quickfixtextfunc=[10,\ 20]
5576 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5577 call assert_fails("Xwindow", 'E117:')
5578 Xclose
5579 set quickfixtextfunc&
5580
5581 " set option to a function with different set of arguments
5582 func Xqftext(a, b, c)
5583 return a:a .. a:b .. a:c
5584 endfunc
5585 set quickfixtextfunc=Xqftext
5586 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5587 call assert_fails("Xwindow", 'E119:')
5588 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005589
5590 " set option to a function that returns a list with non-strings
5591 func Xqftext2(d)
5592 return ['one', [], 'two']
5593 endfunc
5594 set quickfixtextfunc=Xqftext2
5595 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5596 \ 'E730:')
5597 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005598 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5599 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005600 Xclose
5601
Bram Moolenaar858ba062020-05-31 23:11:59 +02005602 set quickfixtextfunc&
5603 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005604 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005605
5606 " set the global option to a lambda function
5607 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5608 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5609 Xwindow
5610 call assert_equal(['green', 'blue'], getline(1, '$'))
5611 Xclose
5612 call assert_equal("{d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 'v:val.text')}", &quickfixtextfunc)
5613 set quickfixtextfunc&
5614
5615 " use a lambda function that returns an empty list
5616 set quickfixtextfunc={d\ ->\ []}
5617 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5618 Xwindow
5619 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5620 \ getline(1, '$'))
5621 Xclose
5622 set quickfixtextfunc&
5623
5624 " use a lambda function that returns a list with empty strings
5625 set quickfixtextfunc={d\ ->\ ['',\ '']}
5626 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5627 Xwindow
5628 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5629 \ getline(1, '$'))
5630 Xclose
5631 set quickfixtextfunc&
5632
5633 " set the per-quickfix list text function to a lambda function
5634 call g:Xsetlist([], ' ',
5635 \ {'quickfixtextfunc' :
5636 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5637 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5638 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5639 Xwindow
5640 call assert_equal('Line 10, Col 2', getline(1))
5641 call assert_equal('Line 20, Col 4', getline(2))
5642 Xclose
5643 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5644 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005645endfunc
5646
5647func Test_qftextfunc()
5648 call Xtest_qftextfunc('c')
5649 call Xtest_qftextfunc('l')
5650endfunc
5651
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005652func Test_qftextfunc_callback()
5653 let lines =<< trim END
5654 set efm=%f:%l:%c:%m
5655
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005656 #" Test for using a function name
5657 LET &qftf = 'g:Tqfexpr'
5658 cexpr "F0:0:0:L0"
5659 copen
5660 call assert_equal('F0-L0C0-L0', getline(1))
5661 cclose
5662
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005663 #" Test for using a function()
5664 set qftf=function('g:Tqfexpr')
5665 cexpr "F1:1:1:L1"
5666 copen
5667 call assert_equal('F1-L1C1-L1', getline(1))
5668 cclose
5669
5670 #" Using a funcref variable to set 'quickfixtextfunc'
5671 VAR Fn = function('g:Tqfexpr')
5672 LET &qftf = Fn
5673 cexpr "F2:2:2:L2"
5674 copen
5675 call assert_equal('F2-L2C2-L2', getline(1))
5676 cclose
5677
5678 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5679 LET Fn = function('g:Tqfexpr')
5680 LET &qftf = string(Fn)
5681 cexpr "F3:3:3:L3"
5682 copen
5683 call assert_equal('F3-L3C3-L3', getline(1))
5684 cclose
5685
5686 #" Test for using a funcref()
5687 set qftf=funcref('g:Tqfexpr')
5688 cexpr "F4:4:4:L4"
5689 copen
5690 call assert_equal('F4-L4C4-L4', getline(1))
5691 cclose
5692
5693 #" Using a funcref variable to set 'quickfixtextfunc'
5694 LET Fn = funcref('g:Tqfexpr')
5695 LET &qftf = Fn
5696 cexpr "F5:5:5:L5"
5697 copen
5698 call assert_equal('F5-L5C5-L5', getline(1))
5699 cclose
5700
5701 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5702 LET Fn = funcref('g:Tqfexpr')
5703 LET &qftf = string(Fn)
5704 cexpr "F5:5:5:L5"
5705 copen
5706 call assert_equal('F5-L5C5-L5', getline(1))
5707 cclose
5708
5709 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005710 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005711 LET optval = substitute(optval, ' ', '\\ ', 'g')
5712 exe "set qftf=" .. optval
5713 cexpr "F6:6:6:L6"
5714 copen
5715 call assert_equal('F6-L6C6-L6', getline(1))
5716 cclose
5717
5718 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005719 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005720 cexpr "F7:7:7:L7"
5721 copen
5722 call assert_equal('F7-L7C7-L7', getline(1))
5723 cclose
5724
5725 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005726 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005727 cexpr "F8:8:8:L8"
5728 copen
5729 call assert_equal('F8-L8C8-L8', getline(1))
5730 cclose
5731
5732 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005733 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005734 LET &qftf = Lambda
5735 cexpr "F9:9:9:L9"
5736 copen
5737 call assert_equal('F9-L9C9-L9', getline(1))
5738 cclose
5739
5740 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005741 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005742 LET &qftf = string(Lambda)
5743 cexpr "F9:9:9:L9"
5744 copen
5745 call assert_equal('F9-L9C9-L9', getline(1))
5746 cclose
5747 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005748 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005749
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005750 " Test for using a script-local function name
5751 func s:TqfFunc2(info)
5752 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5753 return ''
5754 endfunc
5755 let g:TqfFunc2Args = []
5756 set quickfixtextfunc=s:TqfFunc2
5757 cexpr "F10:10:10:L10"
5758 cclose
5759 call assert_equal([1, 1], g:TqfFunc2Args)
5760
5761 let &quickfixtextfunc = 's:TqfFunc2'
5762 cexpr "F11:11:11:L11"
5763 cclose
5764 call assert_equal([1, 1], g:TqfFunc2Args)
5765 delfunc s:TqfFunc2
5766
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005767 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5768 func SetQftfFunc()
5769 let params = {'qftf': function('g:DictQftfFunc')}
5770 let &quickfixtextfunc = params.qftf
5771 endfunc
5772 func g:DictQftfFunc(_) dict
5773 endfunc
5774 call SetQftfFunc()
5775 new
5776 call SetQftfFunc()
5777 bw
5778 call test_garbagecollect_now()
5779 new
5780 set qftf=
5781 wincmd w
5782 set qftf=
5783 :%bw!
5784
5785 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5786 " to cause a crash.
5787 let &qftf = ''
5788 func SetLocalQftfFunc()
5789 let params = {'qftf': function('g:DictQftfFunc')}
5790 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5791 endfunc
5792 call SetLocalQftfFunc()
5793 call test_garbagecollect_now()
5794 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5795 delfunc g:DictQftfFunc
5796 delfunc SetQftfFunc
5797 delfunc SetLocalQftfFunc
5798 set efm&
5799endfunc
5800
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005801" Test for updating a location list for some other window and check that
5802" 'qftextfunc' uses the correct location list.
5803func Test_qftextfunc_other_loclist()
5804 %bw!
5805 call setloclist(0, [], 'f')
5806
5807 " create a window and a location list for it and open the location list
5808 " window
5809 lexpr ['F1:10:12:one', 'F1:20:14:two']
5810 let w1_id = win_getid()
5811 call setloclist(0, [], ' ',
5812 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5813 \ 'quickfixtextfunc':
5814 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5815 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5816 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5817 lwindow
5818 let w2_id = win_getid()
5819
5820 " create another window and a location list for it and open the location
5821 " list window
5822 topleft new
5823 let w3_id = win_getid()
5824 call setloclist(0, [], ' ',
5825 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5826 \ 'quickfixtextfunc':
5827 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5828 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5829 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5830 lwindow
5831 let w4_id = win_getid()
5832
5833 topleft new
5834 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5835 let w5_id = win_getid()
5836
5837 " change the location list for some other window
5838 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5839 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5840 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5841 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5842 \ getbufline(winbufnr(w2_id), 1, '$'))
5843 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5844 \ getbufline(winbufnr(w4_id), 1, '$'))
5845 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5846 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5847 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5848 \ getbufline(winbufnr(w2_id), 1, '$'))
5849 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5850 \ getbufline(winbufnr(w4_id), 1, '$'))
5851
5852 call win_gotoid(w5_id)
5853 lwindow
5854 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5855 \ getline(1, '$'))
5856 %bw!
5857endfunc
5858
Bram Moolenaarec98e932020-06-08 19:35:59 +02005859" Running :lhelpgrep command more than once in a help window, doesn't jump to
5860" the help topic
5861func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005862 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005863 call writefile(['window'], 'Xtestdir/doc/a.txt')
5864 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5865 let save_rtp = &rtp
5866 let &rtp = 'Xtestdir'
5867 lhelpgrep window
5868 lhelpgrep buffer
5869 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5870 lhelpgrep window
5871 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5872 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005873 new | only!
5874endfunc
5875
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005876" Test for the crash fixed by 7.3.715
5877func Test_setloclist_crash()
5878 %bw!
5879 let g:BufNum = bufnr()
5880 augroup QF_Test
5881 au!
5882 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5883 augroup END
5884
5885 try
5886 lvimgrep /.*/ *.mak
5887 catch /E926:/
5888 endtry
5889 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5890 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5891
5892 augroup QF_Test
5893 au!
5894 augroup END
5895 unlet g:BufNum
5896 %bw!
5897endfunc
5898
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005899" Test for adding an invalid entry with the quickfix window open and making
5900" sure that the window contents are not changed
5901func Test_add_invalid_entry_with_qf_window()
5902 call setqflist([], 'f')
5903 cexpr "Xfile1:10:aa"
5904 copen
5905 call setqflist(['bb'], 'a')
5906 call assert_equal(1, line('$'))
5907 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005908 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5909
5910 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5911 call assert_equal(1 , line('$'))
5912 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5913 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5914
5915 call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5916 call assert_equal(1 , line('$'))
5917 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5918 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5919
5920 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5921 call assert_equal(1 , line('$'))
5922 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5923 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5924
5925 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5926 call assert_equal(1 , line('$'))
5927 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5928 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5929
5930 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5931 call assert_equal(1 , line('$'))
5932 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5933 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5934
5935 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5936 call assert_equal(1 , line('$'))
5937 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5938 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5939
5940 call setqflist([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5941 call assert_equal(1 , line('$'))
5942 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5943 call assert_equal([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005944 cclose
5945endfunc
5946
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005947" Test for very weird problem: autocommand causes a failure, resulting opening
5948" the quickfix window to fail. This still splits the window, but otherwise
5949" should not mess up buffers.
5950func Test_quickfix_window_fails_to_open()
5951 CheckScreendump
5952
5953 let lines =<< trim END
5954 anything
5955 try
5956 anything
5957 endtry
5958 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005959 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005960
5961 let lines =<< trim END
5962 split XquickfixFails
5963 silent vimgrep anything %
5964 normal o
5965 au BufLeave * ++once source XquickfixFails
5966 " This will trigger the autocommand, which causes an error, what follows
5967 " is aborted but the window was already split.
5968 silent! cwindow
5969 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005970 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005971 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5972 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5973
5974 " clean up
5975 call term_sendkeys(buf, ":bwipe!\<CR>")
5976 call term_wait(buf)
5977 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005978endfunc
5979
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005980" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005981" is changed.
5982func Xqfbuf_update(cchar)
5983 call s:setup_commands(a:cchar)
5984
5985 Xexpr "F1:1:line1"
5986 Xopen
5987 call assert_equal(['F1|1| line1'], getline(1, '$'))
5988 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5989
5990 " Test setqflist() using the 'lines' key in 'what'
5991 " add a new entry
5992 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5993 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5994 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5995 " replace all the entries with a single entry
5996 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5997 call assert_equal(['F3|3| line3'], getline(1, '$'))
5998 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5999 " remove all the entries
6000 call g:Xsetlist([], 'r', {'lines' : []})
6001 call assert_equal([''], getline(1, '$'))
6002 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6003 " add a new list
6004 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6005 call assert_equal(['F4|4| line4'], getline(1, '$'))
6006 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6007
6008 " Test setqflist() using the 'items' key in 'what'
6009 " add a new entry
6010 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6011 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6012 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6013 " replace all the entries with a single entry
6014 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6015 call assert_equal(['F6|6| line6'], getline(1, '$'))
6016 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6017 " remove all the entries
6018 call g:Xsetlist([], 'r', {'items' : []})
6019 call assert_equal([''], getline(1, '$'))
6020 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6021 " add a new list
6022 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6023 call assert_equal(['F7|7| line7'], getline(1, '$'))
6024 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6025
6026 call g:Xsetlist([], ' ', {})
6027 call assert_equal([''], getline(1, '$'))
6028 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6029
6030 Xclose
6031endfunc
6032
6033func Test_qfbuf_update()
6034 call Xqfbuf_update('c')
6035 call Xqfbuf_update('l')
6036endfunc
6037
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006038func Test_vimgrep_noswapfile()
6039 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006040 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006041 vimgrep two Xgreppie
6042 call assert_equal('two', getline('.'))
6043
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006044 set swapfile
6045endfunc
6046
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006047" Test for the :vimgrep 'f' flag (fuzzy match)
6048func Xvimgrep_fuzzy_match(cchar)
6049 call s:setup_commands(a:cchar)
6050
6051 Xvimgrep /three one/f Xfile*
6052 let l = g:Xgetlist()
6053 call assert_equal(2, len(l))
6054 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6055 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6056 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6057 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6058
6059 Xvimgrep /the/f Xfile*
6060 let l = g:Xgetlist()
6061 call assert_equal(3, len(l))
6062 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6063 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6064 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6065 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6066 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6067 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6068
6069 Xvimgrep /aaa/fg Xfile*
6070 let l = g:Xgetlist()
6071 call assert_equal(4, len(l))
6072 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6073 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6074 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6075 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6076 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6077 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6078 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6079 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6080
6081 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6082endfunc
6083
6084func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006085 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6086 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006087 call Xvimgrep_fuzzy_match('c')
6088 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006089endfunc
6090
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006091func Test_locationlist_open_in_newtab()
6092 call s:create_test_file('Xqftestfile1')
6093 call s:create_test_file('Xqftestfile2')
6094 call s:create_test_file('Xqftestfile3')
6095
6096 %bwipe!
6097
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006098 let lines =<< trim END
6099 Xqftestfile1:5:Line5
6100 Xqftestfile2:10:Line10
6101 Xqftestfile3:16:Line16
6102 END
6103 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006104
6105 silent! llast
6106 call assert_equal(1, tabpagenr('$'))
6107 call assert_equal('Xqftestfile3', bufname())
6108
6109 set switchbuf=newtab
6110
6111 silent! lfirst
6112 call assert_equal(2, tabpagenr('$'))
6113 call assert_equal('Xqftestfile1', bufname())
6114
6115 silent! lnext
6116 call assert_equal(3, tabpagenr('$'))
6117 call assert_equal('Xqftestfile2', bufname())
6118
6119 call delete('Xqftestfile1')
6120 call delete('Xqftestfile2')
6121 call delete('Xqftestfile3')
6122 set switchbuf&vim
6123
6124 %bwipe!
6125endfunc
6126
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006127" Test for win_gettype() in quickfix and location list windows
6128func Test_win_gettype()
6129 copen
6130 call assert_equal("quickfix", win_gettype())
6131 let wid = win_getid()
6132 wincmd p
6133 call assert_equal("quickfix", win_gettype(wid))
6134 cclose
6135 lexpr ''
6136 lopen
6137 call assert_equal("loclist", win_gettype())
6138 let wid = win_getid()
6139 wincmd p
6140 call assert_equal("loclist", win_gettype(wid))
6141 lclose
6142endfunc
6143
Christian Brabandt0b226f62021-12-01 10:54:24 +00006144fun Test_vimgrep_nomatch()
6145 call XexprTests('c')
6146 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6147 copen
6148 if has("win32")
6149 call assert_fails('vimgrep foo *.zzz', 'E479:')
6150 let expected = [{'lnum': 10, 'bufnr': 0, 'end_lnum': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': 0, 'module': '', 'type': '', 'end_col': 0, 'col': 0, 'text': 'Line1'}]
6151 else
6152 call assert_fails('vimgrep foo *.zzz', 'E480:')
6153 let expected = []
6154 endif
6155 call assert_equal(expected, getqflist())
6156 cclose
6157endfunc
6158
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006159" Test for opening the quickfix window in two tab pages and then closing one
6160" of the quickfix windows. This should not make the quickfix buffer unlisted.
6161" (github issue #9300).
6162func Test_two_qf_windows()
6163 cexpr "F1:1:line1"
6164 copen
6165 tabnew
6166 copen
6167 call assert_true(&buflisted)
6168 cclose
6169 tabfirst
6170 call assert_true(&buflisted)
6171 let bnum = bufnr()
6172 cclose
6173 " if all the quickfix windows are closed, then buffer should be unlisted.
6174 call assert_false(buflisted(bnum))
6175 %bw!
6176
6177 " Repeat the test for a location list
6178 lexpr "F2:2:line2"
6179 lopen
6180 let bnum = bufnr()
6181 tabnew
6182 exe "buffer" bnum
6183 tabfirst
6184 lclose
6185 tablast
6186 call assert_true(buflisted(bnum))
6187 tabclose
6188 lopen
6189 call assert_true(buflisted(bnum))
6190 lclose
6191 call assert_false(buflisted(bnum))
6192 %bw!
6193endfunc
6194
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006195" Weird sequence of commands that caused entering a wiped-out buffer
6196func Test_lopen_bwipe()
6197 func R()
6198 silent! tab lopen
6199 e x
6200 silent! lfile
6201 endfunc
6202
6203 cal R()
6204 cal R()
6205 cal R()
6206 bw!
6207 delfunc R
6208endfunc
6209
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006210" Another sequence of commands that caused all buffers to be wiped out
6211func Test_lopen_bwipe_all()
6212 let lines =<< trim END
6213 func R()
6214 silent! tab lopen
6215 e foo
6216 silent! lfile
6217 endfunc
6218 cal R()
6219 exe "norm \<C-W>\<C-V>0"
6220 cal R()
6221 bwipe
6222
6223 call writefile(['done'], 'Xresult')
6224 qall!
6225 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006226 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006227 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6228 call assert_equal(['done'], readfile('Xresult'))
6229 endif
6230
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006231 call delete('Xresult')
6232endfunc
6233
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006234" Test for calling setqflist() function recursively
6235func Test_recursive_setqflist()
6236 augroup QF_Test
6237 au!
6238 autocmd BufWinEnter quickfix call setqflist([], 'r')
6239 augroup END
6240
6241 copen
6242 call assert_fails("call setqflist([], 'a')", 'E952:')
6243
6244 augroup QF_Test
6245 au!
6246 augroup END
6247 %bw!
6248endfunc
6249
6250" Test for failure to create a new window when selecting a file from the
6251" quickfix window
6252func Test_cwindow_newwin_fails()
6253 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6254 cwindow
6255 only
6256 let qf_wid = win_getid()
6257 " create the maximum number of scratch windows
6258 let hor_win_count = (&lines - 1)/2
6259 let hor_split_count = hor_win_count - 1
6260 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6261 call win_gotoid(qf_wid)
6262 call assert_fails('exe "normal \<CR>"', 'E36:')
6263 %bw!
6264endfunc
6265
6266" Test for updating the location list when only the location list window is
6267" present and the corresponding file window is closed.
6268func Test_loclist_update_with_llwin_only()
6269 %bw!
6270 new
6271 wincmd w
6272 lexpr ["Xfile1:1:Line1"]
6273 lopen
6274 wincmd p
6275 close
6276 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6277 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6278 %bw!
6279endfunc
6280
6281" Test for getting the quickfix list after a buffer with an error is wiped out
6282func Test_getqflist_wiped_out_buffer()
6283 %bw!
6284 cexpr ["Xtest1:34:Wiped out"]
6285 let bnum = bufnr('Xtest1')
6286 call assert_equal(bnum, getqflist()[0].bufnr)
6287 bw Xtest1
6288 call assert_equal(0, getqflist()[0].bufnr)
6289 %bw!
6290endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006291
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006292" Test for the status message that is displayed when opening a new quickfix
6293" list
6294func Test_qflist_statusmsg()
6295 cexpr "1\n2"
6296 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6297 call assert_equal('(4 of 4): msg', v:statusmsg)
6298 call setqflist([], 'f')
6299 %bw!
6300
6301 " When creating a new quickfix list, if an autocmd changes the quickfix list
6302 " in the stack, then an error message should be displayed.
6303 augroup QF_Test
6304 au!
6305 au BufEnter test_quickfix.vim colder
6306 augroup END
6307 cexpr "1\n2"
6308 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6309 call setqflist([], 'f')
6310 augroup QF_Test
6311 au!
6312 augroup END
6313 %bw!
6314
6315 augroup QF_Test
6316 au!
6317 au BufEnter test_quickfix.vim caddexpr "4"
6318 augroup END
6319 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6320 call setqflist([], 'f')
6321 augroup QF_Test
6322 au!
6323 augroup END
6324 %bw!
6325endfunc
6326
Bram Moolenaard6c67622022-08-24 20:07:22 +01006327func Test_quickfixtextfunc_recursive()
6328 func s:QFTfunc(o)
6329 cgete '0'
6330 endfunc
6331 copen
6332 let &quickfixtextfunc = 's:QFTfunc'
6333 cex ""
6334
6335 let &quickfixtextfunc = ''
6336 cclose
6337endfunc
6338
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006339" Test for replacing the location list from an autocmd. This used to cause a
6340" read from freed memory.
6341func Test_loclist_replace_autocmd()
6342 %bw!
6343 call setloclist(0, [], 'f')
6344 let s:bufnr = bufnr()
6345 cal setloclist(0, [{'0': 0, '': ''}])
6346 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6347 lopen
6348 try
6349 exe "norm j\<CR>"
6350 catch
6351 endtry
6352 lnext
6353 %bw!
6354 call setloclist(0, [], 'f')
6355endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006356
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006357" Test for a very long error line and a very long information line
6358func Test_very_long_error_line()
6359 let msg = repeat('abcdefghijklmn', 146)
6360 let emsg = 'Xlonglines.c:1:' . msg
6361 call writefile([msg, emsg], 'Xerror', 'D')
6362 cfile Xerror
6363 cwindow
6364 call assert_equal($'|| {msg}', getline(1))
6365 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6366 cclose
6367
6368 let l = execute('clist!')->split("\n")
6369 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6370
6371 let l = execute('cc')->split("\n")
6372 call assert_equal([$'(2 of 2): {msg}'], l)
6373
6374 call setqflist([], 'f')
6375endfunc
6376
6377" In the quickfix window, spaces at the beginning of an informational line
6378" should not be removed but should be removed from an error line.
6379func Test_info_line_with_space()
6380 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6381 \ ' 20 | Afunc():', '', ' | ^']
6382 copen
6383 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6384 \ '|| 20 | Afunc():', '|| ',
6385 \ '|| | ^'], getline(1, '$'))
6386 cclose
6387
6388 let l = execute('clist!')->split("\n")
6389 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6390 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6391
6392 call setqflist([], 'f')
6393endfunc
6394
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006395func s:QfTf(_)
6396endfunc
6397
6398func Test_setqflist_cb_arg()
6399 " This was changing the callback name in the dictionary.
6400 let d = #{quickfixtextfunc: 's:QfTf'}
6401 call setqflist([], 'a', d)
6402 call assert_equal('s:QfTf', d.quickfixtextfunc)
6403
6404 call setqflist([], 'f')
6405endfunc
6406
Bram Moolenaard0fab102022-10-20 16:03:33 +01006407
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006408" vim: shiftwidth=2 sts=2 expandtab