blob: 33ce700f0be585a0cf995065ade551ced64ff6c7 [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},
Shane Harper5bf04282023-06-07 19:09:57 +0100170 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55},
171 \ {'lnum':0,'type':'e','text':'Check type field is output even when lnum==0. ("error" was not output by v9.0.0736.)','nr':66}])
Bram Moolenaaree85df32017-03-19 14:19:50 +0100172 let l = split(execute('Xlist', ""), "\n")
173 call assert_equal([' 1:10 col 5 warning 11: Warning',
174 \ ' 2:20 col 10 error 22: Error',
175 \ ' 3:30 col 15 info 33: Info',
176 \ ' 4:40 col 20 x 44: Other',
Shane Harper5bf04282023-06-07 19:09:57 +0100177 \ ' 5:50 col 25 55: one',
178 \ ' 6 error 66: Check type field is output even when lnum==0. ("error" was not output by v9.0.0736.)'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100179
Bram Moolenaard76ce852018-05-01 15:02:04 +0200180 " Test for module names, one needs to explicitly set `'valid':v:true` so
181 call g:Xsetlist([
182 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
183 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
184 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
185 let l = split(execute('Xlist', ""), "\n")
186 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
187 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
188 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
189
Bram Moolenaar5f30e262022-07-28 11:56:01 +0100190 " Very long line should be displayed.
191 let text = 'Line' .. repeat('1234567890', 130)
192 let lines = ['Xtestfile9:2:9:' .. text]
193 Xgetexpr lines
194
195 let l = split(execute('Xlist', ''), "\n")
196 call assert_equal([' 1 Xtestfile9:2 col 9: ' .. text] , l)
197
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100198 " For help entries in the quickfix list, only the filename without directory
199 " should be displayed
200 Xhelpgrep setqflist()
201 let l = split(execute('Xlist 1', ''), "\n")
202 call assert_match('^ 1 [^\\/]\{-}:', l[0])
203
Bram Moolenaaree85df32017-03-19 14:19:50 +0100204 " Error cases
205 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100206endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100207
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100208func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100209 call XlistTests('c')
210 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100211endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100212
213" Tests for the :colder, :cnewer, :lolder and :lnewer commands
214" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100215" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100216func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200217 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100218
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200219 if a:cchar == 'l'
220 " No location list for the current window
221 call assert_fails('lolder', 'E776:')
222 call assert_fails('lnewer', 'E776:')
223 endif
224
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200225 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200226 call g:Xsetlist(list)
227
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100228 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200229 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100230 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
231
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200232 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100233 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
234
235 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200236 Xgetexpr ['Xtestfile1:1:3:Line1']
237 Xgetexpr ['Xtestfile2:2:2:Line2']
238 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100239
240 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200241 Xolder
242 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100243 call assert_equal('Line2', l[0].text)
244
245 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200246 Xnewer
247 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100248 call assert_equal('Line3', l[0].text)
249
250 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200251 Xolder 2
252 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253 call assert_equal('Line1', l[0].text)
254
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200255 Xnewer 2
256 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100257 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100258endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100259
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100260func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100261 call XageTests('c')
262 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100263endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100264
265" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
266" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100267func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200268 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200270 " Opening the location list window without any errors should fail
271 if a:cchar == 'l'
272 call assert_fails('lopen', 'E776:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000273 call assert_fails('lwindow', 'E776:')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200274 endif
275
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200277 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100278
279 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200280 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100281 call assert_true(winnr('$') == 1)
282
283 " Create a list with valid entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100284 let lines =<< trim END
285 Xtestfile1:1:3:Line1
286 Xtestfile2:2:2:Line2
287 Xtestfile3:3:1:Line3
288 END
289 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100290
291 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200292 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100293 call assert_true(winnr('$') == 2 && winnr() == 2 &&
294 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200295 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100296
297 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200298 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100299 call assert_true(winnr('$') == 1)
300
301 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200302 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100303
304 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200305 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100306 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200307 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100308
309 " Opening the window again, should move the cursor to that window
310 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200311 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100312 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200313 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100314 \ getline('.') ==# '|| non-error 1')
315
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100316 " :cnext in quickfix window should move to the next entry
317 Xnext
318 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100319
320 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200321 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100322 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200323
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100324 " Specifying the width should adjust the width for a vertically split
325 " quickfix window.
326 vert Xopen
327 call assert_equal(10, winwidth(0))
328 vert Xopen 12
329 call assert_equal(12, winwidth(0))
330 Xclose
331
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200332 " Horizontally or vertically splitting the quickfix window should create a
333 " normal window/buffer
334 Xopen
335 wincmd s
336 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
337 call assert_equal(0, getwininfo(win_getid())[0].loclist)
338 call assert_notequal('quickfix', &buftype)
339 close
340 Xopen
341 wincmd v
342 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
343 call assert_equal(0, getwininfo(win_getid())[0].loclist)
344 call assert_notequal('quickfix', &buftype)
345 close
346 Xopen
347 Xclose
348
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200349 if a:cchar == 'c'
350 " Opening the quickfix window in multiple tab pages should reuse the
351 " quickfix buffer
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100352 let lines =<< trim END
353 Xtestfile1:1:3:Line1
354 Xtestfile2:2:2:Line2
355 Xtestfile3:3:1:Line3
356 END
357 Xgetexpr lines
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200358 Xopen
359 let qfbufnum = bufnr('%')
360 tabnew
361 Xopen
362 call assert_equal(qfbufnum, bufnr('%'))
363 new | only | tabonly
364 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100365endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100366
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100367func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368 call XwindowTests('c')
369 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100370endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100371
Bram Moolenaar36d50222019-05-02 20:17:40 +0200372func Test_copenHeight()
373 copen
374 wincmd H
375 let height = winheight(0)
376 copen 10
377 call assert_equal(height, winheight(0))
378 quit
379endfunc
380
Bram Moolenaar1142a312019-10-16 14:51:39 +0200381func Test_copenHeight_tabline()
382 set tabline=foo showtabline=2
383 copen
384 wincmd H
385 let height = winheight(0)
386 copen 10
387 call assert_equal(height, winheight(0))
388 quit
389 set tabline& showtabline&
390endfunc
391
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100392" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
393" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100394func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200395 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100396
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100397 let lines =<< trim END
398 Xtestfile1:700:10:Line 700
399 Xtestfile2:800:15:Line 800
400 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100401 call writefile(lines, 'Xqftestfile1', 'D')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100402
403 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200404 Xfile Xqftestfile1
405 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100406 call assert_true(len(l) == 2 &&
407 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
408 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
409
Bram Moolenaar049cba92016-06-26 14:38:04 +0200410 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200411 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200412
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100413 " Run cfile/lfile from a modified buffer
414 enew!
415 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200416 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100417 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
418
419 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200420 Xaddfile Xqftestfile1
421 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100422 call assert_true(len(l) == 3 &&
423 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
424
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100425 let lines =<< trim END
426 Xtestfile1:222:77:Line 222
427 Xtestfile2:333:88:Line 333
428 END
429 call writefile(lines, 'Xqftestfile1')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100430
431 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200432 Xgetfile Xqftestfile1
433 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434 call assert_true(len(l) == 2 &&
435 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
436 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
437
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100438 " Test for a file with a long line and without a newline at the end
439 let text = repeat('x', 1024)
440 let t = 'a.txt:18:' . text
441 call writefile([t], 'Xqftestfile1', 'b')
442 silent! Xfile Xqftestfile1
443 call assert_equal(text, g:Xgetlist()[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100444endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100445
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100446func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100447 call XfileTests('c')
448 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100449endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100450
451" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
452" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100453func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200454 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100455
456 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100457 let lines =<< trim END
458 Xtestfile7:700:10:Line 700
459 Xtestfile8:800:15:Line 800
460 END
461 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200462 Xbuffer!
463 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100464 call assert_true(len(l) == 2 &&
465 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
466 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
467
468 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100469 let lines =<< trim END
470 Xtestfile9:900:55:Line 900
471 Xtestfile10:950:66:Line 950
472 END
473 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200474 Xgetbuffer
475 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100476 call assert_true(len(l) == 2 &&
477 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
478 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
479
480 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100481 let lines =<< trim END
482 Xtestfile11:700:20:Line 700
483 Xtestfile12:750:25:Line 750
484 END
485 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200486 Xaddbuffer
487 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100488 call assert_true(len(l) == 4 &&
489 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
490 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
491 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200492 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100493
Bram Moolenaaree85df32017-03-19 14:19:50 +0100494 " Check for invalid buffer
495 call assert_fails('Xbuffer 199', 'E474:')
496
497 " Check for unloaded buffer
498 edit Xtestfile1
499 let bnr = bufnr('%')
500 enew!
501 call assert_fails('Xbuffer ' . bnr, 'E681:')
502
503 " Check for invalid range
504 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
505 " commands. So directly call the commands.
506 if (a:cchar == 'c')
507 call assert_fails('900,999cbuffer', 'E16:')
508 else
509 call assert_fails('900,999lbuffer', 'E16:')
510 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100511endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100512
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100513func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100514 call XbufferTests('c')
515 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100516endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100517
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100518func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200519 call s:setup_commands(a:cchar)
520
521 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100522endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200523
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100524func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525 call XexprTests('c')
526 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100527endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528
529" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100530func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200531 call s:setup_commands(a:cchar)
532
Bram Moolenaar74240d32017-12-10 15:26:15 +0100533 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200534 " Jumping to first or next location list entry without any error should
535 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100536 if a:cchar == 'c'
537 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100538 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100539 else
540 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100541 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200542 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100543 call assert_fails('Xnext', err)
544 call assert_fails('Xprev', err)
545 call assert_fails('Xnfile', err)
546 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100547 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200548
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100549 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100550 call assert_fails(cmd, 'E42:')
551
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200552 call s:create_test_file('Xqftestfile1')
553 call s:create_test_file('Xqftestfile2')
554
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100555 let lines =<< trim END
556 Xqftestfile1:5:Line5
557 Xqftestfile1:6:Line6
558 Xqftestfile2:10:Line10
559 Xqftestfile2:11:Line11
560 RegularLine1
561 RegularLine2
562 END
563 Xgetexpr lines
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200564
565 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100566 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200567 call assert_fails('Xprev', 'E553:')
568 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200569 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200570 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200571 call assert_equal(10, line('.'))
572 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200573 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200574 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100575 5Xcc
576 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
577 2Xcc
578 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100579 if a:cchar == 'c'
580 cc
581 else
582 ll
583 endif
584 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100585 10Xcc
586 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200587 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200588 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200589 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200590 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200591 call assert_fails('Xnext', 'E553:')
592 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100593 " To process the range using quickfix list entries, directly use the
594 " quickfix commands (don't use the user defined commands)
595 if a:cchar == 'c'
596 $cc
597 else
598 $ll
599 endif
600 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200601 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200602 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200603 call assert_equal(5, line('.'))
604
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200605 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200606 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200607 call assert_equal(11, line('.'))
608 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200609 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200610 call assert_equal(5, line('.'))
611
Bram Moolenaar74240d32017-12-10 15:26:15 +0100612 " Jumping to an error from the error window using cc command
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100613 let lines =<< trim END
614 Xqftestfile1:5:Line5
615 Xqftestfile1:6:Line6
616 Xqftestfile2:10:Line10
617 Xqftestfile2:11:Line11
618 END
619 Xgetexpr lines
Bram Moolenaar74240d32017-12-10 15:26:15 +0100620 Xopen
621 10Xcc
622 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200623 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100624 Xopen
625 call cursor(2, 1)
626 if a:cchar == 'c'
627 .cc
628 else
629 .ll
630 endif
631 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200632 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100633
634 " Jumping to an error from the error window (when only the error window is
635 " present)
636 Xopen | only
637 Xlast 1
638 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200639 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100640
Bram Moolenaaree85df32017-03-19 14:19:50 +0100641 Xexpr ""
642 call assert_fails('Xnext', 'E42:')
643
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200644 call delete('Xqftestfile1')
645 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200646
647 " Should be able to use next/prev with invalid entries
648 Xexpr ""
649 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
650 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100651 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200652 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
653 Xlast
654 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
655 Xfirst
656 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
657 2Xnext
658 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100659endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200660
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100661func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200662 call Xtest_browse('c')
663 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100664endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200665
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000666" Test for memory allocation failures
667func Xnomem_tests(cchar)
668 call s:setup_commands(a:cchar)
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100669
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000670 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
671 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
672
673 call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
674 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100675
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200676 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000677 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100678
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200679 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000680 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100681
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200682 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000683 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100684
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000685 call test_alloc_fail(GetAllocId('qf_efm_fmtstr'), 0, 0)
686 set efm=%f
687 call assert_fails('Xexpr ["Xfile1"]', 'E342:')
688 set efm&
689
690 call test_alloc_fail(GetAllocId('qf_efm_fmtpart'), 0, 0)
691 set efm=%f:%l:%m,%f-%l-%m
692 call assert_fails('Xaddexpr ["Xfile2", "Xfile3"]', 'E342:')
693 set efm&
694
695 call test_alloc_fail(GetAllocId('qf_title'), 0, 0)
696 call assert_fails('Xexpr ""', 'E342:')
697 call assert_equal('', g:Xgetlist({'all': 1}).title)
698
699 call test_alloc_fail(GetAllocId('qf_mef_name'), 0, 0)
700 set makeef=Xtmp##.err
701 call assert_fails('Xgrep needle haystack', 'E342:')
702 set makeef&
703
704 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
705 call assert_fails('Xexpr "Xfile1:10:Line10"', 'E342:')
706
707 if a:cchar == 'l'
708 for id in ['qf_qfline', 'qf_qfinfo']
709 lgetexpr ["Xfile1:10:L10", "Xfile2:20:L20"]
710 call test_alloc_fail(GetAllocId(id), 0, 0)
711 call assert_fails('new', 'E342:')
712 call assert_equal(2, winnr('$'))
713 call assert_equal([], getloclist(0))
714 %bw!
715 endfor
716 endif
717
718 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
719 try
720 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
721 catch /^Vim:Interrupt$/
722 endtry
723
724 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
725 try
726 call assert_fails('Xvimgrep /vim/f runtest.vim', 'E342:')
727 catch /^Vim:Interrupt$/
728 endtry
729
730 let l = getqflist({"lines": ["Xfile1:10:L10"]})
731 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
732 call assert_fails('call g:Xsetlist(l.items)', 'E342:')
733
734 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
735 try
736 call assert_fails('Xhelpgrep quickfix', 'E342:')
737 catch /^Vim:Interrupt$/
738 endtry
739
740 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
741 call assert_fails('let l = g:Xgetlist({"lines": ["Xfile1:10:L10"]})', 'E342:')
742 call assert_equal(#{items: []}, l)
743
744 if a:cchar == 'l'
745 call setqflist([], 'f')
746 call setloclist(0, [], 'f')
747 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
748 call assert_fails('lhelpgrep quickfix', 'E342:')
749 call assert_equal([], getloclist(0))
750
751 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
752 call assert_fails('lvimgrep vim runtest.vim', 'E342:')
753
754 let l = getqflist({"lines": ["Xfile1:10:L10"]})
755 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
756 call assert_fails('call setloclist(0, l.items)', 'E342:')
757
758 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
759 call assert_fails('lbuffer', 'E342:')
760
761 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
762 call assert_fails('lexpr ["Xfile1:10:L10", "Xfile2:20:L20"]', 'E342:')
763
764 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
765 call assert_fails('lfile runtest.vim', 'E342:')
766 endif
767
768 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
769 set efm=%DEntering\ dir\ %f,%f:%l:%m
770 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E342:')
771 set efm&
772
773 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
774 set efm=%+P[%f],(%l)%m
775 call assert_fails('Xexpr ["[runtest.vim]", "(1)Hello"]', 'E342:')
776 set efm&
777
778 call test_alloc_fail(GetAllocId('qf_multiline_pfx'), 0, 0)
779 set efm=%EError,%Cline\ %l,%Z%m
780 call assert_fails('Xexpr ["Error", "line 1", "msg"]', 'E342:')
781 set efm&
782
783 call test_alloc_fail(GetAllocId('qf_makecmd'), 0, 0)
784 call assert_fails('Xgrep vim runtest.vim', 'E342:')
785
786 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
787 call assert_fails('Xexpr repeat("a", 8192)', 'E342:')
788
789 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
790 call assert_fails('Xexpr [repeat("a", 8192)]', 'E342:')
791
792 new
793 call setline(1, repeat('a', 8192))
794 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
795 call assert_fails('Xbuffer', 'E342:')
796 %bw!
797
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100798 call writefile([repeat('a', 8192)], 'Xtest', 'D')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000799 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
800 call assert_fails('Xfile Xtest', 'E342:')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000801endfunc
802
803func Test_nomem()
804 call Xnomem_tests('c')
805 call Xnomem_tests('l')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100806endfunc
807
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100808func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200809 call s:setup_commands(a:cchar)
810 Xhelpgrep quickfix
811 Xopen
812 if a:cchar == 'c'
813 let title_text = ':helpgrep quickfix'
814 else
815 let title_text = ':lhelpgrep quickfix'
816 endif
817 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200818
819 " Jumping to a help topic should open the help window
820 only
821 Xnext
822 call assert_true(&buftype == 'help')
823 call assert_true(winnr('$') == 2)
824 " Jumping to the next match should reuse the help window
825 Xnext
826 call assert_true(&buftype == 'help')
827 call assert_true(winnr() == 1)
828 call assert_true(winnr('$') == 2)
829 " Jumping to the next match from the quickfix window should reuse the help
830 " window
831 Xopen
832 Xnext
833 call assert_true(&buftype == 'help')
834 call assert_true(winnr() == 1)
835 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200836 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200837
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100838 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200839 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100840
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100841 " When the current window is vertically split, jumping to a help match
842 " should open the help window at the top.
843 only | enew
844 let w1 = win_getid()
845 vert new
846 let w2 = win_getid()
847 Xnext
848 let w3 = win_getid()
849 call assert_true(&buftype == 'help')
850 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100851 " See jump_to_help_window() for details
852 let w2_width = winwidth(w2)
853 if w2_width != &columns && w2_width < 80
854 call assert_equal(['col', [['leaf', w3],
855 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
856 else
857 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
858 \ ['leaf', w1]]] , winlayout())
859 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100860
861 new | only
862 set buftype=help
863 set modified
864 call assert_fails('Xnext', 'E37:')
865 set nomodified
866 new | only
867
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200868 if a:cchar == 'l'
869 " When a help window is present, running :lhelpgrep should reuse the
870 " help window and not the current window
871 new | only
872 call g:Xsetlist([], 'f')
873 help index.txt
874 wincmd w
875 lhelpgrep quickfix
876 call assert_equal(1, winnr())
877 call assert_notequal([], getloclist(1))
878 call assert_equal([], getloclist(2))
879 endif
880
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200881 new | only
882
Bram Moolenaaree85df32017-03-19 14:19:50 +0100883 " Search for non existing help string
884 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200885 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200886 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100887endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200888
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100889func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200890 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200891 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200892 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100893endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100894
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100895def Test_helpgrep_vim9_restore_cpo()
896 assert_equal('aABceFs', &cpo)
897
898 var rtp_save = &rtp
899 var dir = 'Xruntime/after'
900 &rtp ..= ',' .. dir
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100901 mkdir(dir .. '/ftplugin', 'pR')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100902 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100903 filetype plugin on
904 silent helpgrep grail
905 cwindow
906 silent helpgrep grail
907
908 assert_equal('aABceFs', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100909 &rtp = rtp_save
910 cclose
911 helpclose
912enddef
913
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000914" When running the :helpgrep command, if an autocmd modifies the 'cpoptions'
915" value, then Vim crashes. (issue fixed by 7.2b-004 and 8.2.4453)
Bram Moolenaar4791fcd2022-02-23 12:06:00 +0000916func Test_helpgrep_restore_cpo_aucmd()
917 let save_cpo = &cpo
918 augroup QF_Test
919 au!
920 autocmd BufNew * set cpo=acd
921 augroup END
922
923 helpgrep quickfix
924 call assert_equal('acd', &cpo)
925 %bw!
926
927 set cpo&vim
928 augroup QF_Test
929 au!
930 autocmd BufReadPost * set cpo=
931 augroup END
932
933 helpgrep buffer
934 call assert_equal('', &cpo)
935
936 augroup QF_Test
937 au!
938 augroup END
939 %bw!
940 let &cpo = save_cpo
941endfunc
942
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200943def Test_vim9_cexpr()
944 var text = 'somefile:95:error'
945 cexpr text
946 var l = getqflist()
947 assert_equal(1, l->len())
948 assert_equal(95, l[0].lnum)
949 assert_equal('error', l[0].text)
950
951 text = 'somefile:77:warning'
952 caddexpr text
953 l = getqflist()
954 assert_equal(2, l->len())
955 assert_equal(77, l[1].lnum)
956 assert_equal('warning', l[1].text)
957enddef
958
Bram Moolenaar6920c722016-01-22 22:44:10 +0100959func Test_errortitle()
960 augroup QfBufWinEnter
961 au!
962 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
963 augroup END
964 copen
965 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'')'}]
966 call setqflist(a)
967 call assert_equal(':setqflist()', g:a)
968 augroup QfBufWinEnter
969 au!
970 augroup END
971 augroup! QfBufWinEnter
972endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100973
Bram Moolenaar5584df62016-03-18 21:00:51 +0100974func Test_vimgreptitle()
975 augroup QfBufWinEnter
976 au!
977 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
978 augroup END
979 try
980 vimgrep /pattern/j file
981 catch /E480/
982 endtry
983 copen
984 call assert_equal(': vimgrep /pattern/j file', g:a)
985 augroup QfBufWinEnter
986 au!
987 augroup END
988 augroup! QfBufWinEnter
989endfunc
990
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100991func Test_bufwinenter_once()
992 augroup QfBufWinEnter
993 au!
994 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
995 augroup END
996 let g:got_afile = ''
997 copen
998 call assert_equal('got quickfix', g:got_afile)
999
1000 cclose
1001 unlet g:got_afile
1002 augroup QfBufWinEnter
1003 au!
1004 augroup END
1005 augroup! QfBufWinEnter
1006endfunc
1007
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001008func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001009 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +01001010
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001011 Xgetexpr ['file:1:1:message']
1012 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001013 if a:cchar == 'c'
1014 call setqflist(l, 'r')
1015 else
1016 call setloclist(0, l, 'r')
1017 endif
1018
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001019 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +01001020 if a:cchar == 'c'
1021 let title = ':setqflist()'
1022 else
1023 let title = ':setloclist()'
1024 endif
1025 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001026 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001027endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001028
1029" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001030func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001031 call XqfTitleTests('c')
1032 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001033endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001034
1035" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001036func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001037 let save_efm = &efm
1038 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
1039 cgetexpr ['WWWW', 'EEEE', 'CCCC']
1040 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1041 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1042 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
1043 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1044 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1045 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
1046 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1047 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
1048 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001049endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001050
1051" This will test for problems in quickfix:
1052" A. incorrectly copying location lists which caused the location list to show
1053" a different name than the file that was actually being displayed.
1054" B. not reusing the window for which the location list window is opened but
1055" instead creating new windows.
1056" C. make sure that the location list window is not reused instead of the
1057" window it belongs to.
1058"
1059" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001060func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001061 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
1062 let word = substitute(base, '\v(.*)\..*', '\1', '')
1063
1064 setl modifiable
1065 setl noreadonly
1066 setl noswapfile
1067 setl bufhidden=delete
1068 %del _
1069 " For problem 2:
1070 " 'buftype' has to be set to reproduce the constant opening of new windows
1071 setl buftype=nofile
1072
1073 call setline(1, word)
1074
1075 setl nomodified
1076 setl nomodifiable
1077 setl readonly
1078 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001079endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001080
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001081func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001082 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001083
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001084 augroup testgroup
1085 au!
1086 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
1087 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001088
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001089 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001090
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001091 let qflist = []
1092 for word in words
1093 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
1094 " NOTE: problem 1:
1095 " intentionally not setting 'lnum' so that the quickfix entries are not
1096 " valid
1097 eval qflist->setloclist(0, ' ')
1098 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001099
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001100 " Test A
1101 lrewind
1102 enew
1103 lopen
1104 4lnext
1105 vert split
1106 wincmd L
1107 lopen
1108 wincmd p
1109 lnext
1110 let fileName = expand("%")
1111 wincmd p
1112 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
1113 let fileName = substitute(fileName, '\\', '/', 'g')
1114 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
1115 call assert_equal("test://bar.txt", fileName)
1116 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001117
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001118 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001119
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001120 " Test B:
1121 lrewind
1122 lopen
1123 2
1124 exe "normal \<CR>"
1125 wincmd p
1126 3
1127 exe "normal \<CR>"
1128 wincmd p
1129 4
1130 exe "normal \<CR>"
1131 call assert_equal(2, winnr('$'))
1132 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001133
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001134 " Test C:
1135 lrewind
1136 lopen
1137 " Let's move the location list window to the top to check whether it (the
1138 " first window found) will be reused when we try to open new windows:
1139 wincmd K
1140 2
1141 exe "normal \<CR>"
1142 wincmd p
1143 3
1144 exe "normal \<CR>"
1145 wincmd p
1146 4
1147 exe "normal \<CR>"
1148 1wincmd w
1149 call assert_equal('quickfix', &buftype)
1150 2wincmd w
1151 let bufferName = expand("%")
1152 let bufferName = substitute(bufferName, '\\', '/', 'g')
1153 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001154
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001155 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001156
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001157 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +01001158endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001159
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001160func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001161 augroup testgroup
1162 au!
1163 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
1164 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +01001165
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001166 func! R(n)
1167 quit
1168 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001169
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001170 new
1171 let q = []
1172 call add(q, {'filename': 'test_curwin.txt' })
1173 call setloclist(0, q)
1174 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001175
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001176 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001177 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001178endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001179
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001180func Test_locationlist_cross_tab_jump()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001181 call writefile(['loclistfoo'], 'loclistfoo', 'D')
1182 call writefile(['loclistbar'], 'loclistbar', 'D')
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001183 set switchbuf=usetab
1184
1185 edit loclistfoo
1186 tabedit loclistbar
1187 silent lgrep loclistfoo loclist*
1188 call assert_equal(1, tabpagenr())
1189
1190 enew | only | tabonly
1191 set switchbuf&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001192endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001193
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001194" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001195func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001196 " The 'errorformat' setting is different on non-Unix systems.
1197 " This test works only on Unix-like systems.
1198 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001199
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001200 let l =<< trim [DATA]
1201 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1202 "Xtestfile", line 6 col 19; this is an error
1203 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1204 Xtestfile:9: parse error before `asd'
Gregory Andersd1911a82023-06-05 21:52:46 +01001205 make: *** [src/vim/testdir/Makefile:100: test_quickfix] Error 1
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001206 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001207
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001208 2 returned
1209 "Xtestfile", line 11 col 1; this is an error
1210 "Xtestfile", line 12 col 2; this is another error
1211 "Xtestfile", line 14:10; this is an error in column 10
1212 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1213 "Xtestfile", linenr 16: yet another problem
1214 Error in "Xtestfile" at line 17:
1215 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001216 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001217 ^
1218 Error in "Xtestfile" at line 18:
1219 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001220 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001221 .............^
1222 Error in "Xtestfile" at line 19:
1223 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001224 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001225 --------------^
1226 Error in "Xtestfile" at line 20:
1227 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001228 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1229 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001230
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001231 Does anyone know what is the problem and how to correction it?
1232 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1233 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1234 [DATA]
1235
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001236 call writefile(l, 'Xerrorfile1', 'D')
1237 call delete('loclistbar')
1238 call writefile(l[:-2], 'Xerrorfile2', 'D')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001239
1240 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001241 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1242 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1243 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1244 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1245 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1246 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1247 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1248 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1249 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1250 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1251 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1252 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1253 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1254 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1255 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1256 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1257 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1258 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1259 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1260 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1261 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1262[DATA]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001263 call writefile(m, 'Xtestfile', 'D')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001264
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001265 let save_efm = &efm
1266 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1267 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001268
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001269 exe 'cf Xerrorfile2'
1270 clast
1271 copen
1272 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1273 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001274
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001275 exe 'cf Xerrorfile1'
1276 call assert_equal([4, 12], [line('.'), col('.')])
1277 cn
1278 call assert_equal([6, 19], [line('.'), col('.')])
1279 cn
1280 call assert_equal([9, 2], [line('.'), col('.')])
1281 cn
1282 call assert_equal([10, 2], [line('.'), col('.')])
1283 cn
1284 call assert_equal([11, 1], [line('.'), col('.')])
1285 cn
1286 call assert_equal([12, 2], [line('.'), col('.')])
1287 cn
1288 call assert_equal([14, 10], [line('.'), col('.')])
1289 cn
1290 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1291 cn
1292 call assert_equal([16, 2], [line('.'), col('.')])
1293 cn
1294 call assert_equal([17, 6], [line('.'), col('.')])
1295 cn
1296 call assert_equal([18, 7], [line('.'), col('.')])
1297 cn
1298 call assert_equal([19, 8], [line('.'), col('.')])
1299 cn
1300 call assert_equal([20, 9], [line('.'), col('.')])
1301 clast
1302 cprev
1303 cprev
1304 wincmd w
1305 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1306 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001307
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001308 let &efm = save_efm
Bram Moolenaaree85df32017-03-19 14:19:50 +01001309endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001310
Bram Moolenaarab47c612016-06-14 22:02:26 +02001311" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001312func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001313 call s:setup_commands(a:cchar)
1314
Bram Moolenaarab47c612016-06-14 22:02:26 +02001315 let save_efm=&efm
1316 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1317
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001318 let lines =<< trim END
1319 Entering dir 'dir1/a'
1320 habits2.txt:1:Nine Healthy Habits
1321 Entering dir 'b'
1322 habits3.txt:2:0 Hours of television
1323 habits2.txt:7:5 Small meals
1324 Entering dir 'dir1/c'
1325 habits4.txt:3:1 Hour of exercise
1326 Leaving dir 'dir1/c'
1327 Leaving dir 'dir1/a'
1328 habits1.txt:4:2 Liters of water
1329 Entering dir 'dir2'
1330 habits5.txt:5:3 Cups of hot green tea
1331 Leaving dir 'dir2'
1332 END
Bram Moolenaarab47c612016-06-14 22:02:26 +02001333
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001334 Xexpr ""
1335 for l in lines
1336 Xaddexpr l
1337 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001338
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001339 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001340
1341 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1342 call assert_equal(1, qf[1].lnum)
1343 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1344 call assert_equal(2, qf[3].lnum)
1345 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1346 call assert_equal(7, qf[4].lnum)
1347 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1348 call assert_equal(3, qf[6].lnum)
1349 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1350 call assert_equal(4, qf[9].lnum)
1351 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1352 call assert_equal(5, qf[11].lnum)
1353
1354 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001355endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001356
1357" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001358func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001359 " Create the directory stack and files
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001360 call mkdir('dir1', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001361 call mkdir('dir1/a')
1362 call mkdir('dir1/a/b')
1363 call mkdir('dir1/c')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001364 call mkdir('dir2', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001365
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001366 let lines =<< trim END
1367 Nine Healthy Habits
1368 0 Hours of television
1369 1 Hour of exercise
1370 2 Liters of water
1371 3 Cups of hot green tea
1372 4 Short mental breaks
1373 5 Small meals
1374 6 AM wake up time
1375 7 Minutes of laughter
1376 8 Hours of sleep (at least)
1377 9 PM end of the day and off to bed
1378 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001379 call writefile(lines, 'habits1.txt', 'D')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001380 call writefile(lines, 'dir1/a/habits2.txt')
1381 call writefile(lines, 'dir1/a/b/habits3.txt')
1382 call writefile(lines, 'dir1/c/habits4.txt')
1383 call writefile(lines, 'dir2/habits5.txt')
1384
1385 call s:dir_stack_tests('c')
1386 call s:dir_stack_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001387endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001388
Bram Moolenaar9b457942016-10-09 16:10:05 +02001389" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001390func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001391 call s:setup_commands(a:cchar)
1392
1393 let save_efm = &efm
1394
1395 let &efm =
1396 \ '%Eerror %m %l,' .
1397 \ '%-Wignored %m %l,' .
1398 \ '%+Cmore ignored %m %l,' .
1399 \ '%Zignored end'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001400 let lines =<< trim END
1401 ignored warning 1
1402 more ignored continuation 2
1403 ignored end
1404 error resync 4
1405 END
1406 Xgetexpr lines
Bram Moolenaar9b457942016-10-09 16:10:05 +02001407 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1408 call assert_equal([['resync', 1, 4, 'E']], l)
1409
1410 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001411endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001412
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001413func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001414 call Xefm_ignore_continuations('c')
1415 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001416endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001417
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001418" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001419func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001420 call s:setup_commands(a:cchar)
1421
Bram Moolenaar049cba92016-06-26 14:38:04 +02001422 let save_efm = &efm
1423
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001424 set efm=%f:%l:%m,%f:%f:%l:%m
1425 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1426
1427 set efm=%f:%l:%m,%f:%l:%r:%m
1428 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1429
1430 set efm=%f:%l:%m,%O:%f:%l:%m
1431 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1432
1433 set efm=%f:%l:%m,%f:%l:%*[^a-z
1434 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1435
1436 set efm=%f:%l:%m,%f:%l:%*c
1437 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1438
1439 set efm=%f:%l:%m,%L%M%N
1440 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1441
1442 set efm=%f:%l:%m,%f:%l:%m:%R
1443 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1444
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001445 " Invalid regular expression
1446 set efm=%\\%%k
1447 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1448
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001449 set efm=
1450 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1451
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001452 " Empty directory name. When there is an error in parsing new entries, make
1453 " sure the previous quickfix list is made the current list.
1454 set efm&
1455 cexpr ["one", "two"]
1456 let qf_id = getqflist(#{id: 0}).id
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001457 set efm=%DEntering\ dir\ abc,%f:%l:%m
1458 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001459 call assert_equal(qf_id, getqflist(#{id: 0}).id)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001460
1461 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001462endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001463
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001464func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001465 call Xinvalid_efm_Tests('c')
1466 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001467endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001468
1469" TODO:
1470" Add tests for the following formats in 'errorformat'
1471" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001472func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001473 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001474
1475 " Test for %s format in efm
1476 set efm=%f:%s
1477 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001478 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001479 call assert_equal('^\VLine search text\$', l[0].pattern)
1480 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001481
Bram Moolenaaree85df32017-03-19 14:19:50 +01001482 let l = split(execute('clist', ''), "\n")
1483 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1484
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001485 " Test for a long line
1486 cexpr 'Xtestfile:' . repeat('a', 1026)
1487 let l = getqflist()
1488 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1489
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001490 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001491 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001492 [Xtestfile1]
1493 (1,17) error: ';' missing
1494 (21,2) warning: variable 'z' not defined
1495 (67,3) error: end of file found before string ended
1496 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001497
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001498 [Xtestfile2]
1499 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001500
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001501 [Xtestfile3]
1502 NEW compiler v1.1
1503 (2,2) warning: variable 'x' not defined
1504 (67,3) warning: 's' already defined
1505 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001506 [DATA]
1507
Bram Moolenaaree85df32017-03-19 14:19:50 +01001508 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001509 " To exercise the push/pop file functionality in quickfix, the test files
1510 " need to be created.
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001511 call writefile(['Line1'], 'Xtestfile1', 'D')
1512 call writefile(['Line2'], 'Xtestfile2', 'D')
1513 call writefile(['Line3'], 'Xtestfile3', 'D')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001514 cexpr ""
1515 for l in lines
1516 caddexpr l
1517 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001518 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001519 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001520 call assert_equal(21, l[2].lnum)
1521 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001522 call assert_equal('w', l[2].type)
1523 call assert_equal('e', l[3].type)
1524
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001525 " Test for %P, %Q with non-existing files
1526 cexpr lines
1527 let l = getqflist()
1528 call assert_equal(14, len(l))
1529 call assert_equal('[Xtestfile1]', l[0].text)
1530 call assert_equal('[Xtestfile2]', l[6].text)
1531 call assert_equal('[Xtestfile3]', l[9].text)
1532
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001533 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001534 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001535 Error 275
1536 line 42
1537 column 3
1538 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001539 [DATA]
1540
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001541 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1542 cgetexpr lines
1543 let l = getqflist()
1544 call assert_equal(275, l[0].nr)
1545 call assert_equal(42, l[0].lnum)
1546 call assert_equal(3, l[0].col)
1547 call assert_equal('E', l[0].type)
1548 call assert_equal("\n' ' expected after '--'", l[0].text)
1549
1550 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001551 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001552 Error in line 147 of foo.c:
1553 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001554 [DATA]
1555
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001556 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1557 cgetexpr lines
1558 let l = getqflist()
1559 call assert_equal(147, l[0].lnum)
1560 call assert_equal('E', l[0].type)
1561 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001562
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001563 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001564 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001565 ==============================================================
1566 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1567 --------------------------------------------------------------
1568 Traceback (most recent call last):
1569 File "unittests/dbfacadeTest.py", line 89, in testFoo
1570 self.assertEquals(34, dtid)
1571 File "/usr/lib/python2.2/unittest.py", line 286, in
1572 failUnlessEqual
1573 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001574 W:AssertionError: 34 != 33
Bram Moolenaar94722c52023-01-28 19:19:03 +00001575
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001576 --------------------------------------------------------------
1577 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001578 [DATA]
1579
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001580 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001581 cgetexpr lines
1582 let l = getqflist()
1583 call assert_equal(8, len(l))
1584 call assert_equal(89, l[4].lnum)
1585 call assert_equal(1, l[4].valid)
1586 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001587 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001588
Bram Moolenaard76ce852018-05-01 15:02:04 +02001589 " Test for %o
1590 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001591 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001592 call writefile(['Line1'], 'Xotestfile', 'D')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001593 let l = getqflist()
1594 call assert_equal(1, len(l), string(l))
1595 call assert_equal('Language.PureScript.Types', l[0].module)
1596 copen
1597 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1598 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001599 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001600 cclose
1601 bd
Bram Moolenaard76ce852018-05-01 15:02:04 +02001602
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001603 " Test for a long module name
1604 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1605 let l = getqflist()
1606 call assert_equal(repeat('m', 1024), l[0].module)
1607 call assert_equal(15, l[0].lnum)
1608 call assert_equal('message', l[0].text)
1609
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001610 " The following sequence of commands used to crash Vim
1611 set efm=%W%m
1612 cgetexpr ['msg1']
1613 let l = getqflist()
1614 call assert_equal(1, len(l), string(l))
1615 call assert_equal('msg1', l[0].text)
1616 set efm=%C%m
1617 lexpr 'msg2'
1618 let l = getloclist(0)
1619 call assert_equal(1, len(l), string(l))
1620 call assert_equal('msg2', l[0].text)
1621 lopen
1622 call setqflist([], 'r')
1623 caddbuf
1624 let l = getqflist()
1625 call assert_equal(1, len(l), string(l))
1626 call assert_equal('|| msg2', l[0].text)
1627
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001628 " When matching error lines, case should be ignored. Test for this.
1629 set noignorecase
1630 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1631 call assert_equal(10, l.items[0].lnum)
1632 call assert_equal('Line 20', l.items[0].text)
1633 set ignorecase&
1634
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001635 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001636 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001637endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001638
Bram Moolenaare9283662020-06-07 14:10:47 +02001639" Test for '%t' (error type) field in 'efm'
1640func Test_efm_error_type()
1641 let save_efm = &efm
1642
1643 " error type
1644 set efm=%f:%l:%t:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001645 let lines =<< trim END
1646 Xfile1:10:E:msg1
1647 Xfile1:20:W:msg2
1648 Xfile1:30:I:msg3
1649 Xfile1:40:N:msg4
1650 Xfile1:50:R:msg5
1651 END
1652 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001653 let output = split(execute('clist'), "\n")
1654 call assert_equal([
1655 \ ' 1 Xfile1:10 error: msg1',
1656 \ ' 2 Xfile1:20 warning: msg2',
1657 \ ' 3 Xfile1:30 info: msg3',
1658 \ ' 4 Xfile1:40 note: msg4',
1659 \ ' 5 Xfile1:50 R: msg5'], output)
1660
1661 " error type and a error number
1662 set efm=%f:%l:%t:%n:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001663 let lines =<< trim END
1664 Xfile1:10:E:2:msg1
1665 Xfile1:20:W:4:msg2
1666 Xfile1:30:I:6:msg3
1667 Xfile1:40:N:8:msg4
1668 Xfile1:50:R:3:msg5
1669 END
1670 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001671 let output = split(execute('clist'), "\n")
1672 call assert_equal([
1673 \ ' 1 Xfile1:10 error 2: msg1',
1674 \ ' 2 Xfile1:20 warning 4: msg2',
1675 \ ' 3 Xfile1:30 info 6: msg3',
1676 \ ' 4 Xfile1:40 note 8: msg4',
1677 \ ' 5 Xfile1:50 R 3: msg5'], output)
1678 let &efm = save_efm
1679endfunc
1680
haya14busae023d492022-02-08 18:09:29 +00001681" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1682func Test_efm_end_lnum_col()
1683 let save_efm = &efm
1684
1685 " single line
1686 set efm=%f:%l-%e:%c-%k:%t:%m
1687 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1688 let output = split(execute('clist'), "\n")
1689 call assert_equal([
1690 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1691 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1692
1693 " multiple lines
1694 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001695 let lines =<< trim END
1696 1)msg1
1697 Xfile1:14-24:1-2
1698 2)msg2
1699 Xfile1:24-34:3-4
1700 END
1701 cexpr lines
haya14busae023d492022-02-08 18:09:29 +00001702 let output = split(execute('clist'), "\n")
1703 call assert_equal([
1704 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1705 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1706 let &efm = save_efm
1707endfunc
1708
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001709func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001710 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001711 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001712 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001713 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001714 colder
1715 cgetexpr []
1716 endfunc
1717 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001718 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001719 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001720 lolder
1721 lgetexpr []
1722 endfunc
1723 endif
1724
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001725 augroup QF_Test
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001726 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001727 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001728 augroup END
1729
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001730 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001731 let words = [ "a", "b" ]
1732 let qflist = []
1733 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001734 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001736 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001737 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001738
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001739 augroup QF_Test
1740 au!
1741 augroup END
1742
1743 if a:cchar == 'c'
1744 cexpr ["Xtest1:1:Line"]
1745 cwindow
1746 only
1747 augroup QF_Test
1748 au!
1749 autocmd WinEnter * call setqflist([], 'f')
1750 augroup END
1751 call assert_fails('exe "normal \<CR>"', 'E925:')
1752 augroup QF_Test
1753 au!
1754 augroup END
1755 endif
1756 %bw!
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001757endfunc
1758
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001759func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001760 call XquickfixChangedByAutocmd('c')
1761 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001762endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001763
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001764func Test_setloclist_in_autocommand()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001765 call writefile(['test1', 'test2'], 'Xfile', 'D')
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001766 edit Xfile
1767 let s:bufnr = bufnr()
1768 call setloclist(1,
1769 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1770 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1771
1772 augroup Test_LocList
1773 au!
1774 autocmd BufEnter * call setloclist(1,
1775 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1776 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1777 augroup END
1778
1779 lopen
1780 call assert_fails('exe "normal j\<CR>"', 'E926:')
1781
1782 augroup Test_LocList
1783 au!
1784 augroup END
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001785endfunc
1786
Bram Moolenaar8b201792016-03-25 15:01:10 +01001787func Test_caddbuffer_to_empty()
1788 helpgr quickfix
1789 call setqflist([], 'r')
1790 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001791 try
1792 cn
1793 catch
1794 " number of matches is unknown
1795 call assert_true(v:exception =~ 'E553:')
1796 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001797 quit!
1798endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001799
1800func Test_cgetexpr_works()
1801 " this must not crash Vim
1802 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001803 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001804endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001805
1806" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001807func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001808 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001809
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001810 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Tom Praschanca6ac992023-08-11 23:26:12 +02001811 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5, 'user_data': {'6': [7, 8]}}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001812 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001813 call assert_equal(2, len(l))
1814 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001815 call assert_equal(3, l[1].end_lnum)
1816 call assert_equal(4, l[1].col)
1817 call assert_equal(5, l[1].end_col)
Tom Praschanca6ac992023-08-11 23:26:12 +02001818 call assert_equal({'6': [7, 8]}, l[1].user_data)
1819
1820 " Test that user_data is garbage collected
1821 call g:Xsetlist([{'user_data': ['high', 5]},
1822 \ {'user_data': {'this': [7, 'eight'], 'is': ['a', 'dictionary']}}])
1823 call test_garbagecollect_now()
1824 let l = g:Xgetlist()
1825 call assert_equal(2, len(l))
1826 call assert_equal(['high', 5], l[0].user_data)
1827 call assert_equal({'this': [7, 'eight'], 'is': ['a', 'dictionary']}, l[1].user_data)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001828
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001829 Xnext
1830 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1831 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001832 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001834 call assert_equal(3, line('.'))
1835
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001836 " Appending entries to the list should not change the cursor position
1837 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001838 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001839 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001840 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001841 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1842 call assert_equal(1, line('.'))
1843 close
1844
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001845 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001846 \ {'bufnr': a:bnum, 'lnum': 4},
1847 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001848 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001849 call assert_equal(3, len(l))
1850 call assert_equal(5, l[2].lnum)
1851
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001852 call g:Xsetlist([])
1853 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001854 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001855
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001856 " Tests for setting the 'valid' flag
1857 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1858 Xwindow
1859 call assert_equal(1, winnr('$'))
1860 let l = g:Xgetlist()
1861 call g:Xsetlist(l)
1862 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001863 " Adding a non-valid entry should not mark the list as having valid entries
1864 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1865 Xwindow
1866 call assert_equal(1, winnr('$'))
1867
1868 " :cnext/:cprev should still work even with invalid entries in the list
1869 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1870 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1871 call g:Xsetlist(l)
1872 Xnext
1873 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1874 Xprev
1875 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1876 " :cnext/:cprev should still work after appending invalid entries to an
1877 " empty list
1878 call g:Xsetlist([])
1879 call g:Xsetlist(l, 'a')
1880 Xnext
1881 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1882 Xprev
1883 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1884
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001885 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1886 Xwindow
1887 call assert_equal(2, winnr('$'))
1888 Xclose
1889 let save_efm = &efm
1890 set efm=%m
1891 Xgetexpr 'TestMessage'
1892 let l = g:Xgetlist()
1893 call g:Xsetlist(l)
1894 call assert_equal(1, g:Xgetlist()[0].valid)
1895 let &efm = save_efm
1896
Bram Moolenaaree85df32017-03-19 14:19:50 +01001897 " Error cases:
1898 " Refer to a non-existing buffer and pass a non-dictionary type
1899 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1900 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1901 call g:Xsetlist([[1, 2,3]])
1902 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001903 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001904 call g:Xsetlist([test_null_dict()])
1905 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001906endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001907
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001908func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001909 new Xtestfile | only
1910 let bnum = bufnr('%')
1911 call setline(1, range(1,5))
1912
1913 call SetXlistTests('c', bnum)
1914 call SetXlistTests('l', bnum)
1915
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001916 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001917 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001918endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001919
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001920func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001921 call s:setup_commands(a:cchar)
1922
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001923 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001924 let @/ = 'Test_'
1925 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001926 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001927 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001928 Xvimgrep empty test_quickfix.vim
1929 call assert_true(len(g:Xgetlist()) > 0)
1930 Xvimgrep matches test_quickfix.vim
1931 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001932 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001933 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001934 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001935 call g:Xsetlist([], 'r')
1936 call assert_true(len(g:Xgetlist()) == 0)
1937 Xolder
1938 call assert_equal(testlen, len(g:Xgetlist()))
1939 Xnewer
1940 Xnewer
1941 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001942endfunc
1943
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001944func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001945 call Xlist_empty_middle('c')
1946 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001947endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001948
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001949func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001950 call s:setup_commands(a:cchar)
1951
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001952 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001953 Xvimgrep one test_quickfix.vim
1954 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001955 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001956 Xvimgrep two test_quickfix.vim
1957 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001958 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001959 Xvimgrep three test_quickfix.vim
1960 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001961 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001962 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001963 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001964 call g:Xsetlist([], 'r')
1965 call assert_true(len(g:Xgetlist()) == 0)
1966 Xnewer
1967 call assert_equal(twolen, len(g:Xgetlist()))
1968 Xnewer
1969 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001970endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001971
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001972func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001973 call Xlist_empty_older('c')
1974 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001975endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001976
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001977func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001978 call s:setup_commands(a:cchar)
1979
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001980 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1981 \ {'filename': 'fnameB', 'text': 'B'}]
1982 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1983 \ {'filename': 'fnameD', 'text': 'D'},
1984 \ {'filename': 'fnameE', 'text': 'E'}]
1985
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001986 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001987 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001988 silent! Xnewer 99
1989 call g:Xsetlist(list1)
1990 call g:Xsetlist(list2)
1991 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001992 call assert_equal(3, len(li))
1993 call assert_equal('C', li[0]['text'])
1994 call assert_equal('D', li[1]['text'])
1995 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001996 silent! Xolder
1997 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001998 call assert_equal(2, len(li))
1999 call assert_equal('A', li[0]['text'])
2000 call assert_equal('B', li[1]['text'])
2001
2002 " {action} is specified ' '.
2003 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002004 silent! Xnewer 99
2005 call g:Xsetlist(list1)
2006 call g:Xsetlist(list2, ' ')
2007 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002008 call assert_equal(3, len(li))
2009 call assert_equal('C', li[0]['text'])
2010 call assert_equal('D', li[1]['text'])
2011 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002012 silent! Xolder
2013 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002014 call assert_equal(2, len(li))
2015 call assert_equal('A', li[0]['text'])
2016 call assert_equal('B', li[1]['text'])
2017
2018 " {action} is specified 'a'.
2019 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002020 silent! Xnewer 99
2021 call g:Xsetlist(list1)
2022 call g:Xsetlist(list2, 'a')
2023 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002024 call assert_equal(5, len(li))
2025 call assert_equal('A', li[0]['text'])
2026 call assert_equal('B', li[1]['text'])
2027 call assert_equal('C', li[2]['text'])
2028 call assert_equal('D', li[3]['text'])
2029 call assert_equal('E', li[4]['text'])
2030
2031 " {action} is specified 'r'.
2032 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002033 silent! Xnewer 99
2034 call g:Xsetlist(list1)
2035 call g:Xsetlist(list2, 'r')
2036 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002037 call assert_equal(3, len(li))
2038 call assert_equal('C', li[0]['text'])
2039 call assert_equal('D', li[1]['text'])
2040 call assert_equal('E', li[2]['text'])
2041
2042 " Test for wrong value.
2043 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002044 call assert_fails("call g:Xsetlist(0)", 'E714:')
2045 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
2046 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
2047 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
2048 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002049endfunc
2050
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002051func Test_setqflist_invalid_nr()
2052 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02002053 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002054endfunc
2055
Bram Moolenaar99234f22020-02-10 22:56:54 +01002056func Test_setqflist_user_sets_buftype()
2057 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
2058 set buftype=quickfix
2059 call setqflist([], 'a')
2060 enew
2061endfunc
2062
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002063func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002064 call XquickfixSetListWithAct('c')
2065 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002066endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002067
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002068func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002069 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002070
Bram Moolenaar049cba92016-06-26 14:38:04 +02002071 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002072 call assert_equal(1, l[0].lnum)
2073 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002074 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002075 call assert_equal(2, l[1].lnum)
2076 call assert_equal(1, l[1].col)
2077 call assert_equal(4070, len(l[1].text))
2078 call assert_equal(3, l[2].lnum)
2079 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002080 call assert_equal(4070, len(l[2].text))
2081 call assert_equal(4, l[3].lnum)
2082 call assert_equal(1, l[3].col)
2083 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002084
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002085 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002086endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002087
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002088func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002089 call s:setup_commands(a:cchar)
2090
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002091 let testfile = 'samples/quickfix.txt'
2092
2093 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002094 exe 'Xgetfile' testfile
2095 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002096
2097 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002098 Xexpr readfile(testfile)
2099 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002100
2101 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002102 Xexpr join(readfile(testfile), "\n")
2103 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002104
2105 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002106 exe 'edit' testfile
2107 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02002108 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002109endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002110
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002111func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002112 call s:long_lines_tests('c')
2113 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002114endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002115
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002116func Test_cgetfile_on_long_lines()
2117 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
2118 " are read at a time.
2119 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002120 let lines =<< trim END
2121 /tmp/file1:1:1:aaa
2122 /tmp/file2:1:1:%s
2123 /tmp/file3:1:1:bbb
2124 /tmp/file4:1:1:ccc
2125 END
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002126 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002127 call writefile(lines, 'Xcqetfile.txt', 'D')
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002128 cgetfile Xcqetfile.txt
2129 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
2130 endfor
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002131endfunc
2132
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002133func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002134 let l = []
2135 for i in range(1, 20)
2136 call add(l, 'Line' . i)
2137 endfor
2138 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002139endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002140
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002141func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002142 call s:create_test_file('Xqftestfile1')
2143 call s:create_test_file('Xqftestfile2')
2144 call s:create_test_file('Xqftestfile3')
2145
2146 new | only
2147 edit Xqftestfile1
2148 let file1_winid = win_getid()
2149 new Xqftestfile2
2150 let file2_winid = win_getid()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002151 let lines =<< trim END
2152 Xqftestfile1:5:Line5
2153 Xqftestfile1:6:Line6
2154 Xqftestfile2:10:Line10
2155 Xqftestfile2:11:Line11
2156 Xqftestfile3:15:Line15
2157 Xqftestfile3:16:Line16
2158 END
2159 cgetexpr lines
Bram Moolenaar049cba92016-06-26 14:38:04 +02002160
2161 new
2162 let winid = win_getid()
2163 cfirst | cnext
2164 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002165 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002166 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002167 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002168 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002169
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002170 " Test for 'switchbuf' set to search for files in windows in the current
2171 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002172 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002173 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02002174 cfirst | cnext
2175 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002176 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002177 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002178 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002179 call assert_equal(file2_winid, win_getid())
2180
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002181 " Test for 'switchbuf' set to search for files in tabpages and jump to an
2182 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002183 enew | only
2184 set switchbuf=usetab
2185 tabedit Xqftestfile1
2186 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01002187 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02002188 tabfirst
2189 cfirst | cnext
2190 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002191 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002192 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002193 6cnext
2194 call assert_equal(4, tabpagenr())
2195 2cpfile
2196 call assert_equal(2, tabpagenr())
2197 2cnfile
2198 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002199 tabfirst | tabonly | enew
2200
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002201 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002202 set switchbuf=split
2203 cfirst | cnext
2204 call assert_equal(1, winnr('$'))
2205 cnext | cnext
2206 call assert_equal(2, winnr('$'))
2207 cnext | cnext
2208 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002209
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002210 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002211 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002212 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002213 cfirst | cnext
2214 call assert_equal(1, tabpagenr('$'))
2215 cnext | cnext
2216 call assert_equal(2, tabpagenr('$'))
2217 cnext | cnext
2218 call assert_equal(3, tabpagenr('$'))
2219 tabfirst | enew | tabonly | only
2220
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002221 set switchbuf=uselast
2222 split
2223 let last_winid = win_getid()
2224 copen
2225 exe "normal 1G\<CR>"
2226 call assert_equal(last_winid, win_getid())
2227 enew | only
2228
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002229 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2230 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002231 set switchbuf=
2232 edit Xqftestfile1
2233 let file1_winid = win_getid()
2234 new Xqftestfile2
2235 let file2_winid = win_getid()
2236 copen
2237 exe "normal 1G\<CR>"
2238 call assert_equal(file1_winid, win_getid())
2239 copen
2240 exe "normal 3G\<CR>"
2241 call assert_equal(file2_winid, win_getid())
2242 copen | only
2243 exe "normal 5G\<CR>"
2244 call assert_equal(2, winnr('$'))
2245 call assert_equal(1, bufwinnr('Xqftestfile3'))
2246
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002247 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002248 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002249 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002250 set switchbuf=usetab
2251 tabedit Xqftestfile1
2252 tabedit Xqftestfile2
2253 tabedit Xqftestfile3
2254 tabfirst
2255 copen | only
2256 clast
2257 call assert_equal(4, tabpagenr())
2258 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002259
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002260 " Jumping to a file that is not present in any of the tabpages and the
2261 " current tabpage doesn't have any usable windows, should open it in a new
2262 " window in the current tabpage.
2263 copen | only
2264 cfirst
2265 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002266 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002267
2268 " If opening a file changes 'switchbuf', then the new value should be
2269 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002270 set modeline&vim
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002271 call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002272 enew | only
2273 set switchbuf&vim
2274 cexpr "Xqftestfile1:1:10"
2275 call assert_equal('split', &switchbuf)
2276 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2277 enew | only
2278 set switchbuf=useopen
2279 cexpr "Xqftestfile1:1:10"
2280 call assert_equal('usetab', &switchbuf)
2281 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2282 enew | only
2283 set switchbuf=useopen
2284 cexpr "Xqftestfile1:1:10"
2285 call assert_equal('', &switchbuf)
2286
Bram Moolenaar049cba92016-06-26 14:38:04 +02002287 call delete('Xqftestfile2')
2288 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002289 set switchbuf&vim
2290
2291 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002292endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002293
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002294func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002295 call s:setup_commands(a:cchar)
2296
2297 enew | only
2298
Bram Moolenaarc1542742016-07-20 21:44:37 +02002299 let fname = 'Xqftestfile' . a:cchar
2300 call s:create_test_file(fname)
2301 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002302
Bram Moolenaarc1542742016-07-20 21:44:37 +02002303 Xgetexpr [fname . ':5:Line5',
2304 \ fname . ':10:Line10',
2305 \ fname . ':15:Line15',
2306 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002307
2308 6,14delete
2309 call append(6, ['Buffer', 'Window'])
2310
2311 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002312 call assert_equal(5, l[0].lnum)
2313 call assert_equal(6, l[2].lnum)
2314 call assert_equal(13, l[3].lnum)
2315
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002316 " If a file doesn't have any quickfix entries, then deleting lines in the
2317 " file should not update the quickfix list
2318 call g:Xsetlist([], 'f')
2319 1,2delete
2320 call assert_equal([], g:Xgetlist())
2321
Bram Moolenaar049cba92016-06-26 14:38:04 +02002322 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002323 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002324endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002325
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002326func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002327 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002328 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002329 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002330 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002331endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002332
2333" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002334func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002335 call s:setup_commands(a:cchar)
2336
2337 " The following lines are used for the grep test. Don't remove.
2338 " Grep_Test_Text: Match 1
2339 " Grep_Test_Text: Match 2
2340 " GrepAdd_Test_Text: Match 1
2341 " GrepAdd_Test_Text: Match 2
2342 enew! | only
2343 set makeef&vim
2344 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002345 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002346 Xopen
2347 call assert_true(w:quickfix_title =~ '^:grep')
2348 Xclose
2349 enew
2350 set makeef=Temp_File_##
2351 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002352 call assert_true(len(g:Xgetlist()) == 9)
2353
2354 " Try with 'grepprg' set to 'internal'
2355 set grepprg=internal
2356 silent Xgrep Grep_Test_Text: test_quickfix.vim
2357 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2358 call assert_true(len(g:Xgetlist()) == 9)
2359 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002360
2361 call writefile(['Vim'], 'XtestTempFile')
2362 set makeef=XtestTempFile
2363 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002364 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002365 call assert_false(filereadable('XtestTempFile'))
2366 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002367endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002368
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002369func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002370 " The grepprg may not be set on non-Unix systems
2371 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002372
2373 call s:test_xgrep('c')
2374 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002375endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002376
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002377func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002378 " Use one 'errorformat' for two windows. Add an expression to each of them,
2379 " make sure they each keep their own state.
2380 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002381 call mkdir('Xone/a', 'pR')
2382 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002383 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2384 call writefile(lines, 'Xone/a/one.txt')
2385 call writefile(lines, 'Xtwo/a/two.txt')
2386
2387 new one
2388 let one_id = win_getid()
2389 lexpr ""
2390 new two
2391 let two_id = win_getid()
2392 lexpr ""
2393
2394 laddexpr "Entering dir 'Xtwo/a'"
2395 call win_gotoid(one_id)
2396 laddexpr "Entering dir 'Xone/a'"
2397 call win_gotoid(two_id)
2398 laddexpr 'two.txt:5:two two two'
2399 call win_gotoid(one_id)
2400 laddexpr 'one.txt:3:one one one'
2401
2402 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002403 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2404 call assert_equal(3, loc_one[1].lnum)
2405
2406 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002407 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2408 call assert_equal(5, loc_two[1].lnum)
2409
2410 call win_gotoid(one_id)
2411 bwipe!
2412 call win_gotoid(two_id)
2413 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002414endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002415
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002416func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002417 call s:setup_commands(a:cchar)
2418
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002419 " Calling lbottom without any errors should fail
2420 if a:cchar == 'l'
2421 call assert_fails('lbottom', 'E776:')
2422 endif
2423
Bram Moolenaar875feea2017-06-11 16:07:51 +02002424 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002425 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002426 let wid = win_getid()
2427 call assert_equal(1, line('.'))
2428 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002429 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002430 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002431 call win_gotoid(wid)
2432 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002433 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002434endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002435
2436" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002437func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002438 call XbottomTests('c')
2439 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002440endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002441
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002442func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002443 call s:setup_commands(a:cchar)
2444
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002445 " clear all lists after the first one, then replace the first one.
2446 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002447 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002448 let entry = {'filename': 'foo', 'lnum': 42}
2449 call g:Xsetlist([entry], 'r')
2450 call g:Xsetlist([entry, entry])
2451 call g:Xsetlist([entry, entry, entry])
2452 let res = split(execute(a:cchar . 'hist'), "\n")
2453 call assert_equal(3, len(res))
2454 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2455 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2456 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2457 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002458
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002459 " Test for changing the quickfix lists
2460 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2461 exe '1' . a:cchar . 'hist'
2462 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2463 exe '3' . a:cchar . 'hist'
2464 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2465 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2466 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2467
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002468 call g:Xsetlist([], 'f')
2469 let l = split(execute(a:cchar . 'hist'), "\n")
2470 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002471 if a:cchar == 'c'
2472 call assert_fails('4chist', 'E16:')
2473 else
2474 call assert_fails('4lhist', 'E776:')
2475 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002476
2477 " An empty list should still show the stack history
2478 call g:Xsetlist([])
2479 let res = split(execute(a:cchar . 'hist'), "\n")
2480 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2481
2482 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002483endfunc
2484
2485func Test_history()
2486 call HistoryTest('c')
2487 call HistoryTest('l')
2488endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002489
2490func Test_duplicate_buf()
2491 " make sure we can get the highest buffer number
2492 edit DoesNotExist
2493 edit DoesNotExist2
2494 let last_buffer = bufnr("$")
2495
2496 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002497 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002498 vimgrep one Xgrepthis
2499 vimgrep one Xgrepthis
2500 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002501endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002502
2503" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002504func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002505 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002506
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002507 " Error cases
2508 call assert_fails('call g:Xgetlist(99)', 'E715:')
2509 call assert_fails('call g:Xsetlist(99)', 'E714:')
2510 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002511
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002512 " Set and get the title
2513 call g:Xsetlist([])
2514 Xopen
2515 wincmd p
2516 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2517 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2518 call assert_equal(0, s)
2519 let d = g:Xgetlist({"title":1})
2520 call assert_equal('Sample', d.title)
2521 " Try setting title to a non-string value
2522 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2523 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2524
2525 Xopen
2526 call assert_equal('Sample', w:quickfix_title)
2527 Xclose
2528
2529 " Tests for action argument
2530 silent! Xolder 999
2531 let qfnr = g:Xgetlist({'all':1}).nr
2532 call g:Xsetlist([], 'r', {'title' : 'N1'})
2533 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2534 call g:Xsetlist([], ' ', {'title' : 'N2'})
2535 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2536
2537 let res = g:Xgetlist({'nr': 0})
2538 call assert_equal(qfnr + 1, res.nr)
2539 call assert_equal(['nr'], keys(res))
2540
2541 call g:Xsetlist([], ' ', {'title' : 'N3'})
2542 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2543
2544 " Changing the title of an earlier quickfix list
2545 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2546 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2547
2548 " Changing the title of an invalid quickfix list
2549 call assert_equal(-1, g:Xsetlist([], ' ',
2550 \ {'title' : 'SomeTitle', 'nr' : 99}))
2551 call assert_equal(-1, g:Xsetlist([], ' ',
2552 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2553
2554 if a:cchar == 'c'
2555 copen
2556 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2557 cclose
2558 endif
2559
2560 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002561 call assert_fails('call g:Xgetlist([])', 'E715:')
2562 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002563 let s = g:Xsetlist([], 'a', {'abc':1})
2564 call assert_equal(-1, s)
2565
2566 call assert_equal({}, g:Xgetlist({'abc':1}))
2567 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2568 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2569
2570 if a:cchar == 'l'
2571 call assert_equal({}, getloclist(99, {'title': 1}))
2572 endif
2573
2574 " Context related tests
2575 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2576 call assert_equal(0, s)
2577 call test_garbagecollect_now()
2578 let d = g:Xgetlist({'context':1})
2579 call assert_equal([1,2,3], d.context)
2580 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2581 let d = g:Xgetlist({'context':1})
2582 call assert_equal({'color':'green'}, d.context)
2583 call g:Xsetlist([], 'a', {'context':"Context info"})
2584 let d = g:Xgetlist({'context':1})
2585 call assert_equal("Context info", d.context)
2586 call g:Xsetlist([], 'a', {'context':246})
2587 let d = g:Xgetlist({'context':1})
2588 call assert_equal(246, d.context)
2589 " set other Vim data types as context
2590 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2591 if has('channel')
2592 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2593 endif
2594 if has('job')
2595 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2596 endif
2597 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2598 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2599 call g:Xsetlist([], 'a', {'context' : ''})
2600 call test_garbagecollect_now()
2601 if a:cchar == 'l'
2602 " Test for copying context across two different location lists
2603 new | only
2604 let w1_id = win_getid()
2605 let l = [1]
2606 call setloclist(0, [], 'a', {'context':l})
2607 new
2608 let w2_id = win_getid()
2609 call add(l, 2)
2610 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2611 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2612 unlet! l
2613 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2614 only
2615 call setloclist(0, [], 'f')
2616 call assert_equal('', getloclist(0, {'context':1}).context)
2617 endif
2618
2619 " Test for changing the context of previous quickfix lists
2620 call g:Xsetlist([], 'f')
2621 Xexpr "One"
2622 Xexpr "Two"
2623 Xexpr "Three"
2624 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2625 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2626 " Also, check for setting the context using quickfix list number zero.
2627 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2628 call test_garbagecollect_now()
2629 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2630 call assert_equal([1], l.context)
2631 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2632 call assert_equal([2], l.context)
2633 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2634 call assert_equal([3], l.context)
2635
2636 " Test for changing the context through reference and for garbage
2637 " collection of quickfix context
2638 let l = ["red"]
2639 call g:Xsetlist([], ' ', {'context' : l})
2640 call add(l, "blue")
2641 let x = g:Xgetlist({'context' : 1})
2642 call add(x.context, "green")
2643 call assert_equal(["red", "blue", "green"], l)
2644 call assert_equal(["red", "blue", "green"], x.context)
2645 unlet l
2646 call test_garbagecollect_now()
2647 let m = g:Xgetlist({'context' : 1})
2648 call assert_equal(["red", "blue", "green"], m.context)
2649
2650 " Test for setting/getting items
2651 Xexpr ""
2652 let qfprev = g:Xgetlist({'nr':0})
2653 let s = g:Xsetlist([], ' ', {'title':'Green',
2654 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2655 call assert_equal(0, s)
2656 let qfcur = g:Xgetlist({'nr':0})
2657 call assert_true(qfcur.nr == qfprev.nr + 1)
2658 let l = g:Xgetlist({'items':1})
2659 call assert_equal('F1', bufname(l.items[0].bufnr))
2660 call assert_equal(10, l.items[0].lnum)
2661 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2662 \ {'filename':'F2', 'lnum':30}]})
2663 let l = g:Xgetlist({'items':1})
2664 call assert_equal('F2', bufname(l.items[2].bufnr))
2665 call assert_equal(30, l.items[2].lnum)
2666 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2667 let l = g:Xgetlist({'items':1})
2668 call assert_equal('F3', bufname(l.items[0].bufnr))
2669 call assert_equal(40, l.items[0].lnum)
2670 call g:Xsetlist([], 'r', {'items' : []})
2671 let l = g:Xgetlist({'items':1})
2672 call assert_equal(0, len(l.items))
2673
2674 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2675 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2676 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2677 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2678
2679 " Test for getting id of window associated with a location list window
2680 if a:cchar == 'l'
2681 only
2682 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2683 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002684 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002685 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2686 wincmd w
2687 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2688 only
2689 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002690
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002691 " The following used to crash Vim with address sanitizer
2692 call g:Xsetlist([], 'f')
2693 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2694 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002695
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002696 " Try setting the items using a string
2697 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002698
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002699 " Save and restore the quickfix stack
2700 call g:Xsetlist([], 'f')
2701 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2702 Xexpr "File1:10:Line1"
2703 Xexpr "File2:20:Line2"
2704 Xexpr "File3:30:Line3"
2705 let last_qf = g:Xgetlist({'nr':'$'}).nr
2706 call assert_equal(3, last_qf)
2707 let qstack = []
2708 for i in range(1, last_qf)
2709 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2710 endfor
2711 call g:Xsetlist([], 'f')
2712 for i in range(len(qstack))
2713 call g:Xsetlist([], ' ', qstack[i])
2714 endfor
2715 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2716 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2717 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2718 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2719 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002720
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002721 " Swap two quickfix lists
2722 Xexpr "File1:10:Line10"
2723 Xexpr "File2:20:Line20"
2724 Xexpr "File3:30:Line30"
2725 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2726 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2727 let l1=g:Xgetlist({'nr':1,'all':1})
2728 let l2=g:Xgetlist({'nr':2,'all':1})
2729 let save_id = l1.id
2730 let l1.id=l2.id
2731 let l2.id=save_id
2732 call g:Xsetlist([], 'r', l1)
2733 call g:Xsetlist([], 'r', l2)
2734 let newl1=g:Xgetlist({'nr':1,'all':1})
2735 let newl2=g:Xgetlist({'nr':2,'all':1})
2736 call assert_equal('Fruits', newl1.title)
2737 call assert_equal(['Fruits'], newl1.context)
2738 call assert_equal('Line20', newl1.items[0].text)
2739 call assert_equal('Colors', newl2.title)
2740 call assert_equal(['Colors'], newl2.context)
2741 call assert_equal('Line10', newl2.items[0].text)
2742 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002743
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002744 " Cannot specify both a non-empty list argument and a dict argument
2745 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002746endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002747
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002748func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002749 call Xproperty_tests('c')
2750 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002751endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002752
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002753" Test for setting the current index in the location/quickfix list
2754func Xtest_setqfidx(cchar)
2755 call s:setup_commands(a:cchar)
2756
2757 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2758 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2759 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2760
2761 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2762 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2763 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2764 Xolder 2
2765 Xopen
2766 call assert_equal(3, line('.'))
2767 Xnewer
2768 call assert_equal(2, line('.'))
2769 Xnewer
2770 call assert_equal(2, line('.'))
2771 " Update the current index with the quickfix window open
2772 wincmd w
2773 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2774 Xopen
2775 call assert_equal(3, line('.'))
2776 Xclose
2777
2778 " Set the current index to the last entry
2779 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2780 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2781 " A large value should set the index to the last index
2782 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2783 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2784 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2785 " Invalid index values
2786 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2787 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2788 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2789 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2790 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2791 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2792 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2793
2794 call g:Xsetlist([], 'f')
2795 new | only
2796endfunc
2797
2798func Test_setqfidx()
2799 call Xtest_setqfidx('c')
2800 call Xtest_setqfidx('l')
2801endfunc
2802
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002803" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002804func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002805 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002806endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002807
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002808func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002809 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2810 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2811
2812 let g:acmds = []
2813 cexpr "F1:10:Line 10"
2814 caddexpr "F1:20:Line 20"
2815 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002816 cexpr ""
2817 caddexpr ""
2818 cgetexpr ""
2819 silent! cexpr non_existing_func()
2820 silent! caddexpr non_existing_func()
2821 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002822 let l =<< trim END
2823 precexpr
2824 postcexpr
2825 precaddexpr
2826 postcaddexpr
2827 precgetexpr
2828 postcgetexpr
2829 precexpr
2830 postcexpr
2831 precaddexpr
2832 postcaddexpr
2833 precgetexpr
2834 postcgetexpr
2835 precexpr
2836 precaddexpr
2837 precgetexpr
2838 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002839 call assert_equal(l, g:acmds)
2840
2841 let g:acmds = []
2842 enew! | call append(0, "F2:10:Line 10")
2843 cbuffer!
2844 enew! | call append(0, "F2:20:Line 20")
2845 cgetbuffer
2846 enew! | call append(0, "F2:30:Line 30")
2847 caddbuffer
2848 new
2849 let bnum = bufnr('%')
2850 bunload
2851 exe 'silent! cbuffer! ' . bnum
2852 exe 'silent! cgetbuffer ' . bnum
2853 exe 'silent! caddbuffer ' . bnum
2854 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002855 let l =<< trim END
2856 precbuffer
2857 postcbuffer
2858 precgetbuffer
2859 postcgetbuffer
2860 precaddbuffer
2861 postcaddbuffer
2862 precbuffer
2863 precgetbuffer
2864 precaddbuffer
2865 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002866 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002867
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002868 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2869 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002870 let g:acmds = []
2871 cfile Xtest
2872 caddfile Xtest
2873 cgetfile Xtest
2874 cfile Xempty
2875 caddfile Xempty
2876 cgetfile Xempty
2877 silent! cfile do_not_exist
2878 silent! caddfile do_not_exist
2879 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002880 let l =<< trim END
2881 precfile
2882 postcfile
2883 precaddfile
2884 postcaddfile
2885 precgetfile
2886 postcgetfile
2887 precfile
2888 postcfile
2889 precaddfile
2890 postcaddfile
2891 precgetfile
2892 postcgetfile
2893 precfile
2894 postcfile
2895 precaddfile
2896 postcaddfile
2897 precgetfile
2898 postcgetfile
2899 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002900 call assert_equal(l, g:acmds)
2901
2902 let g:acmds = []
2903 helpgrep quickfix
2904 silent! helpgrep non_existing_help_topic
2905 vimgrep test Xtest
2906 vimgrepadd test Xtest
2907 silent! vimgrep non_existing_test Xtest
2908 silent! vimgrepadd non_existing_test Xtest
2909 set makeprg=
2910 silent! make
2911 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002912 let l =<< trim END
2913 prehelpgrep
2914 posthelpgrep
2915 prehelpgrep
2916 posthelpgrep
2917 previmgrep
2918 postvimgrep
2919 previmgrepadd
2920 postvimgrepadd
2921 previmgrep
2922 postvimgrep
2923 previmgrepadd
2924 postvimgrepadd
2925 premake
2926 postmake
2927 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002928 call assert_equal(l, g:acmds)
2929
2930 if has('unix')
2931 " Run this test only on Unix-like systems. The grepprg may not be set on
2932 " non-Unix systems.
2933 " The following lines are used for the grep test. Don't remove.
2934 " Grep_Autocmd_Text: Match 1
2935 " GrepAdd_Autocmd_Text: Match 2
2936 let g:acmds = []
2937 silent grep Grep_Autocmd_Text test_quickfix.vim
2938 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2939 silent grep abc123def Xtest
2940 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002941 set grepprg=internal
2942 silent grep Grep_Autocmd_Text test_quickfix.vim
2943 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2944 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2945 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2946 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002947 let l =<< trim END
2948 pregrep
2949 postgrep
2950 pregrepadd
2951 postgrepadd
2952 pregrep
2953 postgrep
2954 pregrepadd
2955 postgrepadd
2956 pregrep
2957 postgrep
2958 pregrepadd
2959 postgrepadd
2960 prelgrep
2961 postlgrep
2962 prelgrepadd
2963 postlgrepadd
2964 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002965 call assert_equal(l, g:acmds)
2966 endif
2967
Bram Moolenaarb254af32017-12-18 19:48:58 +01002968 au! QuickFixCmdPre
2969 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002970endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002971
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002972func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002973 set efm=%m
2974 lgetexpr '?'
2975
2976 try
2977 call DoesNotExit()
2978 catch
2979 lgetexpr '1'
2980 finally
2981 lgetexpr '1'
2982 endtry
2983
2984 call assert_equal('1', getloclist(0)[0].text)
2985
2986 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002987endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002988
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002989func Test_caddbuffer_wrong()
2990 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002991 let save_efm = &efm
2992 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2993 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2994 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002995 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002996 bwipe!
2997endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002998
2999func Test_caddexpr_wrong()
3000 " This used to cause a memory access in freed memory.
3001 cbuffer
3002 cbuffer
3003 copen
3004 let save_efm = &efm
3005 set efm=%
3006 call assert_fails('caddexpr ""', 'E376:')
3007 let &efm = save_efm
3008endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01003009
3010func Test_dirstack_cleanup()
3011 " This used to cause a memory access in freed memory.
3012 let save_efm = &efm
3013 lexpr '0'
3014 lopen
3015 fun X(c)
3016 let save_efm=&efm
3017 set efm=%D%f
3018 if a:c == 'c'
3019 caddexpr '::'
3020 else
3021 laddexpr ':0:0'
3022 endif
3023 let &efm=save_efm
3024 endfun
3025 call X('c')
3026 call X('l')
3027 call setqflist([], 'r')
3028 caddbuffer
3029 let &efm = save_efm
3030endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003031
3032" Tests for jumping to entries from the location list window and quickfix
3033" window
3034func Test_cwindow_jump()
3035 set efm=%f%%%l%%%m
3036 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3037 lopen | only
3038 lfirst
3039 call assert_true(winnr('$') == 2)
3040 call assert_true(winnr() == 1)
3041 " Location list for the new window should be set
3042 call assert_true(getloclist(0)[2].text == 'Line 30')
3043
3044 " Open a scratch buffer
3045 " Open a new window and create a location list
3046 " Open the location list window and close the other window
3047 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003048 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003049 " should not be used.
3050 enew | only
3051 set buftype=nofile
3052 below new
3053 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3054 lopen
3055 2wincmd c
3056 lnext
3057 call assert_true(winnr('$') == 3)
3058 call assert_true(winnr() == 2)
3059
3060 " Open two windows with two different location lists
3061 " Open the location list window and close the previous window
3062 " Jump to an entry in the location list window
3063 " Should open the file in the first window and not set the location list.
3064 enew | only
3065 lgetexpr ["F1%5%Line 5"]
3066 below new
3067 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3068 lopen
3069 2wincmd c
3070 lnext
3071 call assert_true(winnr() == 1)
3072 call assert_true(getloclist(0)[0].text == 'Line 5')
3073
3074 enew | only
3075 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3076 copen
3077 cnext
3078 call assert_true(winnr('$') == 2)
3079 call assert_true(winnr() == 1)
3080
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003081 " open the quickfix buffer in two windows and jump to an entry. Should open
3082 " the file in the first quickfix window.
3083 enew | only
3084 copen
3085 let bnum = bufnr('')
3086 exe 'sbuffer ' . bnum
3087 wincmd b
3088 cfirst
3089 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003090 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003091 enew | only
3092 exe 'sb' bnum
3093 exe 'botright sb' bnum
3094 wincmd t
3095 clast
3096 call assert_equal(2, winnr())
3097 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3098 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3099
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003100 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003101 " window by wrapping around the window list.
3102 enew | only
3103 call setloclist(0, [], 'f')
3104 new | new
3105 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3106 lopen
3107 1close
3108 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3109 lnext
3110 call assert_equal(3, winnr())
3111 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3112
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003113 enew | only
3114 set efm&vim
3115endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003116
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003117func Test_cwindow_highlight()
3118 CheckScreendump
3119
3120 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003121 call setline(1, ['some', 'text', 'with', 'matches'])
3122 write XCwindow
3123 vimgrep e XCwindow
3124 redraw
3125 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003126 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003127 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003128 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3129 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3130
3131 call term_sendkeys(buf, ":cnext\<CR>")
3132 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3133
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003134 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003135 call term_sendkeys(buf, ":\<CR>")
3136 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3137
3138 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3139 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003140 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3141
3142 call term_sendkeys(buf, "j")
3143 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3144
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003145 " clean up
3146 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003147 call delete('XCwindow')
3148endfunc
3149
Bram Moolenaaree85df32017-03-19 14:19:50 +01003150func XvimgrepTests(cchar)
3151 call s:setup_commands(a:cchar)
3152
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003153 let lines =<< trim END
3154 Editor:VIM vim
3155 Editor:Emacs EmAcS
3156 Editor:Notepad NOTEPAD
3157 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003158 call writefile(lines, 'Xtestfile1', 'D')
3159 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003160
3161 " Error cases
3162 call assert_fails('Xvimgrep /abc *', 'E682:')
3163
3164 let @/=''
3165 call assert_fails('Xvimgrep // *', 'E35:')
3166
3167 call assert_fails('Xvimgrep abc', 'E683:')
3168 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3169 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3170
3171 Xexpr ""
3172 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003173 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003174 let l = g:Xgetlist()
3175 call assert_equal(2, len(l))
3176 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3177
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003178 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003179 let l = g:Xgetlist()
3180 call assert_equal(2, len(l))
3181 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003182 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003183 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003184 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003185
3186 1Xvimgrep ?Editor? Xtestfile*
3187 let l = g:Xgetlist()
3188 call assert_equal(1, len(l))
3189 call assert_equal('Editor:VIM vim', l[0].text)
3190
3191 edit +3 Xtestfile2
3192 Xvimgrep +\cemacs+j Xtestfile1
3193 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003194 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003195 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3196
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003197 " Test for unloading a buffer after vimgrep searched the buffer
3198 %bwipe
3199 Xvimgrep /Editor/j Xtestfile*
3200 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3201 call assert_equal([], getbufinfo('Xtestfile2'))
3202
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003203 " Test for opening the dummy buffer used by vimgrep in a window. The new
3204 " window should be closed
3205 %bw!
3206 augroup QF_Test
3207 au!
3208 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3209 augroup END
3210 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3211 call assert_equal(1, winnr('$'))
3212 augroup QF_Test
3213 au!
3214 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003215endfunc
3216
3217" Tests for the :vimgrep command
3218func Test_vimgrep()
3219 call XvimgrepTests('c')
3220 call XvimgrepTests('l')
3221endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003222
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003223func Test_vimgrep_wildcards_expanded_once()
3224 new X[id-01] file.txt
3225 call setline(1, 'some text to search for')
3226 vimgrep text %
3227 bwipe!
3228endfunc
3229
Bram Moolenaar1c299432018-10-28 14:36:09 +01003230" Test for incsearch highlighting of the :vimgrep pattern
3231" This test used to cause "E315: ml_get: invalid lnum" errors.
3232func Test_vimgrep_incsearch()
3233 enew
3234 set incsearch
3235 call test_override("char_avail", 1)
3236
3237 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3238 let l = getqflist()
3239 call assert_equal(2, len(l))
3240
3241 call test_override("ALL", 0)
3242 set noincsearch
3243endfunc
3244
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003245" Test vimgrep with the last search pattern not set
3246func Test_vimgrep_with_no_last_search_pat()
3247 let lines =<< trim [SCRIPT]
3248 call assert_fails('vimgrep // *', 'E35:')
3249 call writefile(v:errors, 'Xresult')
3250 qall!
3251 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003252 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003253 if RunVim([], [], '--clean -S Xscript')
3254 call assert_equal([], readfile('Xresult'))
3255 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003256 call delete('Xresult')
3257endfunc
3258
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003259" Test vimgrep without swap file
3260func Test_vimgrep_without_swap_file()
3261 let lines =<< trim [SCRIPT]
3262 vimgrep grep test_c*
3263 call writefile(['done'], 'Xresult')
3264 qall!
3265 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003266 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003267 if RunVim([], [], '--clean -n -S Xscript Xscript')
3268 call assert_equal(['done'], readfile('Xresult'))
3269 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003270 call delete('Xresult')
3271endfunc
3272
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003273func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003274 call writefile(['match apple with apple'], 'Xapple', 'D')
3275 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003276 let g:foundSwap = 0
3277 let g:ignoreSwapExists = 1
3278 augroup grep
3279 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3280 augroup END
3281 vimgrep apple Xapple
3282 call assert_equal(1, g:foundSwap)
3283 call assert_match('.Xapple.swo', swapname(''))
3284
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003285 augroup grep
3286 au! SwapExists
3287 augroup END
3288 unlet g:ignoreSwapExists
3289endfunc
3290
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003291func XfreeTests(cchar)
3292 call s:setup_commands(a:cchar)
3293
3294 enew | only
3295
3296 " Deleting the quickfix stack should work even When the current list is
3297 " somewhere in the middle of the stack
3298 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3299 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3300 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3301 Xolder
3302 call g:Xsetlist([], 'f')
3303 call assert_equal(0, len(g:Xgetlist()))
3304
3305 " After deleting the stack, adding a new list should create a stack with a
3306 " single list.
3307 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3308 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3309
3310 " Deleting the stack from a 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 call g:Xsetlist([], 'f')
3318 call assert_equal(2, winnr('$'))
3319 call assert_equal(1, line('$'))
3320 Xclose
3321
3322 " Deleting the stack from a non-quickfix window should update/clear the
3323 " quickfix/location list window.
3324 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3325 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3326 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3327 Xolder
3328 Xwindow
3329 wincmd p
3330 call g:Xsetlist([], 'f')
3331 call assert_equal(0, len(g:Xgetlist()))
3332 wincmd p
3333 call assert_equal(2, winnr('$'))
3334 call assert_equal(1, line('$'))
3335
3336 " After deleting the location list stack, if the location list window is
3337 " opened, then a new location list should be created. So opening the
3338 " location list window again should not create a new window.
3339 if a:cchar == 'l'
3340 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3341 wincmd p
3342 lopen
3343 call assert_equal(2, winnr('$'))
3344 endif
3345 Xclose
3346endfunc
3347
Bram Moolenaar74240d32017-12-10 15:26:15 +01003348" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003349func Test_qf_free()
3350 call XfreeTests('c')
3351 call XfreeTests('l')
3352endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003353
3354" Test for buffer overflow when parsing lines and adding new entries to
3355" the quickfix list.
3356func Test_bufoverflow()
3357 set efm=%f:%l:%m
3358 cgetexpr ['File1:100:' . repeat('x', 1025)]
3359
3360 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3361 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3362
3363 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003364 let lines =<< trim eval END
3365 Entering directory $"{repeat('a', 1006)}"
3366 File1:10:Hello World
3367 END
3368 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003369 set efm&vim
3370endfunc
3371
Bram Moolenaar875feea2017-06-11 16:07:51 +02003372" Tests for getting the quickfix stack size
3373func XsizeTests(cchar)
3374 call s:setup_commands(a:cchar)
3375
3376 call g:Xsetlist([], 'f')
3377 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003378 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3379 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003380
3381 Xexpr "File1:10:Line1"
3382 Xexpr "File2:20:Line2"
3383 Xexpr "File3:30:Line3"
3384 Xolder | Xolder
3385 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3386 call g:Xsetlist([], 'f')
3387
3388 Xexpr "File1:10:Line1"
3389 Xexpr "File2:20:Line2"
3390 Xexpr "File3:30:Line3"
3391 Xolder | Xolder
3392 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3393 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3394endfunc
3395
3396func Test_Qf_Size()
3397 call XsizeTests('c')
3398 call XsizeTests('l')
3399endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003400
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003401func Test_cclose_from_copen()
3402 augroup QF_Test
3403 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003404 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003405 augroup END
3406 copen
3407 augroup QF_Test
3408 au!
3409 augroup END
3410 augroup! QF_Test
3411endfunc
3412
Bram Moolenaar18141832017-06-25 21:17:25 +02003413func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003414 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003415 " event will be triggered.
3416 call test_override('starting', 1)
3417 augroup QF_Test
3418 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003419 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003420 augroup END
3421 copen
3422 augroup QF_Test
3423 au!
3424 augroup END
3425 augroup! QF_Test
3426 call test_override('starting', 0)
3427endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003428
Bram Moolenaar379fb762018-08-30 15:58:28 +02003429" Check that ":file" without an argument is possible even when "curbuf_lock"
3430" is set.
3431func Test_file_from_copen()
3432 " Works without argument.
3433 augroup QF_Test
3434 au!
3435 au FileType qf file
3436 augroup END
3437 copen
3438
3439 augroup QF_Test
3440 au!
3441 augroup END
3442 cclose
3443
3444 " Fails with argument.
3445 augroup QF_Test
3446 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003447 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003448 augroup END
3449 copen
3450 augroup QF_Test
3451 au!
3452 augroup END
3453 cclose
3454
3455 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003456endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003457
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003458func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003459 augroup QF_Test
3460 au!
3461 au FileType qf resize 5
3462 augroup END
3463 try
3464 " This should succeed without any exception. No other buffers are
3465 " involved in the autocmd.
3466 copen
3467 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003468 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003469 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003470 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003471 augroup! QF_Test
3472 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003473endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003474
Bram Moolenaard0fab102022-10-20 16:03:33 +01003475func Test_filetype_autocmd()
3476 " this changes the location list while it is in use to fill a buffer
3477 lexpr ''
3478 lopen
3479 augroup FT_loclist
3480 au FileType * call setloclist(0, [], 'f')
3481 augroup END
3482 silent! lolder
3483 lexpr ''
3484
3485 augroup FT_loclist
3486 au! FileType
3487 augroup END
3488endfunc
3489
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003490func Test_vimgrep_with_textlock()
3491 new
3492
zeertzjqcfe45652022-05-27 17:26:55 +01003493 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003494 " Check that vimgrep without jumping can be executed.
3495 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3496 normal ax
3497 let qflist = getqflist()
3498 call assert_true(len(qflist) > 0)
3499 call assert_match('RunTheTest', qflist[0].text)
3500 call setqflist([], 'r')
3501 au! InsertCharPre
3502
3503 " Check that vimgrepadd without jumping can be executed.
3504 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3505 normal ax
3506 let qflist = getqflist()
3507 call assert_true(len(qflist) > 0)
3508 call assert_match('RunTheTest', qflist[0].text)
3509 call setqflist([], 'r')
3510 au! InsertCharPre
3511
3512 " Check that lvimgrep without jumping can be executed.
3513 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3514 normal ax
3515 let qflist = getloclist(0)
3516 call assert_true(len(qflist) > 0)
3517 call assert_match('RunTheTest', qflist[0].text)
3518 call setloclist(0, [], 'r')
3519 au! InsertCharPre
3520
3521 " Check that lvimgrepadd without jumping can be executed.
3522 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3523 normal ax
3524 let qflist = getloclist(0)
3525 call assert_true(len(qflist) > 0)
3526 call assert_match('RunTheTest', qflist[0].text)
3527 call setloclist(0, [], 'r')
3528 au! InsertCharPre
3529
3530 " trying to jump will give an error
3531 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3532 call assert_fails('normal ax', 'E565:')
3533 au! InsertCharPre
3534
3535 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3536 call assert_fails('normal ax', 'E565:')
3537 au! InsertCharPre
3538
3539 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3540 call assert_fails('normal ax', 'E565:')
3541 au! InsertCharPre
3542
3543 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3544 call assert_fails('normal ax', 'E565:')
3545 au! InsertCharPre
3546
3547 bwipe!
3548endfunc
3549
Bram Moolenaara8788f42017-07-19 17:06:20 +02003550" Tests for the quickfix buffer b:changedtick variable
3551func Xchangedtick_tests(cchar)
3552 call s:setup_commands(a:cchar)
3553
3554 new | only
3555
3556 Xexpr "" | Xexpr "" | Xexpr ""
3557
3558 Xopen
3559 Xolder
3560 Xolder
3561 Xaddexpr "F1:10:Line10"
3562 Xaddexpr "F2:20:Line20"
3563 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3564 call g:Xsetlist([], 'f')
3565 call assert_equal(8, getbufvar('%', 'changedtick'))
3566 Xclose
3567endfunc
3568
3569func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003570 call Xchangedtick_tests('c')
3571 call Xchangedtick_tests('l')
3572endfunc
3573
3574" Tests for parsing an expression using setqflist()
3575func Xsetexpr_tests(cchar)
3576 call s:setup_commands(a:cchar)
3577
3578 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003579 call g:Xsetlist([], ' ', {'lines' : t})
3580 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003581
3582 let l = g:Xgetlist()
3583 call assert_equal(3, len(l))
3584 call assert_equal(20, l[1].lnum)
3585 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003586 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003587 let l = g:Xgetlist()
3588 call assert_equal(1, len(l))
3589 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003590 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3591 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003592
3593 call g:Xsetlist([], 'f')
3594 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003595 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3596 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3597 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3598 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003599 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3600 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003601
3602 " Adding entries using a custom efm
3603 set efm&
3604 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3605 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3606 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3607 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3608 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3609 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3610 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3611 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003612endfunc
3613
3614func Test_setexpr()
3615 call Xsetexpr_tests('c')
3616 call Xsetexpr_tests('l')
3617endfunc
3618
3619" Tests for per quickfix/location list directory stack
3620func Xmultidirstack_tests(cchar)
3621 call s:setup_commands(a:cchar)
3622
3623 call g:Xsetlist([], 'f')
3624 Xexpr "" | Xexpr ""
3625
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003626 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3627 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3628 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3629 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003630
3631 let l1 = g:Xgetlist({'nr':1, 'items':1})
3632 let l2 = g:Xgetlist({'nr':2, 'items':1})
3633 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3634 call assert_equal(3, l1.items[1].lnum)
3635 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3636 call assert_equal(5, l2.items[1].lnum)
3637endfunc
3638
3639func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003640 call mkdir('Xone/a', 'pR')
3641 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003642 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3643 call writefile(lines, 'Xone/a/one.txt')
3644 call writefile(lines, 'Xtwo/a/two.txt')
3645 let save_efm = &efm
3646 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3647
3648 call Xmultidirstack_tests('c')
3649 call Xmultidirstack_tests('l')
3650
3651 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003652endfunc
3653
3654" Tests for per quickfix/location list file stack
3655func Xmultifilestack_tests(cchar)
3656 call s:setup_commands(a:cchar)
3657
3658 call g:Xsetlist([], 'f')
3659 Xexpr "" | Xexpr ""
3660
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003661 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3662 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3663 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3664 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003665
3666 let l1 = g:Xgetlist({'nr':1, 'items':1})
3667 let l2 = g:Xgetlist({'nr':2, 'items':1})
3668 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3669 call assert_equal(3, l1.items[1].lnum)
3670 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3671 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003672
3673 " Test for start of a new error line in the same line where a previous
3674 " error line ends with a file stack.
3675 let efm_val = 'Error\ l%l\ in\ %f,'
3676 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003677 let lines =<< trim END
3678 (one.txt
3679 Error l4 in one.txt
3680 ) (two.txt
3681 Error l6 in two.txt
3682 )
3683 Error l8 in one.txt
3684 END
3685 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003686 call assert_equal(3, len(l.items))
3687 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3688 call assert_equal(4, l.items[0].lnum)
3689 call assert_equal('one.txt', l.items[0].text)
3690 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3691 call assert_equal(6, l.items[1].lnum)
3692 call assert_equal('two.txt', l.items[1].text)
3693 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3694 call assert_equal(8, l.items[2].lnum)
3695 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003696endfunc
3697
3698func Test_multifilestack()
3699 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003700 call writefile(lines, 'one.txt', 'D')
3701 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003702 let save_efm = &efm
3703 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3704
3705 call Xmultifilestack_tests('c')
3706 call Xmultifilestack_tests('l')
3707
3708 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003709endfunc
3710
3711" Tests for per buffer 'efm' setting
3712func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003713 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3714 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003715 set efm=%f#%l#%m
3716 new | only
3717 new
3718 setlocal efm=%f-%l-%m
3719 cfile one.txt
3720 wincmd w
3721 caddfile two.txt
3722
3723 let l = getqflist()
3724 call assert_equal(10, l[0].lnum)
3725 call assert_equal('Line20', l[1].text)
3726
3727 set efm&
3728 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003729endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003730
3731" Open multiple help windows using ":lhelpgrep
3732" This test used to crash Vim
3733func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003734 new | only
3735 lhelpgrep window
3736 lopen
3737 e#
3738 lhelpgrep buffer
3739 call assert_equal(3, winnr('$'))
3740 call assert_true(len(getloclist(1)) != 0)
3741 call assert_true(len(getloclist(2)) != 0)
3742 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003743endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003744
3745" Tests for adding new quickfix lists using setqflist()
3746func XaddQf_tests(cchar)
3747 call s:setup_commands(a:cchar)
3748
3749 " Create a new list using ' ' for action
3750 call g:Xsetlist([], 'f')
3751 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3752 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3753 call assert_equal(1, l.nr)
3754 call assert_equal('Test1', l.title)
3755
3756 " Create a new list using ' ' for action and '$' for 'nr'
3757 call g:Xsetlist([], 'f')
3758 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3759 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3760 call assert_equal(1, l.nr)
3761 call assert_equal('Test2', l.title)
3762
3763 " Create a new list using 'a' for action
3764 call g:Xsetlist([], 'f')
3765 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3766 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3767 call assert_equal(1, l.nr)
3768 call assert_equal('Test3', l.title)
3769
3770 " Create a new list using 'a' for action and '$' for 'nr'
3771 call g:Xsetlist([], 'f')
3772 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3773 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3774 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3775 call assert_equal(1, l.nr)
3776 call assert_equal('Test4', l.title)
3777
3778 " Adding a quickfix list should remove all the lists following the current
3779 " list.
3780 Xexpr "" | Xexpr "" | Xexpr ""
3781 silent! 10Xolder
3782 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3783 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3784 call assert_equal(2, l.nr)
3785 call assert_equal('Test5', l.title)
3786
3787 " Add a quickfix list using '$' as the list number.
3788 let lastqf = g:Xgetlist({'nr':'$'}).nr
3789 silent! 99Xolder
3790 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3791 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3792 call assert_equal(lastqf + 1, l.nr)
3793 call assert_equal('Test6', l.title)
3794
3795 " Add a quickfix list using 'nr' set to one more than the quickfix
3796 " list size.
3797 let lastqf = g:Xgetlist({'nr':'$'}).nr
3798 silent! 99Xolder
3799 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3800 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3801 call assert_equal(lastqf + 1, l.nr)
3802 call assert_equal('Test7', l.title)
3803
3804 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3805 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3806 silent! 99Xolder
3807 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3808 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3809 call assert_equal(10, l.nr)
3810 call assert_equal('Test8', l.title)
3811
3812 " Add a quickfix list using 'nr' set to a value greater than 10
3813 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3814
3815 " Try adding a quickfix list with 'nr' set to a value greater than the
3816 " quickfix list size but less than 10.
3817 call g:Xsetlist([], 'f')
3818 Xexpr "" | Xexpr "" | Xexpr ""
3819 silent! 99Xolder
3820 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3821
3822 " Add a quickfix list using 'nr' set to a some string or list
3823 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3824endfunc
3825
3826func Test_add_qf()
3827 call XaddQf_tests('c')
3828 call XaddQf_tests('l')
3829endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003830
3831" Test for getting the quickfix list items from some text without modifying
3832" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003833func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003834 call s:setup_commands(a:cchar)
3835 call g:Xsetlist([], 'f')
3836
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003837 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003838 call assert_equal(2, len(l))
3839 call assert_equal(30, l[1].lnum)
3840
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003841 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3842 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3843 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3844 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003845
Bram Moolenaar36538222017-09-02 19:51:44 +02003846 " Parse text using a custom efm
3847 set efm&
3848 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3849 call assert_equal('Line30', l[0].text)
3850 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3851 call assert_equal('File3:30:Line30', l[0].text)
3852 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3853 call assert_equal({}, l)
3854 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3855 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3856
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003857 " Make sure that the quickfix stack is not modified
3858 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3859endfunc
3860
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003861func Test_get_list_from_lines()
3862 call XgetListFromLines('c')
3863 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003864endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003865
3866" Tests for the quickfix list id
3867func Xqfid_tests(cchar)
3868 call s:setup_commands(a:cchar)
3869
3870 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003871 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003872 Xexpr ''
3873 let start_id = g:Xgetlist({'id' : 0}).id
3874 Xexpr '' | Xexpr ''
3875 Xolder
3876 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3877 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3878 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003879 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003880 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003881 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3882 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003883
3884 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3885 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003886 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003887 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3888 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3889 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3890
3891 let qfid = g:Xgetlist({'id':0, 'nr':0})
3892 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003893 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003894endfunc
3895
3896func Test_qf_id()
3897 call Xqfid_tests('c')
3898 call Xqfid_tests('l')
3899endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003900
3901func Xqfjump_tests(cchar)
3902 call s:setup_commands(a:cchar)
3903
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003904 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3905 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3906 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003907
3908 call g:Xsetlist([], 'f')
3909
3910 " Tests for
3911 " Jumping to a line using a pattern
3912 " Jumping to a column greater than the last column in a line
3913 " Jumping to a line greater than the last line in the file
3914 let l = []
3915 for i in range(1, 7)
3916 call add(l, {})
3917 endfor
3918 let l[0].filename='F1'
3919 let l[0].pattern='Line1'
3920 let l[1].filename='F2'
3921 let l[1].pattern='Line1'
3922 let l[2].filename='F3'
3923 let l[2].pattern='Line1'
3924 let l[3].filename='F3'
3925 let l[3].lnum=1
3926 let l[3].col=9
3927 let l[3].vcol=1
3928 let l[4].filename='F3'
3929 let l[4].lnum=99
3930 let l[5].filename='F3'
3931 let l[5].lnum=1
3932 let l[5].col=99
3933 let l[5].vcol=1
3934 let l[6].filename='F3'
3935 let l[6].pattern='abcxyz'
3936
3937 call g:Xsetlist([], ' ', {'items' : l})
3938 Xopen | only
3939 2Xnext
3940 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003941 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003942 Xnext
3943 call assert_equal(7, col('.'))
3944 Xnext
3945 call assert_equal(2, line('.'))
3946 Xnext
3947 call assert_equal(9, col('.'))
3948 2
3949 Xnext
3950 call assert_equal(2, line('.'))
3951
3952 if a:cchar == 'l'
3953 " When jumping to a location list entry in the location list window and
3954 " no usable windows are available, then a new window should be opened.
3955 enew! | new | only
3956 call g:Xsetlist([], 'f')
3957 setlocal buftype=nofile
3958 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003959 let lines =<< trim END
3960 F1:1:1:Line1
3961 F1:2:2:Line2
3962 F2:1:1:Line1
3963 F2:2:2:Line2
3964 F3:1:1:Line1
3965 F3:2:2:Line2
3966 END
3967 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003968 Xopen
3969 let winid = win_getid()
3970 wincmd p
3971 close
3972 call win_gotoid(winid)
3973 Xnext
3974 call assert_equal(3, winnr('$'))
3975 call assert_equal(1, winnr())
3976 call assert_equal(2, line('.'))
3977
3978 " When jumping to an entry in the location list window and the window
3979 " associated with the location list is not present and a window containing
3980 " the file is already present, then that window should be used.
3981 close
3982 belowright new
3983 call g:Xsetlist([], 'f')
3984 edit F3
3985 call win_gotoid(winid)
3986 Xlast
3987 call assert_equal(3, winnr())
3988 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3989 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3990 endif
3991
3992 " Cleanup
3993 enew!
3994 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01003995endfunc
3996
3997func Test_qfjump()
3998 call Xqfjump_tests('c')
3999 call Xqfjump_tests('l')
4000endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01004001
4002" Tests for the getqflist() and getloclist() functions when the list is not
4003" present or is empty
4004func Xgetlist_empty_tests(cchar)
4005 call s:setup_commands(a:cchar)
4006
4007 " Empty quickfix stack
4008 call g:Xsetlist([], 'f')
4009 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4010 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
4011 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4012 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4013 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4014 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4015 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4016 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004017 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004018 if a:cchar == 'c'
4019 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004020 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004021 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4022 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004023 else
4024 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4025 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004026 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004027 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004028 \ g:Xgetlist({'all' : 0}))
4029 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004030
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004031 " Quickfix window with empty stack
4032 silent! Xopen
4033 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004034 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004035 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4036 Xclose
4037
Bram Moolenaara6d48492017-12-12 22:45:31 +01004038 " Empty quickfix list
4039 Xexpr ""
4040 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4041 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4042 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4043 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4044 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4045 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4046 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4047 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004048 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004049
4050 let qfid = g:Xgetlist({'id' : 0}).id
4051 call g:Xsetlist([], 'f')
4052
4053 " Non-existing quickfix identifier
4054 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4055 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4056 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4057 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4058 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4059 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4060 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4061 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004062 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004063 if a:cchar == 'c'
4064 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4065 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004066 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004067 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4068 else
4069 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4070 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004071 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4072 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004073 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4074 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004075
4076 " Non-existing quickfix list number
4077 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4078 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4079 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4080 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4081 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4082 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4083 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4084 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004085 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004086 if a:cchar == 'c'
4087 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4088 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004089 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4090 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004091 else
4092 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4093 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004094 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4095 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004096 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004097endfunc
4098
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004099func Test_empty_list_quickfixtextfunc()
4100 " This was crashing. Can only reproduce by running it in a separate Vim
4101 " instance.
4102 let lines =<< trim END
4103 func s:Func(o)
4104 cgetexpr '0'
4105 endfunc
4106 cope
4107 let &quickfixtextfunc = 's:Func'
4108 cgetfile [ex
4109 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004110 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004111 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004112endfunc
4113
Bram Moolenaara6d48492017-12-12 22:45:31 +01004114func Test_getqflist()
4115 call Xgetlist_empty_tests('c')
4116 call Xgetlist_empty_tests('l')
4117endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004118
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004119func Test_getqflist_invalid_nr()
4120 " The following commands used to crash Vim
4121 cexpr ""
4122 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4123
4124 " Cleanup
4125 call setqflist([], 'r')
4126endfunc
4127
Bram Moolenaarb254af32017-12-18 19:48:58 +01004128" Tests for the quickfix/location list changedtick
4129func Xqftick_tests(cchar)
4130 call s:setup_commands(a:cchar)
4131
4132 call g:Xsetlist([], 'f')
4133
4134 Xexpr "F1:10:Line10"
4135 let qfid = g:Xgetlist({'id' : 0}).id
4136 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4137 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4138 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4139 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4140 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4141 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4142 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4143 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4144 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4145
4146 enew!
4147 call append(0, ["F5:50:L50", "F6:60:L60"])
4148 Xaddbuffer
4149 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4150 enew!
4151
4152 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4153 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4154 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4155 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4156 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4157 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4158 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4159 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4160 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4161 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4162 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4163
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004164 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004165 Xfile Xone
4166 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4167 Xaddfile Xone
4168 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4169
4170 " Test case for updating a non-current quickfix list
4171 call g:Xsetlist([], 'f')
4172 Xexpr "F1:1:L1"
4173 Xexpr "F2:2:L2"
4174 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4175 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4176 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004177endfunc
4178
4179func Test_qf_tick()
4180 call Xqftick_tests('c')
4181 call Xqftick_tests('l')
4182endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004183
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004184" Test helpgrep with lang specifier
4185func Xtest_helpgrep_with_lang_specifier(cchar)
4186 call s:setup_commands(a:cchar)
4187 Xhelpgrep Vim@en
4188 call assert_equal('help', &filetype)
4189 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4190 new | only
4191endfunc
4192
4193func Test_helpgrep_with_lang_specifier()
4194 call Xtest_helpgrep_with_lang_specifier('c')
4195 call Xtest_helpgrep_with_lang_specifier('l')
4196endfunc
4197
Bram Moolenaar12237442017-12-19 12:38:52 +01004198" The following test used to crash Vim.
4199" Open the location list window and close the regular window associated with
4200" the location list. When the garbage collection runs now, it incorrectly
4201" marks the location list context as not in use and frees the context.
4202func Test_ll_window_ctx()
4203 call setloclist(0, [], 'f')
4204 call setloclist(0, [], 'a', {'context' : []})
4205 lopen | only
4206 call test_garbagecollect_now()
4207 echo getloclist(0, {'context' : 1}).context
4208 enew | only
4209endfunc
4210
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004211" The following test used to crash vim
4212func Test_lfile_crash()
4213 sp Xtest
4214 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004215 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004216 au! QuickFixCmdPre
4217endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004218
4219" The following test used to crash vim
4220func Test_lbuffer_crash()
4221 sv Xtest
4222 augroup QF_Test
4223 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004224 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004225 augroup END
4226 lbuffer
4227 augroup QF_Test
4228 au!
4229 augroup END
4230endfunc
4231
4232" The following test used to crash vim
4233func Test_lexpr_crash()
4234 augroup QF_Test
4235 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004236 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004237 augroup END
4238 lexpr ""
4239 augroup QF_Test
4240 au!
4241 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004242
Bram Moolenaar3c097222017-12-21 20:54:49 +01004243 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004244 augroup QF_Test
4245 au!
4246 au BufNew * call setloclist(0, [], 'f')
4247 augroup END
4248 lexpr 'x:1:x'
4249 augroup QF_Test
4250 au!
4251 augroup END
4252
4253 enew | only
4254 lexpr ''
4255 lopen
4256 augroup QF_Test
4257 au!
4258 au FileType * call setloclist(0, [], 'f')
4259 augroup END
4260 lexpr ''
4261 augroup QF_Test
4262 au!
4263 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004264endfunc
4265
4266" The following test used to crash Vim
4267func Test_lvimgrep_crash()
4268 sv Xtest
4269 augroup QF_Test
4270 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004271 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004272 augroup END
4273 lvimgrep quickfix test_quickfix.vim
4274 augroup QF_Test
4275 au!
4276 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004277
4278 new | only
4279 augroup QF_Test
4280 au!
4281 au BufEnter * call setloclist(0, [], 'r')
4282 augroup END
4283 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4284 augroup QF_Test
4285 au!
4286 augroup END
4287
Bram Moolenaar3c097222017-12-21 20:54:49 +01004288 enew | only
4289endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004290
Bram Moolenaar2573af32020-03-14 17:21:34 +01004291func Test_lvimgrep_crash2()
4292 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004293 call assert_fails('lvimgrep x x', 'E471:')
4294 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004295
4296 au! BufNewFile
4297endfunc
4298
Bram Moolenaarde046542017-12-26 13:53:11 +01004299" Test for the position of the quickfix and location list window
4300func Test_qfwin_pos()
4301 " Open two windows
4302 new | only
4303 new
4304 cexpr ['F1:10:L10']
4305 copen
4306 " Quickfix window should be the bottom most window
4307 call assert_equal(3, winnr())
4308 close
4309 " Open at the very top
4310 wincmd t
4311 topleft copen
4312 call assert_equal(1, winnr())
4313 close
4314 " open left of the current window
4315 wincmd t
4316 below new
4317 leftabove copen
4318 call assert_equal(2, winnr())
4319 close
4320 " open right of the current window
4321 rightbelow copen
4322 call assert_equal(3, winnr())
4323 close
4324endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004325
4326" Tests for quickfix/location lists changed by autocommands when
4327" :vimgrep/:lvimgrep commands are running.
4328func Test_vimgrep_autocmd()
4329 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004330 call writefile(['stars'], 'Xtest1.txt', 'D')
4331 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004332
4333 " Test 1:
4334 " When searching for a pattern using :vimgrep, if the quickfix list is
4335 " changed by an autocmd, the results should be added to the correct quickfix
4336 " list.
4337 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4338 silent vimgrep stars Xtest*.txt
4339 call assert_equal(1, getqflist({'nr' : 0}).nr)
4340 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4341 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4342 au! BufRead Xtest2.txt
4343
4344 " Test 2:
4345 " When searching for a pattern using :vimgrep, if the quickfix list is
4346 " freed, then a error should be given.
4347 silent! %bwipe!
4348 call setqflist([], 'f')
4349 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4350 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4351 au! BufRead Xtest2.txt
4352
4353 " Test 3:
4354 " When searching for a pattern using :lvimgrep, if the location list is
4355 " freed, then the command should error out.
4356 silent! %bwipe!
4357 let g:save_winid = win_getid()
4358 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4359 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4360 au! BufRead Xtest2.txt
4361
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004362 call setqflist([], 'f')
4363endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004364
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004365" Test for an autocmd changing the current directory when running vimgrep
4366func Xvimgrep_autocmd_cd(cchar)
4367 call s:setup_commands(a:cchar)
4368
4369 %bwipe
4370 let save_cwd = getcwd()
4371
4372 augroup QF_Test
4373 au!
4374 autocmd BufRead * silent cd %:p:h
4375 augroup END
4376
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004377 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004378 let l = g:Xgetlist()
4379 call assert_equal('f1.txt', bufname(l[0].bufnr))
4380 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4381
4382 augroup QF_Test
4383 au!
4384 augroup END
4385
4386 exe 'cd ' . save_cwd
4387endfunc
4388
4389func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004390 call mkdir('Xgrepdir/a', 'pR')
4391 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004392 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4393 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004394 call Xvimgrep_autocmd_cd('c')
4395 call Xvimgrep_autocmd_cd('l')
4396 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004397endfunc
4398
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004399" The following test used to crash Vim
4400func Test_lhelpgrep_autocmd()
4401 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004402 augroup QF_Test
4403 au!
4404 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4405 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004406 lhelpgrep buffer
4407 call assert_equal('help', &filetype)
4408 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4409 lhelpgrep tabpage
4410 call assert_equal('help', &filetype)
4411 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004412 augroup QF_Test
4413 au!
4414 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004415
4416 new | only
4417 augroup QF_Test
4418 au!
4419 au BufEnter * call setqflist([], 'f')
4420 augroup END
4421 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004422 " run the test with a help window already open
4423 help
4424 wincmd w
4425 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004426 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004427 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004428 augroup END
4429
4430 new | only
4431 augroup QF_Test
4432 au!
4433 au BufEnter * call setqflist([], 'r')
4434 augroup END
4435 call assert_fails('helpgrep quickfix', 'E925:')
4436 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004437 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004438 augroup END
4439
4440 new | only
4441 augroup QF_Test
4442 au!
4443 au BufEnter * call setloclist(0, [], 'r')
4444 augroup END
4445 call assert_fails('lhelpgrep quickfix', 'E926:')
4446 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004447 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004448 augroup END
4449
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004450 " Replace the contents of a help window location list when it is still in
4451 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004452 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004453 lhelpgrep quickfix
4454 wincmd w
4455 augroup QF_Test
4456 au!
4457 autocmd WinEnter * call setloclist(0, [], 'r')
4458 augroup END
4459 call assert_fails('lhelpgrep win_getid', 'E926:')
4460 augroup QF_Test
4461 au!
4462 augroup END
4463
4464 %bw!
4465endfunc
4466
4467" The following test used to crash Vim
4468func Test_lhelpgrep_autocmd_free_loclist()
4469 %bw!
4470 lhelpgrep quickfix
4471 wincmd w
4472 augroup QF_Test
4473 au!
4474 autocmd WinEnter * call setloclist(0, [], 'f')
4475 augroup END
4476 lhelpgrep win_getid
4477 wincmd w
4478 wincmd w
4479 wincmd w
4480 augroup QF_Test
4481 au!
4482 augroup END
4483 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004484endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004485
4486" Test for shortening/simplifying the file name when opening the
4487" quickfix window or when displaying the quickfix list
4488func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004489 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004490 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004491 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004492 let fname = getcwd() . '/test_quickfix.vim'
4493 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4494 call assert_equal(fname, bufname('test_quickfix.vim'))
4495 " Opening the quickfix window should simplify the file path
4496 cwindow
4497 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4498 cclose
4499 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004500 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004501 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4502 call assert_equal(fname, bufname('test_quickfix.vim'))
4503 " Displaying the quickfix list should simplify the file path
4504 silent! clist
4505 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004506 " Add a few entries for the same file with different paths and check whether
4507 " the buffer name is shortened
4508 %bwipe
4509 call setqflist([], 'f')
4510 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4511 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4512 \ {'filename' : fname, 'lnum' : 30}], ' ')
4513 copen
4514 call assert_equal(['test_quickfix.vim|10| ',
4515 \ 'test_quickfix.vim|20| ',
4516 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4517 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004518endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004519
4520" Quickfix title tests
4521" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4522" Otherwise due to indentation, the title is set with spaces at the beginning
4523" of the command.
4524func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004525 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004526
4527 " :cexpr
4528 exe "cexpr readfile('Xerr')"
4529 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4530
4531 " :cgetexpr
4532 exe "cgetexpr readfile('Xerr')"
4533 call assert_equal(":cgetexpr readfile('Xerr')",
4534 \ getqflist({'title' : 1}).title)
4535
4536 " :caddexpr
4537 call setqflist([], 'f')
4538 exe "caddexpr readfile('Xerr')"
4539 call assert_equal(":caddexpr readfile('Xerr')",
4540 \ getqflist({'title' : 1}).title)
4541
4542 " :cbuffer
4543 new Xerr
4544 exe "cbuffer"
4545 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4546
4547 " :cgetbuffer
4548 edit Xerr
4549 exe "cgetbuffer"
4550 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4551
4552 " :caddbuffer
4553 call setqflist([], 'f')
4554 edit Xerr
4555 exe "caddbuffer"
4556 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4557
4558 " :cfile
4559 exe "cfile Xerr"
4560 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4561
4562 " :cgetfile
4563 exe "cgetfile Xerr"
4564 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4565
4566 " :caddfile
4567 call setqflist([], 'f')
4568 exe "caddfile Xerr"
4569 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4570
4571 " :grep
4572 set grepprg=internal
4573 exe "grep F1 Xerr"
4574 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4575
4576 " :grepadd
4577 call setqflist([], 'f')
4578 exe "grepadd F1 Xerr"
4579 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4580 set grepprg&vim
4581
4582 " :vimgrep
4583 exe "vimgrep F1 Xerr"
4584 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4585
4586 " :vimgrepadd
4587 call setqflist([], 'f')
4588 exe "vimgrepadd F1 Xerr"
4589 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4590
4591 call setqflist(['F1:10:L10'], ' ')
4592 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4593
4594 call setqflist([], 'f')
4595 call setqflist(['F1:10:L10'], 'a')
4596 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4597
4598 call setqflist([], 'f')
4599 call setqflist(['F1:10:L10'], 'r')
4600 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4601
4602 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004603
4604 call setqflist([], ' ', {'title' : 'Errors'})
4605 copen
4606 call assert_equal('Errors', w:quickfix_title)
4607 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4608 call assert_equal('Errors', w:quickfix_title)
4609 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004610
4611 " Switching to another quickfix list in one tab page should update the
4612 " quickfix window title and statusline in all the other tab pages also
4613 call setqflist([], 'f')
4614 %bw!
4615 cgetexpr ['file_one:1:1: error in the first quickfix list']
4616 call setqflist([], 'a', {'title': 'first quickfix list'})
4617 cgetexpr ['file_two:2:1: error in the second quickfix list']
4618 call setqflist([], 'a', {'title': 'second quickfix list'})
4619 copen
4620 wincmd t
4621 tabnew two
4622 copen
4623 wincmd t
4624 colder
4625 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4626 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4627 call assert_equal(1, tabpagewinnr(1))
4628 call assert_equal(1, tabpagewinnr(2))
4629 tabnew
4630 call setqflist([], 'a', {'title': 'new quickfix title'})
4631 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4632 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4633 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004634endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004635
4636func Test_lbuffer_with_bwipe()
4637 new
4638 new
4639 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004640 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004641 augroup END
4642 lbuffer
4643 augroup nasty
4644 au!
4645 augroup END
4646endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004647
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004648" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4649" running
4650func Xexpr_acmd_freelist(cchar)
4651 call s:setup_commands(a:cchar)
4652
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004653 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004654 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004655 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004656 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004657 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004658 augroup nasty
4659 au!
4660 augroup END
4661endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004662
4663func Test_cexpr_acmd_freelist()
4664 call Xexpr_acmd_freelist('c')
4665 call Xexpr_acmd_freelist('l')
4666endfunc
4667
4668" Test for commands that create a new quickfix/location list and jump to the
4669" first error automatically.
4670func Xjumpto_first_error_test(cchar)
4671 call s:setup_commands(a:cchar)
4672
4673 call s:create_test_file('Xtestfile1')
4674 call s:create_test_file('Xtestfile2')
4675 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4676
4677 " Test for cexpr/lexpr
4678 enew
4679 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004680 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004681 call assert_equal(2, line('.'))
4682
4683 " Test for cfile/lfile
4684 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004685 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004686 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004687 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004688 call assert_equal(2, line('.'))
4689
4690 " Test for cbuffer/lbuffer
4691 edit Xerr
4692 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004693 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004694 call assert_equal(2, line('.'))
4695
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004696 call delete('Xtestfile1')
4697 call delete('Xtestfile2')
4698endfunc
4699
4700func Test_jumpto_first_error()
4701 call Xjumpto_first_error_test('c')
4702 call Xjumpto_first_error_test('l')
4703endfunc
4704
4705" Test for a quickfix autocmd changing the quickfix/location list before
4706" jumping to the first error in the new list.
4707func Xautocmd_changelist(cchar)
4708 call s:setup_commands(a:cchar)
4709
4710 " Test for cfile/lfile
4711 call s:create_test_file('Xtestfile1')
4712 call s:create_test_file('Xtestfile2')
4713 Xexpr 'Xtestfile1:2:Line2'
4714 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004715 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004716 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004717 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004718 call assert_equal(4, line('.'))
4719 autocmd! QuickFixCmdPost
4720
4721 " Test for cbuffer/lbuffer
4722 call g:Xsetlist([], 'f')
4723 Xexpr 'Xtestfile1:2:Line2'
4724 autocmd QuickFixCmdPost * Xolder
4725 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4726 edit Xerr
4727 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004728 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004729 call assert_equal(4, line('.'))
4730 autocmd! QuickFixCmdPost
4731
4732 " Test for cexpr/lexpr
4733 call g:Xsetlist([], 'f')
4734 Xexpr 'Xtestfile1:2:Line2'
4735 autocmd QuickFixCmdPost * Xolder
4736 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004737 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004738 call assert_equal(4, line('.'))
4739 autocmd! QuickFixCmdPost
4740
Bram Moolenaar851332e2018-07-03 19:16:00 +02004741 " The grepprg may not be set on non-Unix systems
4742 if has('unix')
4743 " Test for grep/lgrep
4744 call g:Xsetlist([], 'f')
4745 Xexpr 'Xtestfile1:2:Line2'
4746 autocmd QuickFixCmdPost * Xolder
4747 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004748 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004749 call assert_equal(5, line('.'))
4750 autocmd! QuickFixCmdPost
4751 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004752
4753 " Test for vimgrep/lvimgrep
4754 call g:Xsetlist([], 'f')
4755 Xexpr 'Xtestfile1:2:Line2'
4756 autocmd QuickFixCmdPost * Xolder
4757 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004758 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004759 call assert_equal(5, line('.'))
4760 autocmd! QuickFixCmdPost
4761
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004762 " Test for autocommands clearing the quickfix list before jumping to the
4763 " first error. This should not result in an error
4764 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4765 let v:errmsg = ''
4766 " Test for cfile/lfile
4767 Xfile Xerr
4768 call assert_true(v:errmsg !~# 'E42:')
4769 " Test for cbuffer/lbuffer
4770 edit Xerr
4771 Xbuffer
4772 call assert_true(v:errmsg !~# 'E42:')
4773 " Test for cexpr/lexpr
4774 Xexpr 'Xtestfile2:4:Line4'
4775 call assert_true(v:errmsg !~# 'E42:')
4776 " Test for grep/lgrep
4777 " The grepprg may not be set on non-Unix systems
4778 if has('unix')
4779 silent Xgrep Line5 Xtestfile2
4780 call assert_true(v:errmsg !~# 'E42:')
4781 endif
4782 " Test for vimgrep/lvimgrep
4783 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4784 autocmd! QuickFixCmdPost
4785
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004786 call delete('Xtestfile1')
4787 call delete('Xtestfile2')
4788endfunc
4789
4790func Test_autocmd_changelist()
4791 call Xautocmd_changelist('c')
4792 call Xautocmd_changelist('l')
4793endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004794
4795" Tests for the ':filter /pat/ clist' command
4796func Test_filter_clist()
4797 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4798 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4799 \ split(execute('filter /Line 15/ clist'), "\n"))
4800 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4801 \ split(execute('filter /Xfile1/ clist'), "\n"))
4802 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4803
4804 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4805 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4806 call assert_equal([' 2 pqr:pat2: '],
4807 \ split(execute('filter /pqr/ clist'), "\n"))
4808 call assert_equal([' 1 abc:pat1: '],
4809 \ split(execute('filter /pat1/ clist'), "\n"))
4810endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004811
4812" Tests for the "CTRL-W <CR>" command.
4813func Xview_result_split_tests(cchar)
4814 call s:setup_commands(a:cchar)
4815
4816 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4817 call g:Xsetlist([])
4818 Xopen
4819 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004820 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004821 call assert_equal(l:win_count, winnr('$'))
4822 Xclose
4823endfunc
4824
4825func Test_view_result_split()
4826 call Xview_result_split_tests('c')
4827 call Xview_result_split_tests('l')
4828endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004829
4830" Test that :cc sets curswant
4831func Test_curswant()
4832 helpgrep quickfix
4833 normal! llll
4834 1cc
4835 call assert_equal(getcurpos()[4], virtcol('.'))
4836 cclose | helpclose
4837endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004838
4839" Test for opening a file from the quickfix window using CTRL-W <Enter>
4840" doesn't leave an empty buffer around.
4841func Test_splitview()
4842 call s:create_test_file('Xtestfile1')
4843 call s:create_test_file('Xtestfile2')
4844 new | only
4845 let last_bufnr = bufnr('Test_sv_1', 1)
4846 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4847 cgetexpr l
4848 copen
4849 let numbufs = len(getbufinfo())
4850 exe "normal \<C-W>\<CR>"
4851 copen
4852 exe "normal j\<C-W>\<CR>"
4853 " Make sure new empty buffers are not created
4854 call assert_equal(numbufs, len(getbufinfo()))
4855 " Creating a new buffer should use the next available buffer number
4856 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4857 bwipe Test_sv_1
4858 bwipe Test_sv_2
4859 new | only
4860
4861 " When split opening files from location list window, make sure that two
4862 " windows doesn't refer to the same location list
4863 lgetexpr l
4864 let locid = getloclist(0, {'id' : 0}).id
4865 lopen
4866 exe "normal \<C-W>\<CR>"
4867 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4868 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4869 new | only
4870
4871 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004872 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004873 lhelpgrep window
4874 let locid = getloclist(0, {'id' : 0}).id
4875 lwindow
4876 exe "normal j\<C-W>\<CR>"
4877 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4878 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4879 new | only
4880
Bram Moolenaar406cd902020-02-18 21:54:41 +01004881 " Using :split or :vsplit from a quickfix window should behave like a :new
4882 " or a :vnew command
4883 copen
4884 split
4885 call assert_equal(3, winnr('$'))
4886 let l = getwininfo()
4887 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4888 close
4889 copen
4890 vsplit
4891 let l = getwininfo()
4892 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4893 new | only
4894
Bram Moolenaarb2443732018-11-11 22:50:27 +01004895 call delete('Xtestfile1')
4896 call delete('Xtestfile2')
4897endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004898
4899" Test for parsing entries using visual screen column
4900func Test_viscol()
4901 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004902 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004903 edit Xfile1
4904
4905 " Use byte offset for column number
4906 set efm&
4907 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4908 call assert_equal([5, 8], [col('.'), virtcol('.')])
4909 cnext
4910 call assert_equal([9, 12], [col('.'), virtcol('.')])
4911 cnext
4912 call assert_equal([14, 20], [col('.'), virtcol('.')])
4913
4914 " Use screen column offset for column number
4915 set efm=%f:%l:%v:%m
4916 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4917 call assert_equal([5, 8], [col('.'), virtcol('.')])
4918 cnext
4919 call assert_equal([9, 12], [col('.'), virtcol('.')])
4920 cnext
4921 call assert_equal([14, 20], [col('.'), virtcol('.')])
4922 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4923 call assert_equal([5, 8], [col('.'), virtcol('.')])
4924 cnext
4925 call assert_equal([10, 16], [col('.'), virtcol('.')])
4926 cnext
4927 call assert_equal([14, 20], [col('.'), virtcol('.')])
4928
4929 enew
4930 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4931
4932 " Use byte offset for column number
4933 set efm&
4934 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4935 call assert_equal([8, 10], [col('.'), virtcol('.')])
4936 cnext
4937 call assert_equal([11, 17], [col('.'), virtcol('.')])
4938 cnext
4939 call assert_equal([16, 25], [col('.'), virtcol('.')])
4940
4941 " Use screen column offset for column number
4942 set efm=%f:%l:%v:%m
4943 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4944 call assert_equal([8, 10], [col('.'), virtcol('.')])
4945 cnext
4946 call assert_equal([11, 17], [col('.'), virtcol('.')])
4947 cnext
4948 call assert_equal([16, 25], [col('.'), virtcol('.')])
4949
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004950 " Use screen column number with a multi-line error message
4951 enew
4952 call writefile(["à test"], 'Xfile1')
4953 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4954 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4955 call assert_equal('Xfile1', @%)
4956 call assert_equal([0, 1, 4, 0], getpos('.'))
4957
4958 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4959 " does not break this
4960 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4961 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4962 call assert_equal('Xfile1', @%)
4963 call assert_equal([0, 1, 3, 0], getpos('.'))
4964
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004965 enew | only
4966 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004967endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004968
4969" Test for the quickfix window buffer
4970func Xqfbuf_test(cchar)
4971 call s:setup_commands(a:cchar)
4972
4973 " Quickfix buffer should be reused across closing and opening a quickfix
4974 " window
4975 Xexpr "F1:10:Line10"
4976 Xopen
4977 let qfbnum = bufnr('')
4978 Xclose
4979 " Even after the quickfix window is closed, the buffer should be loaded
4980 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004981 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004982 Xopen
4983 " Buffer should be reused when opening the window again
4984 call assert_equal(qfbnum, bufnr(''))
4985 Xclose
4986
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004987 " When quickfix buffer is wiped out, getqflist() should return 0
4988 %bw!
4989 Xexpr ""
4990 Xopen
4991 bw!
4992 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4993
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004994 if a:cchar == 'l'
4995 %bwipe
4996 " For a location list, when both the file window and the location list
4997 " window for the list are closed, then the buffer should be freed.
4998 new | only
4999 lexpr "F1:10:Line10"
5000 let wid = win_getid()
5001 lopen
5002 let qfbnum = bufnr('')
5003 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
5004 close
5005 " When the location list window is closed, the buffer name should not
5006 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005007 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005008 call assert_true(bufloaded(qfbnum))
5009
Bram Moolenaard82a81c2019-03-02 07:57:18 +01005010 " After deleting a location list buffer using ":bdelete", opening the
5011 " location list window should mark the buffer as a location list buffer.
5012 exe "bdelete " . qfbnum
5013 lopen
5014 call assert_equal("quickfix", &buftype)
5015 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5016 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5017 call assert_false(&swapfile)
5018 lclose
5019
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005020 " When the location list is cleared for the window, the buffer should be
5021 " removed
5022 call setloclist(0, [], 'f')
5023 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005024 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005025
5026 " When the location list is freed with the location list window open, the
5027 " location list buffer should not be lost. It should be reused when the
5028 " location list is again populated.
5029 lexpr "F1:10:Line10"
5030 lopen
5031 let wid = win_getid()
5032 let qfbnum = bufnr('')
5033 wincmd p
5034 call setloclist(0, [], 'f')
5035 lexpr "F1:10:Line10"
5036 lopen
5037 call assert_equal(wid, win_getid())
5038 call assert_equal(qfbnum, bufnr(''))
5039 lclose
5040
5041 " When the window with the location list is closed, the buffer should be
5042 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005043 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005044 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005045 endif
5046endfunc
5047
5048func Test_qfbuf()
5049 call Xqfbuf_test('c')
5050 call Xqfbuf_test('l')
5051endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005052
5053" If there is an autocmd to use only one window, then opening the location
5054" list window used to crash Vim.
5055func Test_winonly_autocmd()
5056 call s:create_test_file('Xtest1')
5057 " Autocmd to show only one Vim window at a time
5058 autocmd WinEnter * only
5059 new
5060 " Load the location list
5061 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5062 let loclistid = getloclist(0, {'id' : 0}).id
5063 " Open the location list window. Only this window will be shown and the file
5064 " window is closed.
5065 lopen
5066 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5067 " Jump to an entry in the location list and make sure that the cursor is
5068 " positioned correctly.
5069 ll 3
5070 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005071 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005072 call assert_equal(15, line('.'))
5073 " Cleanup
5074 autocmd! WinEnter
5075 new | only
5076 call delete('Xtest1')
5077endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005078
5079" Test to make sure that an empty quickfix buffer is not reused for loading
5080" a normal buffer.
5081func Test_empty_qfbuf()
5082 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005083 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005084 call setqflist([], 'f')
5085 copen | only
5086 let qfbuf = bufnr('')
5087 edit Xfile1
5088 call assert_notequal(qfbuf, bufnr(''))
5089 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005090endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005091
5092" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005093" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005094func Xtest_below(cchar)
5095 call s:setup_commands(a:cchar)
5096
5097 " No quickfix/location list
5098 call assert_fails('Xbelow', 'E42:')
5099 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005100 call assert_fails('Xbefore', 'E42:')
5101 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005102
5103 " Empty quickfix/location list
5104 call g:Xsetlist([])
5105 call assert_fails('Xbelow', 'E42:')
5106 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005107 call assert_fails('Xbefore', 'E42:')
5108 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005109
5110 call s:create_test_file('X1')
5111 call s:create_test_file('X2')
5112 call s:create_test_file('X3')
5113 call s:create_test_file('X4')
5114
5115 " Invalid entries
5116 edit X1
5117 call g:Xsetlist(["E1", "E2"])
5118 call assert_fails('Xbelow', 'E42:')
5119 call assert_fails('Xabove', 'E42:')
5120 call assert_fails('3Xbelow', 'E42:')
5121 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005122 call assert_fails('Xbefore', 'E42:')
5123 call assert_fails('Xafter', 'E42:')
5124 call assert_fails('3Xbefore', 'E42:')
5125 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005126
5127 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005128 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 +02005129 edit +7 X2
5130 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005131 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005132 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005133 normal 7G
5134 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005135 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005136 call assert_fails('Xbefore', 'E553:')
5137
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005138 normal 2j
5139 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005140 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005141 normal 7G
5142 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005143 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005144
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005145 " Last error in this file
5146 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005147 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005148 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005149 normal gg
5150 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005151 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005152 call assert_fails('Xafter', 'E553:')
5153
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005154 " First error in this file
5155 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005156 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005157 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005158 normal G
5159 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005160 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005161 call assert_fails('Xbefore', 'E553:')
5162
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005163 normal gg
5164 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005165 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005166 normal gg
5167 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005168 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005169
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005170 normal G
5171 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005172 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005173 normal G
5174 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005175 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005176
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005177 edit X4
5178 call assert_fails('Xabove', 'E42:')
5179 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005180 call assert_fails('Xbefore', 'E42:')
5181 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005182 if a:cchar == 'l'
5183 " If a buffer has location list entries from some other window but not
5184 " from the current window, then the commands should fail.
5185 edit X1 | split | call setloclist(0, [], 'f')
5186 call assert_fails('Xabove', 'E776:')
5187 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005188 call assert_fails('Xbefore', 'E776:')
5189 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005190 close
5191 endif
5192
5193 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005194 let lines =<< trim END
5195 X1:5:L5
5196 X2:5:1:L5_1
5197 X2:5:2:L5_2
5198 X2:5:3:L5_3
5199 X2:10:1:L10_1
5200 X2:10:2:L10_2
5201 X2:10:3:L10_3
5202 X2:15:1:L15_1
5203 X2:15:2:L15_2
5204 X2:15:3:L15_3
5205 X3:3:L3
5206 END
5207 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005208 edit +1 X2
5209 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005210 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005211 normal 1G
5212 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005213 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005214
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005215 normal gg
5216 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005217 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005218 normal gg
5219 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005220 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005221
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005222 normal G
5223 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005224 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005225 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005226 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005227 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005228
5229 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005230 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005231 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005232 normal G
5233 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005234 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005235
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005236 normal 10G
5237 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005238 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005239 normal 10G$
5240 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005241 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005242
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005243 normal 10G
5244 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005245 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005246 normal 9G
5247 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005248 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005249
5250 " Invalid range
5251 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005252 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005253 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005254 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005255 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005256 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005257 endif
5258
5259 call delete('X1')
5260 call delete('X2')
5261 call delete('X3')
5262 call delete('X4')
5263endfunc
5264
5265func Test_cbelow()
5266 call Xtest_below('c')
5267 call Xtest_below('l')
5268endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005269
5270func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005271 let commands =<< trim END
5272 cNext
5273 cNfile
5274 cabove
5275 cbelow
5276 cfirst
5277 clast
5278 cnewer
5279 cnext
5280 cnfile
5281 colder
5282 cprevious
5283 crewind
5284 lNext
5285 lNfile
5286 labove
5287 lbelow
5288 lfirst
5289 llast
5290 lnewer
5291 lnext
5292 lnfile
5293 lolder
5294 lprevious
5295 lrewind
5296 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005297 for cmd in commands
5298 call assert_fails('-1' .. cmd, 'E16:')
5299 call assert_fails('.' .. cmd, 'E16:')
5300 call assert_fails('%' .. cmd, 'E16:')
5301 call assert_fails('$' .. cmd, 'E16:')
5302 endfor
5303endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005304
5305" Test for aborting quickfix commands using QuickFixCmdPre
5306func Xtest_qfcmd_abort(cchar)
5307 call s:setup_commands(a:cchar)
5308
5309 call g:Xsetlist([], 'f')
5310
5311 " cexpr/lexpr
5312 let e = ''
5313 try
5314 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5315 catch /.*/
5316 let e = v:exception
5317 endtry
5318 call assert_equal('AbortCmd', e)
5319 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5320
5321 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005322 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005323 let e = ''
5324 try
5325 Xfile Xfile1
5326 catch /.*/
5327 let e = v:exception
5328 endtry
5329 call assert_equal('AbortCmd', e)
5330 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005331
5332 " cgetbuffer/lgetbuffer
5333 enew!
5334 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5335 let e = ''
5336 try
5337 Xgetbuffer
5338 catch /.*/
5339 let e = v:exception
5340 endtry
5341 call assert_equal('AbortCmd', e)
5342 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5343 enew!
5344
5345 " vimgrep/lvimgrep
5346 let e = ''
5347 try
5348 Xvimgrep /func/ test_quickfix.vim
5349 catch /.*/
5350 let e = v:exception
5351 endtry
5352 call assert_equal('AbortCmd', e)
5353 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5354
5355 " helpgrep/lhelpgrep
5356 let e = ''
5357 try
5358 Xhelpgrep quickfix
5359 catch /.*/
5360 let e = v:exception
5361 endtry
5362 call assert_equal('AbortCmd', e)
5363 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5364
5365 " grep/lgrep
5366 if has('unix')
5367 let e = ''
5368 try
5369 silent Xgrep func test_quickfix.vim
5370 catch /.*/
5371 let e = v:exception
5372 endtry
5373 call assert_equal('AbortCmd', e)
5374 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5375 endif
5376endfunc
5377
5378func Test_qfcmd_abort()
5379 augroup QF_Test
5380 au!
5381 autocmd QuickFixCmdPre * throw "AbortCmd"
5382 augroup END
5383
5384 call Xtest_qfcmd_abort('c')
5385 call Xtest_qfcmd_abort('l')
5386
5387 augroup QF_Test
5388 au!
5389 augroup END
5390endfunc
5391
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005392" Test for using a file in one of the parent directories.
5393func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005394 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005395 let save_cwd = getcwd()
5396 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5397 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5398 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5399 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5400
5401 let lines = "Entering dir Xtestdir\n" .
5402 \ "Entering dir a\n" .
5403 \ "Entering dir b\n" .
5404 \ "Xfile2:2:X2_L2\n" .
5405 \ "Leaving dir a\n" .
5406 \ "Xfile1:2:X1_L2\n" .
5407 \ "Xfile3:1:X3_L1\n" .
5408 \ "Entering dir c\n" .
5409 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005410 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005411 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005412 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005413 call assert_equal(11, getqflist({'size' : 0}).size)
5414 call assert_equal(4, getqflist({'idx' : 0}).idx)
5415 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005416 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005417 cnext
5418 call assert_equal(6, getqflist({'idx' : 0}).idx)
5419 call assert_equal('X1_L2', getline('.'))
5420 cnext
5421 call assert_equal(7, getqflist({'idx' : 0}).idx)
5422 call assert_equal(1, line('$'))
5423 call assert_equal('', getline(1))
5424 cnext
5425 call assert_equal(9, getqflist({'idx' : 0}).idx)
5426 call assert_equal(1, line('$'))
5427 call assert_equal('', getline(1))
5428
5429 set efm&
5430 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005431endfunc
5432
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005433" Test for :cquit
5434func Test_cquit()
5435 " Exit Vim with a non-zero value
5436 if RunVim([], ["cquit 7"], '')
5437 call assert_equal(7, v:shell_error)
5438 endif
5439
5440 if RunVim([], ["50cquit"], '')
5441 call assert_equal(50, v:shell_error)
5442 endif
5443
5444 " Exit Vim with default value
5445 if RunVim([], ["cquit"], '')
5446 call assert_equal(1, v:shell_error)
5447 endif
5448
5449 " Exit Vim with zero value
5450 if RunVim([], ["cquit 0"], '')
5451 call assert_equal(0, v:shell_error)
5452 endif
5453
5454 " Exit Vim with negative value
5455 call assert_fails('-3cquit', 'E16:')
5456endfunc
5457
Bram Moolenaar858ba062020-05-31 23:11:59 +02005458" Test for getting a specific item from a quickfix list
5459func Xtest_getqflist_by_idx(cchar)
5460 call s:setup_commands(a:cchar)
5461 " Empty list
5462 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5463 Xexpr ['F1:10:L10', 'F1:20:L20']
5464 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5465 call assert_equal(bufnr('F1'), l[0].bufnr)
5466 call assert_equal(20, l[0].lnum)
5467 call assert_equal('L20', l[0].text)
5468 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5469 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005470 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005471 %bwipe!
5472endfunc
5473
5474func Test_getqflist_by_idx()
5475 call Xtest_getqflist_by_idx('c')
5476 call Xtest_getqflist_by_idx('l')
5477endfunc
5478
5479" Test for the 'quickfixtextfunc' setting
5480func Tqfexpr(info)
5481 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005482 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005483 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005484 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005485 endif
5486
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005487 let l = []
5488 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5489 let e = qfl[idx]
5490 let s = ''
5491 if e.bufnr != 0
5492 let bname = bufname(e.bufnr)
5493 let s ..= fnamemodify(bname, ':.')
5494 endif
5495 let s ..= '-'
5496 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5497 let s ..= e.text
5498 call add(l, s)
5499 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005500
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005501 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005502endfunc
5503
5504func Xtest_qftextfunc(cchar)
5505 call s:setup_commands(a:cchar)
5506
5507 set efm=%f:%l:%c:%m
5508 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005509 call assert_equal('Tqfexpr', &quickfixtextfunc)
5510 call assert_equal('',
5511 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005512 call g:Xsetlist([
5513 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5514 \ 'end_col': 7, 'text': 'green'},
5515 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5516 \ 'end_col': 8, 'text': 'blue'},
5517 \ ])
5518
Bram Moolenaar858ba062020-05-31 23:11:59 +02005519 Xwindow
5520 call assert_equal('F1-L10C2-green', getline(1))
5521 call assert_equal('F1-L20C4-blue', getline(2))
5522 Xclose
5523 set quickfixtextfunc&vim
5524 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005525 call assert_equal('F1|10 col 2-7| green', getline(1))
5526 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005527 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005528
5529 set efm=%f:%l:%c:%m
5530 set quickfixtextfunc=Tqfexpr
5531 " Update the list with only the cwindow
5532 Xwindow
5533 only
5534 call g:Xsetlist([
5535 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5536 \ 'end_col': 7, 'text': 'red'}
5537 \ ])
5538 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5539 new
5540 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005541 set efm&
5542 set quickfixtextfunc&
5543
5544 " Test for per list 'quickfixtextfunc' setting
5545 func PerQfText(info)
5546 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005547 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005548 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005549 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005550 endif
5551 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005552 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005553 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005554 let l = []
5555 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5556 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5557 endfor
5558 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005559 endfunc
5560 set quickfixtextfunc=Tqfexpr
5561 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5562 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5563 Xwindow
5564 call assert_equal('Line 10, Col 2', getline(1))
5565 call assert_equal('Line 20, Col 4', getline(2))
5566 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005567 call assert_equal(function('PerQfText'),
5568 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005569 " Add entries to the list when the quickfix buffer is hidden
5570 Xaddexpr ['F1:30:6:red']
5571 Xwindow
5572 call assert_equal('Line 30, Col 6', getline(3))
5573 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005574 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005575 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005576 set quickfixtextfunc&
5577 delfunc PerQfText
5578
5579 " Non-existing function
5580 set quickfixtextfunc=Tabc
5581 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5582 call assert_fails("Xwindow", 'E117:')
5583 Xclose
5584 set quickfixtextfunc&
5585
5586 " set option to a non-function
5587 set quickfixtextfunc=[10,\ 20]
5588 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5589 call assert_fails("Xwindow", 'E117:')
5590 Xclose
5591 set quickfixtextfunc&
5592
5593 " set option to a function with different set of arguments
5594 func Xqftext(a, b, c)
5595 return a:a .. a:b .. a:c
5596 endfunc
5597 set quickfixtextfunc=Xqftext
5598 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5599 call assert_fails("Xwindow", 'E119:')
5600 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005601
5602 " set option to a function that returns a list with non-strings
5603 func Xqftext2(d)
5604 return ['one', [], 'two']
5605 endfunc
5606 set quickfixtextfunc=Xqftext2
5607 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5608 \ 'E730:')
5609 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005610 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5611 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005612 Xclose
5613
Bram Moolenaar858ba062020-05-31 23:11:59 +02005614 set quickfixtextfunc&
5615 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005616 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005617
5618 " set the global option to a lambda function
5619 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5620 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5621 Xwindow
5622 call assert_equal(['green', 'blue'], getline(1, '$'))
5623 Xclose
5624 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)
5625 set quickfixtextfunc&
5626
5627 " use a lambda function that returns an empty list
5628 set quickfixtextfunc={d\ ->\ []}
5629 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5630 Xwindow
5631 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5632 \ getline(1, '$'))
5633 Xclose
5634 set quickfixtextfunc&
5635
5636 " use a lambda function that returns a list with empty strings
5637 set quickfixtextfunc={d\ ->\ ['',\ '']}
5638 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5639 Xwindow
5640 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5641 \ getline(1, '$'))
5642 Xclose
5643 set quickfixtextfunc&
5644
5645 " set the per-quickfix list text function to a lambda function
5646 call g:Xsetlist([], ' ',
5647 \ {'quickfixtextfunc' :
5648 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5649 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5650 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5651 Xwindow
5652 call assert_equal('Line 10, Col 2', getline(1))
5653 call assert_equal('Line 20, Col 4', getline(2))
5654 Xclose
5655 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5656 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005657endfunc
5658
5659func Test_qftextfunc()
5660 call Xtest_qftextfunc('c')
5661 call Xtest_qftextfunc('l')
5662endfunc
5663
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005664func Test_qftextfunc_callback()
5665 let lines =<< trim END
5666 set efm=%f:%l:%c:%m
5667
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005668 #" Test for using a function name
5669 LET &qftf = 'g:Tqfexpr'
5670 cexpr "F0:0:0:L0"
5671 copen
5672 call assert_equal('F0-L0C0-L0', getline(1))
5673 cclose
5674
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005675 #" Test for using a function()
5676 set qftf=function('g:Tqfexpr')
5677 cexpr "F1:1:1:L1"
5678 copen
5679 call assert_equal('F1-L1C1-L1', getline(1))
5680 cclose
5681
5682 #" Using a funcref variable to set 'quickfixtextfunc'
5683 VAR Fn = function('g:Tqfexpr')
5684 LET &qftf = Fn
5685 cexpr "F2:2:2:L2"
5686 copen
5687 call assert_equal('F2-L2C2-L2', getline(1))
5688 cclose
5689
5690 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5691 LET Fn = function('g:Tqfexpr')
5692 LET &qftf = string(Fn)
5693 cexpr "F3:3:3:L3"
5694 copen
5695 call assert_equal('F3-L3C3-L3', getline(1))
5696 cclose
5697
5698 #" Test for using a funcref()
5699 set qftf=funcref('g:Tqfexpr')
5700 cexpr "F4:4:4:L4"
5701 copen
5702 call assert_equal('F4-L4C4-L4', getline(1))
5703 cclose
5704
5705 #" Using a funcref variable to set 'quickfixtextfunc'
5706 LET Fn = funcref('g:Tqfexpr')
5707 LET &qftf = Fn
5708 cexpr "F5:5:5:L5"
5709 copen
5710 call assert_equal('F5-L5C5-L5', getline(1))
5711 cclose
5712
5713 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5714 LET Fn = funcref('g:Tqfexpr')
5715 LET &qftf = string(Fn)
5716 cexpr "F5:5:5:L5"
5717 copen
5718 call assert_equal('F5-L5C5-L5', getline(1))
5719 cclose
5720
5721 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005722 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005723 LET optval = substitute(optval, ' ', '\\ ', 'g')
5724 exe "set qftf=" .. optval
5725 cexpr "F6:6:6:L6"
5726 copen
5727 call assert_equal('F6-L6C6-L6', getline(1))
5728 cclose
5729
5730 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005731 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005732 cexpr "F7:7:7:L7"
5733 copen
5734 call assert_equal('F7-L7C7-L7', getline(1))
5735 cclose
5736
5737 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005738 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005739 cexpr "F8:8:8:L8"
5740 copen
5741 call assert_equal('F8-L8C8-L8', getline(1))
5742 cclose
5743
5744 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005745 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005746 LET &qftf = Lambda
5747 cexpr "F9:9:9:L9"
5748 copen
5749 call assert_equal('F9-L9C9-L9', getline(1))
5750 cclose
5751
5752 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005753 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005754 LET &qftf = string(Lambda)
5755 cexpr "F9:9:9:L9"
5756 copen
5757 call assert_equal('F9-L9C9-L9', getline(1))
5758 cclose
5759 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005760 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005761
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005762 " Test for using a script-local function name
5763 func s:TqfFunc2(info)
5764 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5765 return ''
5766 endfunc
5767 let g:TqfFunc2Args = []
5768 set quickfixtextfunc=s:TqfFunc2
5769 cexpr "F10:10:10:L10"
5770 cclose
5771 call assert_equal([1, 1], g:TqfFunc2Args)
5772
5773 let &quickfixtextfunc = 's:TqfFunc2'
5774 cexpr "F11:11:11:L11"
5775 cclose
5776 call assert_equal([1, 1], g:TqfFunc2Args)
5777 delfunc s:TqfFunc2
5778
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005779 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5780 func SetQftfFunc()
5781 let params = {'qftf': function('g:DictQftfFunc')}
5782 let &quickfixtextfunc = params.qftf
5783 endfunc
5784 func g:DictQftfFunc(_) dict
5785 endfunc
5786 call SetQftfFunc()
5787 new
5788 call SetQftfFunc()
5789 bw
5790 call test_garbagecollect_now()
5791 new
5792 set qftf=
5793 wincmd w
5794 set qftf=
5795 :%bw!
5796
5797 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5798 " to cause a crash.
5799 let &qftf = ''
5800 func SetLocalQftfFunc()
5801 let params = {'qftf': function('g:DictQftfFunc')}
5802 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5803 endfunc
5804 call SetLocalQftfFunc()
5805 call test_garbagecollect_now()
5806 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5807 delfunc g:DictQftfFunc
5808 delfunc SetQftfFunc
5809 delfunc SetLocalQftfFunc
5810 set efm&
5811endfunc
5812
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005813" Test for updating a location list for some other window and check that
5814" 'qftextfunc' uses the correct location list.
5815func Test_qftextfunc_other_loclist()
5816 %bw!
5817 call setloclist(0, [], 'f')
5818
5819 " create a window and a location list for it and open the location list
5820 " window
5821 lexpr ['F1:10:12:one', 'F1:20:14:two']
5822 let w1_id = win_getid()
5823 call setloclist(0, [], ' ',
5824 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5825 \ 'quickfixtextfunc':
5826 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5827 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5828 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5829 lwindow
5830 let w2_id = win_getid()
5831
5832 " create another window and a location list for it and open the location
5833 " list window
5834 topleft new
5835 let w3_id = win_getid()
5836 call setloclist(0, [], ' ',
5837 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5838 \ 'quickfixtextfunc':
5839 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5840 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5841 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5842 lwindow
5843 let w4_id = win_getid()
5844
5845 topleft new
5846 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5847 let w5_id = win_getid()
5848
5849 " change the location list for some other window
5850 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5851 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5852 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5853 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5854 \ getbufline(winbufnr(w2_id), 1, '$'))
5855 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5856 \ getbufline(winbufnr(w4_id), 1, '$'))
5857 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5858 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5859 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5860 \ getbufline(winbufnr(w2_id), 1, '$'))
5861 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5862 \ getbufline(winbufnr(w4_id), 1, '$'))
5863
5864 call win_gotoid(w5_id)
5865 lwindow
5866 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5867 \ getline(1, '$'))
5868 %bw!
5869endfunc
5870
Bram Moolenaarec98e932020-06-08 19:35:59 +02005871" Running :lhelpgrep command more than once in a help window, doesn't jump to
5872" the help topic
5873func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005874 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005875 call writefile(['window'], 'Xtestdir/doc/a.txt')
5876 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5877 let save_rtp = &rtp
5878 let &rtp = 'Xtestdir'
5879 lhelpgrep window
5880 lhelpgrep buffer
5881 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5882 lhelpgrep window
5883 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5884 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005885 new | only!
5886endfunc
5887
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005888" Test for the crash fixed by 7.3.715
5889func Test_setloclist_crash()
5890 %bw!
5891 let g:BufNum = bufnr()
5892 augroup QF_Test
5893 au!
5894 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5895 augroup END
5896
5897 try
5898 lvimgrep /.*/ *.mak
5899 catch /E926:/
5900 endtry
5901 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5902 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5903
5904 augroup QF_Test
5905 au!
5906 augroup END
5907 unlet g:BufNum
5908 %bw!
5909endfunc
5910
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005911" Test for adding an invalid entry with the quickfix window open and making
5912" sure that the window contents are not changed
5913func Test_add_invalid_entry_with_qf_window()
5914 call setqflist([], 'f')
5915 cexpr "Xfile1:10:aa"
5916 copen
5917 call setqflist(['bb'], 'a')
5918 call assert_equal(1, line('$'))
5919 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005920 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())
5921
5922 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5923 call assert_equal(1 , line('$'))
5924 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5925 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())
5926
5927 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')
5928 call assert_equal(1 , line('$'))
5929 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5930 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())
5931
5932 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')
5933 call assert_equal(1 , line('$'))
5934 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5935 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())
5936
5937 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')
5938 call assert_equal(1 , line('$'))
5939 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5940 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())
5941
5942 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')
5943 call assert_equal(1 , line('$'))
5944 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5945 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())
5946
5947 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')
5948 call assert_equal(1 , line('$'))
5949 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5950 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())
5951
5952 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')
5953 call assert_equal(1 , line('$'))
5954 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5955 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 +01005956 cclose
5957endfunc
5958
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005959" Test for very weird problem: autocommand causes a failure, resulting opening
5960" the quickfix window to fail. This still splits the window, but otherwise
5961" should not mess up buffers.
5962func Test_quickfix_window_fails_to_open()
5963 CheckScreendump
5964
5965 let lines =<< trim END
5966 anything
5967 try
5968 anything
5969 endtry
5970 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005971 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005972
5973 let lines =<< trim END
5974 split XquickfixFails
5975 silent vimgrep anything %
5976 normal o
5977 au BufLeave * ++once source XquickfixFails
5978 " This will trigger the autocommand, which causes an error, what follows
5979 " is aborted but the window was already split.
5980 silent! cwindow
5981 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005982 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005983 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5984 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5985
5986 " clean up
5987 call term_sendkeys(buf, ":bwipe!\<CR>")
5988 call term_wait(buf)
5989 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005990endfunc
5991
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005992" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005993" is changed.
5994func Xqfbuf_update(cchar)
5995 call s:setup_commands(a:cchar)
5996
5997 Xexpr "F1:1:line1"
5998 Xopen
5999 call assert_equal(['F1|1| line1'], getline(1, '$'))
6000 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6001
6002 " Test setqflist() using the 'lines' key in 'what'
6003 " add a new entry
6004 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
6005 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
6006 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6007 " replace all the entries with a single entry
6008 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
6009 call assert_equal(['F3|3| line3'], getline(1, '$'))
6010 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6011 " remove all the entries
6012 call g:Xsetlist([], 'r', {'lines' : []})
6013 call assert_equal([''], getline(1, '$'))
6014 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6015 " add a new list
6016 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6017 call assert_equal(['F4|4| line4'], getline(1, '$'))
6018 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6019
6020 " Test setqflist() using the 'items' key in 'what'
6021 " add a new entry
6022 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6023 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6024 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6025 " replace all the entries with a single entry
6026 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6027 call assert_equal(['F6|6| line6'], getline(1, '$'))
6028 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6029 " remove all the entries
6030 call g:Xsetlist([], 'r', {'items' : []})
6031 call assert_equal([''], getline(1, '$'))
6032 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6033 " add a new list
6034 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6035 call assert_equal(['F7|7| line7'], getline(1, '$'))
6036 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6037
6038 call g:Xsetlist([], ' ', {})
6039 call assert_equal([''], getline(1, '$'))
6040 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6041
6042 Xclose
6043endfunc
6044
6045func Test_qfbuf_update()
6046 call Xqfbuf_update('c')
6047 call Xqfbuf_update('l')
6048endfunc
6049
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006050func Test_vimgrep_noswapfile()
6051 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006052 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006053 vimgrep two Xgreppie
6054 call assert_equal('two', getline('.'))
6055
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006056 set swapfile
6057endfunc
6058
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006059" Test for the :vimgrep 'f' flag (fuzzy match)
6060func Xvimgrep_fuzzy_match(cchar)
6061 call s:setup_commands(a:cchar)
6062
6063 Xvimgrep /three one/f Xfile*
6064 let l = g:Xgetlist()
6065 call assert_equal(2, len(l))
6066 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6067 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6068 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6069 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6070
6071 Xvimgrep /the/f Xfile*
6072 let l = g:Xgetlist()
6073 call assert_equal(3, len(l))
6074 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6075 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6076 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6077 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6078 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6079 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6080
6081 Xvimgrep /aaa/fg Xfile*
6082 let l = g:Xgetlist()
6083 call assert_equal(4, len(l))
6084 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6085 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6086 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6087 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6088 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6089 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6090 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6091 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6092
6093 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6094endfunc
6095
6096func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006097 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6098 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006099 call Xvimgrep_fuzzy_match('c')
6100 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006101endfunc
6102
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006103func Test_locationlist_open_in_newtab()
6104 call s:create_test_file('Xqftestfile1')
6105 call s:create_test_file('Xqftestfile2')
6106 call s:create_test_file('Xqftestfile3')
6107
6108 %bwipe!
6109
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006110 let lines =<< trim END
6111 Xqftestfile1:5:Line5
6112 Xqftestfile2:10:Line10
6113 Xqftestfile3:16:Line16
6114 END
6115 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006116
6117 silent! llast
6118 call assert_equal(1, tabpagenr('$'))
6119 call assert_equal('Xqftestfile3', bufname())
6120
6121 set switchbuf=newtab
6122
6123 silent! lfirst
6124 call assert_equal(2, tabpagenr('$'))
6125 call assert_equal('Xqftestfile1', bufname())
6126
6127 silent! lnext
6128 call assert_equal(3, tabpagenr('$'))
6129 call assert_equal('Xqftestfile2', bufname())
6130
6131 call delete('Xqftestfile1')
6132 call delete('Xqftestfile2')
6133 call delete('Xqftestfile3')
6134 set switchbuf&vim
6135
6136 %bwipe!
6137endfunc
6138
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006139" Test for win_gettype() in quickfix and location list windows
6140func Test_win_gettype()
6141 copen
6142 call assert_equal("quickfix", win_gettype())
6143 let wid = win_getid()
6144 wincmd p
6145 call assert_equal("quickfix", win_gettype(wid))
6146 cclose
6147 lexpr ''
6148 lopen
6149 call assert_equal("loclist", win_gettype())
6150 let wid = win_getid()
6151 wincmd p
6152 call assert_equal("loclist", win_gettype(wid))
6153 lclose
6154endfunc
6155
Christian Brabandt0b226f62021-12-01 10:54:24 +00006156fun Test_vimgrep_nomatch()
6157 call XexprTests('c')
6158 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6159 copen
6160 if has("win32")
6161 call assert_fails('vimgrep foo *.zzz', 'E479:')
6162 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'}]
6163 else
6164 call assert_fails('vimgrep foo *.zzz', 'E480:')
6165 let expected = []
6166 endif
6167 call assert_equal(expected, getqflist())
6168 cclose
6169endfunc
6170
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006171" Test for opening the quickfix window in two tab pages and then closing one
6172" of the quickfix windows. This should not make the quickfix buffer unlisted.
6173" (github issue #9300).
6174func Test_two_qf_windows()
6175 cexpr "F1:1:line1"
6176 copen
6177 tabnew
6178 copen
6179 call assert_true(&buflisted)
6180 cclose
6181 tabfirst
6182 call assert_true(&buflisted)
6183 let bnum = bufnr()
6184 cclose
6185 " if all the quickfix windows are closed, then buffer should be unlisted.
6186 call assert_false(buflisted(bnum))
6187 %bw!
6188
6189 " Repeat the test for a location list
6190 lexpr "F2:2:line2"
6191 lopen
6192 let bnum = bufnr()
6193 tabnew
6194 exe "buffer" bnum
6195 tabfirst
6196 lclose
6197 tablast
6198 call assert_true(buflisted(bnum))
6199 tabclose
6200 lopen
6201 call assert_true(buflisted(bnum))
6202 lclose
6203 call assert_false(buflisted(bnum))
6204 %bw!
6205endfunc
6206
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006207" Weird sequence of commands that caused entering a wiped-out buffer
6208func Test_lopen_bwipe()
6209 func R()
6210 silent! tab lopen
6211 e x
6212 silent! lfile
6213 endfunc
6214
6215 cal R()
6216 cal R()
6217 cal R()
6218 bw!
6219 delfunc R
6220endfunc
6221
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006222" Another sequence of commands that caused all buffers to be wiped out
6223func Test_lopen_bwipe_all()
6224 let lines =<< trim END
6225 func R()
6226 silent! tab lopen
6227 e foo
6228 silent! lfile
6229 endfunc
6230 cal R()
6231 exe "norm \<C-W>\<C-V>0"
6232 cal R()
6233 bwipe
6234
6235 call writefile(['done'], 'Xresult')
6236 qall!
6237 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006238 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006239 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6240 call assert_equal(['done'], readfile('Xresult'))
6241 endif
6242
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006243 call delete('Xresult')
6244endfunc
6245
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006246" Test for calling setqflist() function recursively
6247func Test_recursive_setqflist()
6248 augroup QF_Test
6249 au!
6250 autocmd BufWinEnter quickfix call setqflist([], 'r')
6251 augroup END
6252
6253 copen
6254 call assert_fails("call setqflist([], 'a')", 'E952:')
6255
6256 augroup QF_Test
6257 au!
6258 augroup END
6259 %bw!
6260endfunc
6261
6262" Test for failure to create a new window when selecting a file from the
6263" quickfix window
6264func Test_cwindow_newwin_fails()
6265 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6266 cwindow
6267 only
6268 let qf_wid = win_getid()
6269 " create the maximum number of scratch windows
6270 let hor_win_count = (&lines - 1)/2
6271 let hor_split_count = hor_win_count - 1
6272 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6273 call win_gotoid(qf_wid)
6274 call assert_fails('exe "normal \<CR>"', 'E36:')
6275 %bw!
6276endfunc
6277
6278" Test for updating the location list when only the location list window is
6279" present and the corresponding file window is closed.
6280func Test_loclist_update_with_llwin_only()
6281 %bw!
6282 new
6283 wincmd w
6284 lexpr ["Xfile1:1:Line1"]
6285 lopen
6286 wincmd p
6287 close
6288 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6289 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6290 %bw!
6291endfunc
6292
6293" Test for getting the quickfix list after a buffer with an error is wiped out
6294func Test_getqflist_wiped_out_buffer()
6295 %bw!
6296 cexpr ["Xtest1:34:Wiped out"]
6297 let bnum = bufnr('Xtest1')
6298 call assert_equal(bnum, getqflist()[0].bufnr)
6299 bw Xtest1
6300 call assert_equal(0, getqflist()[0].bufnr)
6301 %bw!
6302endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006303
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006304" Test for the status message that is displayed when opening a new quickfix
6305" list
6306func Test_qflist_statusmsg()
6307 cexpr "1\n2"
6308 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6309 call assert_equal('(4 of 4): msg', v:statusmsg)
6310 call setqflist([], 'f')
6311 %bw!
6312
6313 " When creating a new quickfix list, if an autocmd changes the quickfix list
6314 " in the stack, then an error message should be displayed.
6315 augroup QF_Test
6316 au!
6317 au BufEnter test_quickfix.vim colder
6318 augroup END
6319 cexpr "1\n2"
6320 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6321 call setqflist([], 'f')
6322 augroup QF_Test
6323 au!
6324 augroup END
6325 %bw!
6326
6327 augroup QF_Test
6328 au!
6329 au BufEnter test_quickfix.vim caddexpr "4"
6330 augroup END
6331 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6332 call setqflist([], 'f')
6333 augroup QF_Test
6334 au!
6335 augroup END
6336 %bw!
6337endfunc
6338
Bram Moolenaard6c67622022-08-24 20:07:22 +01006339func Test_quickfixtextfunc_recursive()
6340 func s:QFTfunc(o)
6341 cgete '0'
6342 endfunc
6343 copen
6344 let &quickfixtextfunc = 's:QFTfunc'
6345 cex ""
6346
6347 let &quickfixtextfunc = ''
6348 cclose
6349endfunc
6350
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006351" Test for replacing the location list from an autocmd. This used to cause a
6352" read from freed memory.
6353func Test_loclist_replace_autocmd()
6354 %bw!
6355 call setloclist(0, [], 'f')
6356 let s:bufnr = bufnr()
6357 cal setloclist(0, [{'0': 0, '': ''}])
6358 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6359 lopen
6360 try
6361 exe "norm j\<CR>"
6362 catch
6363 endtry
6364 lnext
6365 %bw!
6366 call setloclist(0, [], 'f')
6367endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006368
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006369" Test for a very long error line and a very long information line
6370func Test_very_long_error_line()
6371 let msg = repeat('abcdefghijklmn', 146)
6372 let emsg = 'Xlonglines.c:1:' . msg
6373 call writefile([msg, emsg], 'Xerror', 'D')
6374 cfile Xerror
6375 cwindow
6376 call assert_equal($'|| {msg}', getline(1))
6377 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6378 cclose
6379
6380 let l = execute('clist!')->split("\n")
6381 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6382
6383 let l = execute('cc')->split("\n")
6384 call assert_equal([$'(2 of 2): {msg}'], l)
6385
6386 call setqflist([], 'f')
6387endfunc
6388
6389" In the quickfix window, spaces at the beginning of an informational line
6390" should not be removed but should be removed from an error line.
6391func Test_info_line_with_space()
6392 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6393 \ ' 20 | Afunc():', '', ' | ^']
6394 copen
6395 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6396 \ '|| 20 | Afunc():', '|| ',
6397 \ '|| | ^'], getline(1, '$'))
6398 cclose
6399
6400 let l = execute('clist!')->split("\n")
6401 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6402 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6403
6404 call setqflist([], 'f')
6405endfunc
6406
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006407func s:QfTf(_)
6408endfunc
6409
6410func Test_setqflist_cb_arg()
6411 " This was changing the callback name in the dictionary.
6412 let d = #{quickfixtextfunc: 's:QfTf'}
6413 call setqflist([], 'a', d)
6414 call assert_equal('s:QfTf', d.quickfixtextfunc)
6415
6416 call setqflist([], 'f')
6417endfunc
6418
zeertzjqa40c0bc2023-05-27 14:10:08 +01006419" Test that setqflist() should not prevent :stopinsert from working
6420func Test_setqflist_stopinsert()
6421 new
6422 call setqflist([], 'f')
6423 copen
6424 cclose
6425 func StopInsert()
6426 stopinsert
6427 call setqflist([{'text': 'foo'}])
6428 return ''
6429 endfunc
6430
6431 call setline(1, 'abc')
6432 call cursor(1, 1)
6433 call feedkeys("i\<C-R>=StopInsert()\<CR>$", 'tnix')
6434 call assert_equal('foo', getqflist()[0].text)
6435 call assert_equal([0, 1, 3, 0, v:maxcol], getcurpos())
6436 call assert_equal(['abc'], getline(1, '$'))
6437
6438 delfunc StopInsert
6439 call setqflist([], 'f')
6440 bwipe!
6441endfunc
Bram Moolenaard0fab102022-10-20 16:03:33 +01006442
Shane Harper5bf04282023-06-07 19:09:57 +01006443func Test_quickfix_buffer_contents()
6444 call setqflist([{'filename':'filename', 'pattern':'pattern', 'text':'text'}])
6445 copen
6446 call assert_equal(['filename|pattern| text'], getline(1, '$')) " The assert failed with Vim v9.0.0736; '| text' did not appear after the pattern.
6447 call setqflist([], 'f')
6448endfunc
6449
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006450" vim: shiftwidth=2 sts=2 expandtab