blob: b7d290275ba6b38f2d2eb1d97926dd8f4c8f20b6 [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},
thinca6864efa2021-06-19 20:45:20 +02001811 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
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)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001818
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001819 Xnext
1820 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1821 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001822 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001823 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001824 call assert_equal(3, line('.'))
1825
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001826 " Appending entries to the list should not change the cursor position
1827 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001828 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001829 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001830 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001831 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1832 call assert_equal(1, line('.'))
1833 close
1834
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001835 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001836 \ {'bufnr': a:bnum, 'lnum': 4},
1837 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001838 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001839 call assert_equal(3, len(l))
1840 call assert_equal(5, l[2].lnum)
1841
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001842 call g:Xsetlist([])
1843 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001844 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001845
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001846 " Tests for setting the 'valid' flag
1847 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1848 Xwindow
1849 call assert_equal(1, winnr('$'))
1850 let l = g:Xgetlist()
1851 call g:Xsetlist(l)
1852 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001853 " Adding a non-valid entry should not mark the list as having valid entries
1854 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1855 Xwindow
1856 call assert_equal(1, winnr('$'))
1857
1858 " :cnext/:cprev should still work even with invalid entries in the list
1859 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1860 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1861 call g:Xsetlist(l)
1862 Xnext
1863 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1864 Xprev
1865 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1866 " :cnext/:cprev should still work after appending invalid entries to an
1867 " empty list
1868 call g:Xsetlist([])
1869 call g:Xsetlist(l, 'a')
1870 Xnext
1871 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1872 Xprev
1873 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1874
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001875 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1876 Xwindow
1877 call assert_equal(2, winnr('$'))
1878 Xclose
1879 let save_efm = &efm
1880 set efm=%m
1881 Xgetexpr 'TestMessage'
1882 let l = g:Xgetlist()
1883 call g:Xsetlist(l)
1884 call assert_equal(1, g:Xgetlist()[0].valid)
1885 let &efm = save_efm
1886
Bram Moolenaaree85df32017-03-19 14:19:50 +01001887 " Error cases:
1888 " Refer to a non-existing buffer and pass a non-dictionary type
1889 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1890 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1891 call g:Xsetlist([[1, 2,3]])
1892 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001893 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001894 call g:Xsetlist([test_null_dict()])
1895 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001896endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001897
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001898func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001899 new Xtestfile | only
1900 let bnum = bufnr('%')
1901 call setline(1, range(1,5))
1902
1903 call SetXlistTests('c', bnum)
1904 call SetXlistTests('l', bnum)
1905
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001906 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001907 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001908endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001909
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001910func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001911 call s:setup_commands(a:cchar)
1912
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001913 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001914 let @/ = 'Test_'
1915 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001916 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001917 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001918 Xvimgrep empty test_quickfix.vim
1919 call assert_true(len(g:Xgetlist()) > 0)
1920 Xvimgrep matches test_quickfix.vim
1921 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001922 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001923 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001924 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001925 call g:Xsetlist([], 'r')
1926 call assert_true(len(g:Xgetlist()) == 0)
1927 Xolder
1928 call assert_equal(testlen, len(g:Xgetlist()))
1929 Xnewer
1930 Xnewer
1931 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001932endfunc
1933
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001934func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001935 call Xlist_empty_middle('c')
1936 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001937endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001938
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001939func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001940 call s:setup_commands(a:cchar)
1941
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001942 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001943 Xvimgrep one test_quickfix.vim
1944 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001945 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001946 Xvimgrep two test_quickfix.vim
1947 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001948 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001949 Xvimgrep three test_quickfix.vim
1950 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001951 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001952 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001953 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001954 call g:Xsetlist([], 'r')
1955 call assert_true(len(g:Xgetlist()) == 0)
1956 Xnewer
1957 call assert_equal(twolen, len(g:Xgetlist()))
1958 Xnewer
1959 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001960endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001961
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001962func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001963 call Xlist_empty_older('c')
1964 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001965endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001966
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001967func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001968 call s:setup_commands(a:cchar)
1969
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001970 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1971 \ {'filename': 'fnameB', 'text': 'B'}]
1972 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1973 \ {'filename': 'fnameD', 'text': 'D'},
1974 \ {'filename': 'fnameE', 'text': 'E'}]
1975
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001976 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001977 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001978 silent! Xnewer 99
1979 call g:Xsetlist(list1)
1980 call g:Xsetlist(list2)
1981 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001982 call assert_equal(3, len(li))
1983 call assert_equal('C', li[0]['text'])
1984 call assert_equal('D', li[1]['text'])
1985 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001986 silent! Xolder
1987 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001988 call assert_equal(2, len(li))
1989 call assert_equal('A', li[0]['text'])
1990 call assert_equal('B', li[1]['text'])
1991
1992 " {action} is specified ' '.
1993 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001994 silent! Xnewer 99
1995 call g:Xsetlist(list1)
1996 call g:Xsetlist(list2, ' ')
1997 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001998 call assert_equal(3, len(li))
1999 call assert_equal('C', li[0]['text'])
2000 call assert_equal('D', li[1]['text'])
2001 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002002 silent! Xolder
2003 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002004 call assert_equal(2, len(li))
2005 call assert_equal('A', li[0]['text'])
2006 call assert_equal('B', li[1]['text'])
2007
2008 " {action} is specified 'a'.
2009 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002010 silent! Xnewer 99
2011 call g:Xsetlist(list1)
2012 call g:Xsetlist(list2, 'a')
2013 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002014 call assert_equal(5, len(li))
2015 call assert_equal('A', li[0]['text'])
2016 call assert_equal('B', li[1]['text'])
2017 call assert_equal('C', li[2]['text'])
2018 call assert_equal('D', li[3]['text'])
2019 call assert_equal('E', li[4]['text'])
2020
2021 " {action} is specified 'r'.
2022 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002023 silent! Xnewer 99
2024 call g:Xsetlist(list1)
2025 call g:Xsetlist(list2, 'r')
2026 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002027 call assert_equal(3, len(li))
2028 call assert_equal('C', li[0]['text'])
2029 call assert_equal('D', li[1]['text'])
2030 call assert_equal('E', li[2]['text'])
2031
2032 " Test for wrong value.
2033 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002034 call assert_fails("call g:Xsetlist(0)", 'E714:')
2035 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
2036 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
2037 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
2038 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002039endfunc
2040
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002041func Test_setqflist_invalid_nr()
2042 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02002043 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002044endfunc
2045
Bram Moolenaar99234f22020-02-10 22:56:54 +01002046func Test_setqflist_user_sets_buftype()
2047 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
2048 set buftype=quickfix
2049 call setqflist([], 'a')
2050 enew
2051endfunc
2052
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002053func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002054 call XquickfixSetListWithAct('c')
2055 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002056endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002057
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002058func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002059 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002060
Bram Moolenaar049cba92016-06-26 14:38:04 +02002061 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002062 call assert_equal(1, l[0].lnum)
2063 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002064 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002065 call assert_equal(2, l[1].lnum)
2066 call assert_equal(1, l[1].col)
2067 call assert_equal(4070, len(l[1].text))
2068 call assert_equal(3, l[2].lnum)
2069 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002070 call assert_equal(4070, len(l[2].text))
2071 call assert_equal(4, l[3].lnum)
2072 call assert_equal(1, l[3].col)
2073 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002074
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002075 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002076endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002077
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002078func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002079 call s:setup_commands(a:cchar)
2080
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002081 let testfile = 'samples/quickfix.txt'
2082
2083 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002084 exe 'Xgetfile' testfile
2085 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002086
2087 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002088 Xexpr readfile(testfile)
2089 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002090
2091 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002092 Xexpr join(readfile(testfile), "\n")
2093 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002094
2095 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002096 exe 'edit' testfile
2097 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02002098 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002099endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002100
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002101func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002102 call s:long_lines_tests('c')
2103 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002104endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002105
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002106func Test_cgetfile_on_long_lines()
2107 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
2108 " are read at a time.
2109 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002110 let lines =<< trim END
2111 /tmp/file1:1:1:aaa
2112 /tmp/file2:1:1:%s
2113 /tmp/file3:1:1:bbb
2114 /tmp/file4:1:1:ccc
2115 END
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002116 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002117 call writefile(lines, 'Xcqetfile.txt', 'D')
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002118 cgetfile Xcqetfile.txt
2119 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
2120 endfor
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002121endfunc
2122
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002123func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002124 let l = []
2125 for i in range(1, 20)
2126 call add(l, 'Line' . i)
2127 endfor
2128 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002129endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002130
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002131func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002132 call s:create_test_file('Xqftestfile1')
2133 call s:create_test_file('Xqftestfile2')
2134 call s:create_test_file('Xqftestfile3')
2135
2136 new | only
2137 edit Xqftestfile1
2138 let file1_winid = win_getid()
2139 new Xqftestfile2
2140 let file2_winid = win_getid()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002141 let lines =<< trim END
2142 Xqftestfile1:5:Line5
2143 Xqftestfile1:6:Line6
2144 Xqftestfile2:10:Line10
2145 Xqftestfile2:11:Line11
2146 Xqftestfile3:15:Line15
2147 Xqftestfile3:16:Line16
2148 END
2149 cgetexpr lines
Bram Moolenaar049cba92016-06-26 14:38:04 +02002150
2151 new
2152 let winid = win_getid()
2153 cfirst | cnext
2154 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002155 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002156 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002157 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002158 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002159
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002160 " Test for 'switchbuf' set to search for files in windows in the current
2161 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002162 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002163 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02002164 cfirst | cnext
2165 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002166 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002167 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002168 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002169 call assert_equal(file2_winid, win_getid())
2170
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002171 " Test for 'switchbuf' set to search for files in tabpages and jump to an
2172 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002173 enew | only
2174 set switchbuf=usetab
2175 tabedit Xqftestfile1
2176 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01002177 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02002178 tabfirst
2179 cfirst | cnext
2180 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002181 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002182 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002183 6cnext
2184 call assert_equal(4, tabpagenr())
2185 2cpfile
2186 call assert_equal(2, tabpagenr())
2187 2cnfile
2188 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002189 tabfirst | tabonly | enew
2190
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002191 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002192 set switchbuf=split
2193 cfirst | cnext
2194 call assert_equal(1, winnr('$'))
2195 cnext | cnext
2196 call assert_equal(2, winnr('$'))
2197 cnext | cnext
2198 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002199
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002200 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002201 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002202 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002203 cfirst | cnext
2204 call assert_equal(1, tabpagenr('$'))
2205 cnext | cnext
2206 call assert_equal(2, tabpagenr('$'))
2207 cnext | cnext
2208 call assert_equal(3, tabpagenr('$'))
2209 tabfirst | enew | tabonly | only
2210
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002211 set switchbuf=uselast
2212 split
2213 let last_winid = win_getid()
2214 copen
2215 exe "normal 1G\<CR>"
2216 call assert_equal(last_winid, win_getid())
2217 enew | only
2218
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002219 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2220 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002221 set switchbuf=
2222 edit Xqftestfile1
2223 let file1_winid = win_getid()
2224 new Xqftestfile2
2225 let file2_winid = win_getid()
2226 copen
2227 exe "normal 1G\<CR>"
2228 call assert_equal(file1_winid, win_getid())
2229 copen
2230 exe "normal 3G\<CR>"
2231 call assert_equal(file2_winid, win_getid())
2232 copen | only
2233 exe "normal 5G\<CR>"
2234 call assert_equal(2, winnr('$'))
2235 call assert_equal(1, bufwinnr('Xqftestfile3'))
2236
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002237 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002238 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002239 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002240 set switchbuf=usetab
2241 tabedit Xqftestfile1
2242 tabedit Xqftestfile2
2243 tabedit Xqftestfile3
2244 tabfirst
2245 copen | only
2246 clast
2247 call assert_equal(4, tabpagenr())
2248 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002249
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002250 " Jumping to a file that is not present in any of the tabpages and the
2251 " current tabpage doesn't have any usable windows, should open it in a new
2252 " window in the current tabpage.
2253 copen | only
2254 cfirst
2255 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002256 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002257
2258 " If opening a file changes 'switchbuf', then the new value should be
2259 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002260 set modeline&vim
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002261 call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002262 enew | only
2263 set switchbuf&vim
2264 cexpr "Xqftestfile1:1:10"
2265 call assert_equal('split', &switchbuf)
2266 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2267 enew | only
2268 set switchbuf=useopen
2269 cexpr "Xqftestfile1:1:10"
2270 call assert_equal('usetab', &switchbuf)
2271 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2272 enew | only
2273 set switchbuf=useopen
2274 cexpr "Xqftestfile1:1:10"
2275 call assert_equal('', &switchbuf)
2276
Bram Moolenaar049cba92016-06-26 14:38:04 +02002277 call delete('Xqftestfile2')
2278 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002279 set switchbuf&vim
2280
2281 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002282endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002283
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002284func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002285 call s:setup_commands(a:cchar)
2286
2287 enew | only
2288
Bram Moolenaarc1542742016-07-20 21:44:37 +02002289 let fname = 'Xqftestfile' . a:cchar
2290 call s:create_test_file(fname)
2291 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002292
Bram Moolenaarc1542742016-07-20 21:44:37 +02002293 Xgetexpr [fname . ':5:Line5',
2294 \ fname . ':10:Line10',
2295 \ fname . ':15:Line15',
2296 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002297
2298 6,14delete
2299 call append(6, ['Buffer', 'Window'])
2300
2301 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002302 call assert_equal(5, l[0].lnum)
2303 call assert_equal(6, l[2].lnum)
2304 call assert_equal(13, l[3].lnum)
2305
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002306 " If a file doesn't have any quickfix entries, then deleting lines in the
2307 " file should not update the quickfix list
2308 call g:Xsetlist([], 'f')
2309 1,2delete
2310 call assert_equal([], g:Xgetlist())
2311
Bram Moolenaar049cba92016-06-26 14:38:04 +02002312 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002313 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002314endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002315
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002316func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002317 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002318 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002319 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002320 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002321endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002322
2323" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002324func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002325 call s:setup_commands(a:cchar)
2326
2327 " The following lines are used for the grep test. Don't remove.
2328 " Grep_Test_Text: Match 1
2329 " Grep_Test_Text: Match 2
2330 " GrepAdd_Test_Text: Match 1
2331 " GrepAdd_Test_Text: Match 2
2332 enew! | only
2333 set makeef&vim
2334 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002335 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002336 Xopen
2337 call assert_true(w:quickfix_title =~ '^:grep')
2338 Xclose
2339 enew
2340 set makeef=Temp_File_##
2341 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002342 call assert_true(len(g:Xgetlist()) == 9)
2343
2344 " Try with 'grepprg' set to 'internal'
2345 set grepprg=internal
2346 silent Xgrep Grep_Test_Text: test_quickfix.vim
2347 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2348 call assert_true(len(g:Xgetlist()) == 9)
2349 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002350
2351 call writefile(['Vim'], 'XtestTempFile')
2352 set makeef=XtestTempFile
2353 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002354 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002355 call assert_false(filereadable('XtestTempFile'))
2356 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002357endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002358
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002359func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002360 " The grepprg may not be set on non-Unix systems
2361 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002362
2363 call s:test_xgrep('c')
2364 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002365endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002366
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002367func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002368 " Use one 'errorformat' for two windows. Add an expression to each of them,
2369 " make sure they each keep their own state.
2370 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002371 call mkdir('Xone/a', 'pR')
2372 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002373 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2374 call writefile(lines, 'Xone/a/one.txt')
2375 call writefile(lines, 'Xtwo/a/two.txt')
2376
2377 new one
2378 let one_id = win_getid()
2379 lexpr ""
2380 new two
2381 let two_id = win_getid()
2382 lexpr ""
2383
2384 laddexpr "Entering dir 'Xtwo/a'"
2385 call win_gotoid(one_id)
2386 laddexpr "Entering dir 'Xone/a'"
2387 call win_gotoid(two_id)
2388 laddexpr 'two.txt:5:two two two'
2389 call win_gotoid(one_id)
2390 laddexpr 'one.txt:3:one one one'
2391
2392 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002393 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2394 call assert_equal(3, loc_one[1].lnum)
2395
2396 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002397 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2398 call assert_equal(5, loc_two[1].lnum)
2399
2400 call win_gotoid(one_id)
2401 bwipe!
2402 call win_gotoid(two_id)
2403 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002404endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002405
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002406func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002407 call s:setup_commands(a:cchar)
2408
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002409 " Calling lbottom without any errors should fail
2410 if a:cchar == 'l'
2411 call assert_fails('lbottom', 'E776:')
2412 endif
2413
Bram Moolenaar875feea2017-06-11 16:07:51 +02002414 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002415 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002416 let wid = win_getid()
2417 call assert_equal(1, line('.'))
2418 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002419 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002420 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002421 call win_gotoid(wid)
2422 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002423 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002424endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002425
2426" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002427func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002428 call XbottomTests('c')
2429 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002430endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002431
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002432func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002433 call s:setup_commands(a:cchar)
2434
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002435 " clear all lists after the first one, then replace the first one.
2436 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002437 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002438 let entry = {'filename': 'foo', 'lnum': 42}
2439 call g:Xsetlist([entry], 'r')
2440 call g:Xsetlist([entry, entry])
2441 call g:Xsetlist([entry, entry, entry])
2442 let res = split(execute(a:cchar . 'hist'), "\n")
2443 call assert_equal(3, len(res))
2444 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2445 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2446 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2447 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002448
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002449 " Test for changing the quickfix lists
2450 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2451 exe '1' . a:cchar . 'hist'
2452 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2453 exe '3' . a:cchar . 'hist'
2454 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2455 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2456 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2457
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002458 call g:Xsetlist([], 'f')
2459 let l = split(execute(a:cchar . 'hist'), "\n")
2460 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002461 if a:cchar == 'c'
2462 call assert_fails('4chist', 'E16:')
2463 else
2464 call assert_fails('4lhist', 'E776:')
2465 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002466
2467 " An empty list should still show the stack history
2468 call g:Xsetlist([])
2469 let res = split(execute(a:cchar . 'hist'), "\n")
2470 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2471
2472 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002473endfunc
2474
2475func Test_history()
2476 call HistoryTest('c')
2477 call HistoryTest('l')
2478endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002479
2480func Test_duplicate_buf()
2481 " make sure we can get the highest buffer number
2482 edit DoesNotExist
2483 edit DoesNotExist2
2484 let last_buffer = bufnr("$")
2485
2486 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002487 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002488 vimgrep one Xgrepthis
2489 vimgrep one Xgrepthis
2490 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002491endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002492
2493" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002494func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002495 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002496
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002497 " Error cases
2498 call assert_fails('call g:Xgetlist(99)', 'E715:')
2499 call assert_fails('call g:Xsetlist(99)', 'E714:')
2500 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002501
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002502 " Set and get the title
2503 call g:Xsetlist([])
2504 Xopen
2505 wincmd p
2506 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2507 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2508 call assert_equal(0, s)
2509 let d = g:Xgetlist({"title":1})
2510 call assert_equal('Sample', d.title)
2511 " Try setting title to a non-string value
2512 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2513 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2514
2515 Xopen
2516 call assert_equal('Sample', w:quickfix_title)
2517 Xclose
2518
2519 " Tests for action argument
2520 silent! Xolder 999
2521 let qfnr = g:Xgetlist({'all':1}).nr
2522 call g:Xsetlist([], 'r', {'title' : 'N1'})
2523 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2524 call g:Xsetlist([], ' ', {'title' : 'N2'})
2525 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2526
2527 let res = g:Xgetlist({'nr': 0})
2528 call assert_equal(qfnr + 1, res.nr)
2529 call assert_equal(['nr'], keys(res))
2530
2531 call g:Xsetlist([], ' ', {'title' : 'N3'})
2532 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2533
2534 " Changing the title of an earlier quickfix list
2535 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2536 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2537
2538 " Changing the title of an invalid quickfix list
2539 call assert_equal(-1, g:Xsetlist([], ' ',
2540 \ {'title' : 'SomeTitle', 'nr' : 99}))
2541 call assert_equal(-1, g:Xsetlist([], ' ',
2542 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2543
2544 if a:cchar == 'c'
2545 copen
2546 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2547 cclose
2548 endif
2549
2550 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002551 call assert_fails('call g:Xgetlist([])', 'E715:')
2552 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002553 let s = g:Xsetlist([], 'a', {'abc':1})
2554 call assert_equal(-1, s)
2555
2556 call assert_equal({}, g:Xgetlist({'abc':1}))
2557 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2558 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2559
2560 if a:cchar == 'l'
2561 call assert_equal({}, getloclist(99, {'title': 1}))
2562 endif
2563
2564 " Context related tests
2565 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2566 call assert_equal(0, s)
2567 call test_garbagecollect_now()
2568 let d = g:Xgetlist({'context':1})
2569 call assert_equal([1,2,3], d.context)
2570 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2571 let d = g:Xgetlist({'context':1})
2572 call assert_equal({'color':'green'}, d.context)
2573 call g:Xsetlist([], 'a', {'context':"Context info"})
2574 let d = g:Xgetlist({'context':1})
2575 call assert_equal("Context info", d.context)
2576 call g:Xsetlist([], 'a', {'context':246})
2577 let d = g:Xgetlist({'context':1})
2578 call assert_equal(246, d.context)
2579 " set other Vim data types as context
2580 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2581 if has('channel')
2582 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2583 endif
2584 if has('job')
2585 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2586 endif
2587 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2588 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2589 call g:Xsetlist([], 'a', {'context' : ''})
2590 call test_garbagecollect_now()
2591 if a:cchar == 'l'
2592 " Test for copying context across two different location lists
2593 new | only
2594 let w1_id = win_getid()
2595 let l = [1]
2596 call setloclist(0, [], 'a', {'context':l})
2597 new
2598 let w2_id = win_getid()
2599 call add(l, 2)
2600 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2601 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2602 unlet! l
2603 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2604 only
2605 call setloclist(0, [], 'f')
2606 call assert_equal('', getloclist(0, {'context':1}).context)
2607 endif
2608
2609 " Test for changing the context of previous quickfix lists
2610 call g:Xsetlist([], 'f')
2611 Xexpr "One"
2612 Xexpr "Two"
2613 Xexpr "Three"
2614 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2615 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2616 " Also, check for setting the context using quickfix list number zero.
2617 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2618 call test_garbagecollect_now()
2619 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2620 call assert_equal([1], l.context)
2621 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2622 call assert_equal([2], l.context)
2623 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2624 call assert_equal([3], l.context)
2625
2626 " Test for changing the context through reference and for garbage
2627 " collection of quickfix context
2628 let l = ["red"]
2629 call g:Xsetlist([], ' ', {'context' : l})
2630 call add(l, "blue")
2631 let x = g:Xgetlist({'context' : 1})
2632 call add(x.context, "green")
2633 call assert_equal(["red", "blue", "green"], l)
2634 call assert_equal(["red", "blue", "green"], x.context)
2635 unlet l
2636 call test_garbagecollect_now()
2637 let m = g:Xgetlist({'context' : 1})
2638 call assert_equal(["red", "blue", "green"], m.context)
2639
2640 " Test for setting/getting items
2641 Xexpr ""
2642 let qfprev = g:Xgetlist({'nr':0})
2643 let s = g:Xsetlist([], ' ', {'title':'Green',
2644 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2645 call assert_equal(0, s)
2646 let qfcur = g:Xgetlist({'nr':0})
2647 call assert_true(qfcur.nr == qfprev.nr + 1)
2648 let l = g:Xgetlist({'items':1})
2649 call assert_equal('F1', bufname(l.items[0].bufnr))
2650 call assert_equal(10, l.items[0].lnum)
2651 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2652 \ {'filename':'F2', 'lnum':30}]})
2653 let l = g:Xgetlist({'items':1})
2654 call assert_equal('F2', bufname(l.items[2].bufnr))
2655 call assert_equal(30, l.items[2].lnum)
2656 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2657 let l = g:Xgetlist({'items':1})
2658 call assert_equal('F3', bufname(l.items[0].bufnr))
2659 call assert_equal(40, l.items[0].lnum)
2660 call g:Xsetlist([], 'r', {'items' : []})
2661 let l = g:Xgetlist({'items':1})
2662 call assert_equal(0, len(l.items))
2663
2664 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2665 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2666 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2667 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2668
2669 " Test for getting id of window associated with a location list window
2670 if a:cchar == 'l'
2671 only
2672 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2673 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002674 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002675 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2676 wincmd w
2677 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2678 only
2679 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002680
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002681 " The following used to crash Vim with address sanitizer
2682 call g:Xsetlist([], 'f')
2683 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2684 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002685
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002686 " Try setting the items using a string
2687 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002688
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002689 " Save and restore the quickfix stack
2690 call g:Xsetlist([], 'f')
2691 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2692 Xexpr "File1:10:Line1"
2693 Xexpr "File2:20:Line2"
2694 Xexpr "File3:30:Line3"
2695 let last_qf = g:Xgetlist({'nr':'$'}).nr
2696 call assert_equal(3, last_qf)
2697 let qstack = []
2698 for i in range(1, last_qf)
2699 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2700 endfor
2701 call g:Xsetlist([], 'f')
2702 for i in range(len(qstack))
2703 call g:Xsetlist([], ' ', qstack[i])
2704 endfor
2705 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2706 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2707 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2708 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2709 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002710
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002711 " Swap two quickfix lists
2712 Xexpr "File1:10:Line10"
2713 Xexpr "File2:20:Line20"
2714 Xexpr "File3:30:Line30"
2715 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2716 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2717 let l1=g:Xgetlist({'nr':1,'all':1})
2718 let l2=g:Xgetlist({'nr':2,'all':1})
2719 let save_id = l1.id
2720 let l1.id=l2.id
2721 let l2.id=save_id
2722 call g:Xsetlist([], 'r', l1)
2723 call g:Xsetlist([], 'r', l2)
2724 let newl1=g:Xgetlist({'nr':1,'all':1})
2725 let newl2=g:Xgetlist({'nr':2,'all':1})
2726 call assert_equal('Fruits', newl1.title)
2727 call assert_equal(['Fruits'], newl1.context)
2728 call assert_equal('Line20', newl1.items[0].text)
2729 call assert_equal('Colors', newl2.title)
2730 call assert_equal(['Colors'], newl2.context)
2731 call assert_equal('Line10', newl2.items[0].text)
2732 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002733
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002734 " Cannot specify both a non-empty list argument and a dict argument
2735 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002736endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002737
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002738func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002739 call Xproperty_tests('c')
2740 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002741endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002742
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002743" Test for setting the current index in the location/quickfix list
2744func Xtest_setqfidx(cchar)
2745 call s:setup_commands(a:cchar)
2746
2747 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2748 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2749 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2750
2751 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2752 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2753 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2754 Xolder 2
2755 Xopen
2756 call assert_equal(3, line('.'))
2757 Xnewer
2758 call assert_equal(2, line('.'))
2759 Xnewer
2760 call assert_equal(2, line('.'))
2761 " Update the current index with the quickfix window open
2762 wincmd w
2763 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2764 Xopen
2765 call assert_equal(3, line('.'))
2766 Xclose
2767
2768 " Set the current index to the last entry
2769 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2770 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2771 " A large value should set the index to the last index
2772 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2773 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2774 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2775 " Invalid index values
2776 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2777 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2778 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2779 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2780 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2781 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2782 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2783
2784 call g:Xsetlist([], 'f')
2785 new | only
2786endfunc
2787
2788func Test_setqfidx()
2789 call Xtest_setqfidx('c')
2790 call Xtest_setqfidx('l')
2791endfunc
2792
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002793" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002794func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002795 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002796endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002797
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002798func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002799 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2800 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2801
2802 let g:acmds = []
2803 cexpr "F1:10:Line 10"
2804 caddexpr "F1:20:Line 20"
2805 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002806 cexpr ""
2807 caddexpr ""
2808 cgetexpr ""
2809 silent! cexpr non_existing_func()
2810 silent! caddexpr non_existing_func()
2811 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002812 let l =<< trim END
2813 precexpr
2814 postcexpr
2815 precaddexpr
2816 postcaddexpr
2817 precgetexpr
2818 postcgetexpr
2819 precexpr
2820 postcexpr
2821 precaddexpr
2822 postcaddexpr
2823 precgetexpr
2824 postcgetexpr
2825 precexpr
2826 precaddexpr
2827 precgetexpr
2828 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002829 call assert_equal(l, g:acmds)
2830
2831 let g:acmds = []
2832 enew! | call append(0, "F2:10:Line 10")
2833 cbuffer!
2834 enew! | call append(0, "F2:20:Line 20")
2835 cgetbuffer
2836 enew! | call append(0, "F2:30:Line 30")
2837 caddbuffer
2838 new
2839 let bnum = bufnr('%')
2840 bunload
2841 exe 'silent! cbuffer! ' . bnum
2842 exe 'silent! cgetbuffer ' . bnum
2843 exe 'silent! caddbuffer ' . bnum
2844 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002845 let l =<< trim END
2846 precbuffer
2847 postcbuffer
2848 precgetbuffer
2849 postcgetbuffer
2850 precaddbuffer
2851 postcaddbuffer
2852 precbuffer
2853 precgetbuffer
2854 precaddbuffer
2855 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002856 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002857
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002858 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2859 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002860 let g:acmds = []
2861 cfile Xtest
2862 caddfile Xtest
2863 cgetfile Xtest
2864 cfile Xempty
2865 caddfile Xempty
2866 cgetfile Xempty
2867 silent! cfile do_not_exist
2868 silent! caddfile do_not_exist
2869 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002870 let l =<< trim END
2871 precfile
2872 postcfile
2873 precaddfile
2874 postcaddfile
2875 precgetfile
2876 postcgetfile
2877 precfile
2878 postcfile
2879 precaddfile
2880 postcaddfile
2881 precgetfile
2882 postcgetfile
2883 precfile
2884 postcfile
2885 precaddfile
2886 postcaddfile
2887 precgetfile
2888 postcgetfile
2889 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002890 call assert_equal(l, g:acmds)
2891
2892 let g:acmds = []
2893 helpgrep quickfix
2894 silent! helpgrep non_existing_help_topic
2895 vimgrep test Xtest
2896 vimgrepadd test Xtest
2897 silent! vimgrep non_existing_test Xtest
2898 silent! vimgrepadd non_existing_test Xtest
2899 set makeprg=
2900 silent! make
2901 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002902 let l =<< trim END
2903 prehelpgrep
2904 posthelpgrep
2905 prehelpgrep
2906 posthelpgrep
2907 previmgrep
2908 postvimgrep
2909 previmgrepadd
2910 postvimgrepadd
2911 previmgrep
2912 postvimgrep
2913 previmgrepadd
2914 postvimgrepadd
2915 premake
2916 postmake
2917 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002918 call assert_equal(l, g:acmds)
2919
2920 if has('unix')
2921 " Run this test only on Unix-like systems. The grepprg may not be set on
2922 " non-Unix systems.
2923 " The following lines are used for the grep test. Don't remove.
2924 " Grep_Autocmd_Text: Match 1
2925 " GrepAdd_Autocmd_Text: Match 2
2926 let g:acmds = []
2927 silent grep Grep_Autocmd_Text test_quickfix.vim
2928 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2929 silent grep abc123def Xtest
2930 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002931 set grepprg=internal
2932 silent grep Grep_Autocmd_Text test_quickfix.vim
2933 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2934 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2935 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2936 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002937 let l =<< trim END
2938 pregrep
2939 postgrep
2940 pregrepadd
2941 postgrepadd
2942 pregrep
2943 postgrep
2944 pregrepadd
2945 postgrepadd
2946 pregrep
2947 postgrep
2948 pregrepadd
2949 postgrepadd
2950 prelgrep
2951 postlgrep
2952 prelgrepadd
2953 postlgrepadd
2954 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002955 call assert_equal(l, g:acmds)
2956 endif
2957
Bram Moolenaarb254af32017-12-18 19:48:58 +01002958 au! QuickFixCmdPre
2959 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002960endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002961
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002962func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002963 set efm=%m
2964 lgetexpr '?'
2965
2966 try
2967 call DoesNotExit()
2968 catch
2969 lgetexpr '1'
2970 finally
2971 lgetexpr '1'
2972 endtry
2973
2974 call assert_equal('1', getloclist(0)[0].text)
2975
2976 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002977endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002978
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002979func Test_caddbuffer_wrong()
2980 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002981 let save_efm = &efm
2982 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2983 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2984 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002985 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002986 bwipe!
2987endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002988
2989func Test_caddexpr_wrong()
2990 " This used to cause a memory access in freed memory.
2991 cbuffer
2992 cbuffer
2993 copen
2994 let save_efm = &efm
2995 set efm=%
2996 call assert_fails('caddexpr ""', 'E376:')
2997 let &efm = save_efm
2998endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002999
3000func Test_dirstack_cleanup()
3001 " This used to cause a memory access in freed memory.
3002 let save_efm = &efm
3003 lexpr '0'
3004 lopen
3005 fun X(c)
3006 let save_efm=&efm
3007 set efm=%D%f
3008 if a:c == 'c'
3009 caddexpr '::'
3010 else
3011 laddexpr ':0:0'
3012 endif
3013 let &efm=save_efm
3014 endfun
3015 call X('c')
3016 call X('l')
3017 call setqflist([], 'r')
3018 caddbuffer
3019 let &efm = save_efm
3020endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003021
3022" Tests for jumping to entries from the location list window and quickfix
3023" window
3024func Test_cwindow_jump()
3025 set efm=%f%%%l%%%m
3026 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3027 lopen | only
3028 lfirst
3029 call assert_true(winnr('$') == 2)
3030 call assert_true(winnr() == 1)
3031 " Location list for the new window should be set
3032 call assert_true(getloclist(0)[2].text == 'Line 30')
3033
3034 " Open a scratch buffer
3035 " Open a new window and create a location list
3036 " Open the location list window and close the other window
3037 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003038 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003039 " should not be used.
3040 enew | only
3041 set buftype=nofile
3042 below new
3043 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3044 lopen
3045 2wincmd c
3046 lnext
3047 call assert_true(winnr('$') == 3)
3048 call assert_true(winnr() == 2)
3049
3050 " Open two windows with two different location lists
3051 " Open the location list window and close the previous window
3052 " Jump to an entry in the location list window
3053 " Should open the file in the first window and not set the location list.
3054 enew | only
3055 lgetexpr ["F1%5%Line 5"]
3056 below new
3057 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3058 lopen
3059 2wincmd c
3060 lnext
3061 call assert_true(winnr() == 1)
3062 call assert_true(getloclist(0)[0].text == 'Line 5')
3063
3064 enew | only
3065 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3066 copen
3067 cnext
3068 call assert_true(winnr('$') == 2)
3069 call assert_true(winnr() == 1)
3070
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003071 " open the quickfix buffer in two windows and jump to an entry. Should open
3072 " the file in the first quickfix window.
3073 enew | only
3074 copen
3075 let bnum = bufnr('')
3076 exe 'sbuffer ' . bnum
3077 wincmd b
3078 cfirst
3079 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003080 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003081 enew | only
3082 exe 'sb' bnum
3083 exe 'botright sb' bnum
3084 wincmd t
3085 clast
3086 call assert_equal(2, winnr())
3087 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3088 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3089
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003090 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003091 " window by wrapping around the window list.
3092 enew | only
3093 call setloclist(0, [], 'f')
3094 new | new
3095 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3096 lopen
3097 1close
3098 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3099 lnext
3100 call assert_equal(3, winnr())
3101 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3102
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003103 enew | only
3104 set efm&vim
3105endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003106
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003107func Test_cwindow_highlight()
3108 CheckScreendump
3109
3110 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003111 call setline(1, ['some', 'text', 'with', 'matches'])
3112 write XCwindow
3113 vimgrep e XCwindow
3114 redraw
3115 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003116 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003117 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003118 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3119 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3120
3121 call term_sendkeys(buf, ":cnext\<CR>")
3122 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3123
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003124 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003125 call term_sendkeys(buf, ":\<CR>")
3126 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3127
3128 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3129 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003130 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3131
3132 call term_sendkeys(buf, "j")
3133 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3134
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003135 " clean up
3136 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003137 call delete('XCwindow')
3138endfunc
3139
Bram Moolenaaree85df32017-03-19 14:19:50 +01003140func XvimgrepTests(cchar)
3141 call s:setup_commands(a:cchar)
3142
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003143 let lines =<< trim END
3144 Editor:VIM vim
3145 Editor:Emacs EmAcS
3146 Editor:Notepad NOTEPAD
3147 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003148 call writefile(lines, 'Xtestfile1', 'D')
3149 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003150
3151 " Error cases
3152 call assert_fails('Xvimgrep /abc *', 'E682:')
3153
3154 let @/=''
3155 call assert_fails('Xvimgrep // *', 'E35:')
3156
3157 call assert_fails('Xvimgrep abc', 'E683:')
3158 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3159 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3160
3161 Xexpr ""
3162 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003163 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003164 let l = g:Xgetlist()
3165 call assert_equal(2, len(l))
3166 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3167
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003168 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003169 let l = g:Xgetlist()
3170 call assert_equal(2, len(l))
3171 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003172 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003173 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003174 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003175
3176 1Xvimgrep ?Editor? Xtestfile*
3177 let l = g:Xgetlist()
3178 call assert_equal(1, len(l))
3179 call assert_equal('Editor:VIM vim', l[0].text)
3180
3181 edit +3 Xtestfile2
3182 Xvimgrep +\cemacs+j Xtestfile1
3183 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003184 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003185 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3186
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003187 " Test for unloading a buffer after vimgrep searched the buffer
3188 %bwipe
3189 Xvimgrep /Editor/j Xtestfile*
3190 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3191 call assert_equal([], getbufinfo('Xtestfile2'))
3192
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003193 " Test for opening the dummy buffer used by vimgrep in a window. The new
3194 " window should be closed
3195 %bw!
3196 augroup QF_Test
3197 au!
3198 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3199 augroup END
3200 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3201 call assert_equal(1, winnr('$'))
3202 augroup QF_Test
3203 au!
3204 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003205endfunc
3206
3207" Tests for the :vimgrep command
3208func Test_vimgrep()
3209 call XvimgrepTests('c')
3210 call XvimgrepTests('l')
3211endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003212
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003213func Test_vimgrep_wildcards_expanded_once()
3214 new X[id-01] file.txt
3215 call setline(1, 'some text to search for')
3216 vimgrep text %
3217 bwipe!
3218endfunc
3219
Bram Moolenaar1c299432018-10-28 14:36:09 +01003220" Test for incsearch highlighting of the :vimgrep pattern
3221" This test used to cause "E315: ml_get: invalid lnum" errors.
3222func Test_vimgrep_incsearch()
3223 enew
3224 set incsearch
3225 call test_override("char_avail", 1)
3226
3227 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3228 let l = getqflist()
3229 call assert_equal(2, len(l))
3230
3231 call test_override("ALL", 0)
3232 set noincsearch
3233endfunc
3234
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003235" Test vimgrep with the last search pattern not set
3236func Test_vimgrep_with_no_last_search_pat()
3237 let lines =<< trim [SCRIPT]
3238 call assert_fails('vimgrep // *', 'E35:')
3239 call writefile(v:errors, 'Xresult')
3240 qall!
3241 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003242 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003243 if RunVim([], [], '--clean -S Xscript')
3244 call assert_equal([], readfile('Xresult'))
3245 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003246 call delete('Xresult')
3247endfunc
3248
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003249" Test vimgrep without swap file
3250func Test_vimgrep_without_swap_file()
3251 let lines =<< trim [SCRIPT]
3252 vimgrep grep test_c*
3253 call writefile(['done'], 'Xresult')
3254 qall!
3255 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003256 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003257 if RunVim([], [], '--clean -n -S Xscript Xscript')
3258 call assert_equal(['done'], readfile('Xresult'))
3259 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003260 call delete('Xresult')
3261endfunc
3262
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003263func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003264 call writefile(['match apple with apple'], 'Xapple', 'D')
3265 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003266 let g:foundSwap = 0
3267 let g:ignoreSwapExists = 1
3268 augroup grep
3269 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3270 augroup END
3271 vimgrep apple Xapple
3272 call assert_equal(1, g:foundSwap)
3273 call assert_match('.Xapple.swo', swapname(''))
3274
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003275 augroup grep
3276 au! SwapExists
3277 augroup END
3278 unlet g:ignoreSwapExists
3279endfunc
3280
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003281func XfreeTests(cchar)
3282 call s:setup_commands(a:cchar)
3283
3284 enew | only
3285
3286 " Deleting the quickfix stack should work even When the current list is
3287 " somewhere in the middle of the stack
3288 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3289 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3290 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3291 Xolder
3292 call g:Xsetlist([], 'f')
3293 call assert_equal(0, len(g:Xgetlist()))
3294
3295 " After deleting the stack, adding a new list should create a stack with a
3296 " single list.
3297 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3298 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3299
3300 " Deleting the stack from a quickfix window should update/clear the
3301 " quickfix/location list window.
3302 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3303 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3304 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3305 Xolder
3306 Xwindow
3307 call g:Xsetlist([], 'f')
3308 call assert_equal(2, winnr('$'))
3309 call assert_equal(1, line('$'))
3310 Xclose
3311
3312 " Deleting the stack from a non-quickfix window should update/clear the
3313 " quickfix/location list window.
3314 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3315 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3316 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3317 Xolder
3318 Xwindow
3319 wincmd p
3320 call g:Xsetlist([], 'f')
3321 call assert_equal(0, len(g:Xgetlist()))
3322 wincmd p
3323 call assert_equal(2, winnr('$'))
3324 call assert_equal(1, line('$'))
3325
3326 " After deleting the location list stack, if the location list window is
3327 " opened, then a new location list should be created. So opening the
3328 " location list window again should not create a new window.
3329 if a:cchar == 'l'
3330 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3331 wincmd p
3332 lopen
3333 call assert_equal(2, winnr('$'))
3334 endif
3335 Xclose
3336endfunc
3337
Bram Moolenaar74240d32017-12-10 15:26:15 +01003338" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003339func Test_qf_free()
3340 call XfreeTests('c')
3341 call XfreeTests('l')
3342endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003343
3344" Test for buffer overflow when parsing lines and adding new entries to
3345" the quickfix list.
3346func Test_bufoverflow()
3347 set efm=%f:%l:%m
3348 cgetexpr ['File1:100:' . repeat('x', 1025)]
3349
3350 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3351 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3352
3353 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003354 let lines =<< trim eval END
3355 Entering directory $"{repeat('a', 1006)}"
3356 File1:10:Hello World
3357 END
3358 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003359 set efm&vim
3360endfunc
3361
Bram Moolenaar875feea2017-06-11 16:07:51 +02003362" Tests for getting the quickfix stack size
3363func XsizeTests(cchar)
3364 call s:setup_commands(a:cchar)
3365
3366 call g:Xsetlist([], 'f')
3367 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003368 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3369 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003370
3371 Xexpr "File1:10:Line1"
3372 Xexpr "File2:20:Line2"
3373 Xexpr "File3:30:Line3"
3374 Xolder | Xolder
3375 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3376 call g:Xsetlist([], 'f')
3377
3378 Xexpr "File1:10:Line1"
3379 Xexpr "File2:20:Line2"
3380 Xexpr "File3:30:Line3"
3381 Xolder | Xolder
3382 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3383 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3384endfunc
3385
3386func Test_Qf_Size()
3387 call XsizeTests('c')
3388 call XsizeTests('l')
3389endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003390
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003391func Test_cclose_from_copen()
3392 augroup QF_Test
3393 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003394 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003395 augroup END
3396 copen
3397 augroup QF_Test
3398 au!
3399 augroup END
3400 augroup! QF_Test
3401endfunc
3402
Bram Moolenaar18141832017-06-25 21:17:25 +02003403func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003404 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003405 " event will be triggered.
3406 call test_override('starting', 1)
3407 augroup QF_Test
3408 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003409 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003410 augroup END
3411 copen
3412 augroup QF_Test
3413 au!
3414 augroup END
3415 augroup! QF_Test
3416 call test_override('starting', 0)
3417endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003418
Bram Moolenaar379fb762018-08-30 15:58:28 +02003419" Check that ":file" without an argument is possible even when "curbuf_lock"
3420" is set.
3421func Test_file_from_copen()
3422 " Works without argument.
3423 augroup QF_Test
3424 au!
3425 au FileType qf file
3426 augroup END
3427 copen
3428
3429 augroup QF_Test
3430 au!
3431 augroup END
3432 cclose
3433
3434 " Fails with argument.
3435 augroup QF_Test
3436 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003437 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003438 augroup END
3439 copen
3440 augroup QF_Test
3441 au!
3442 augroup END
3443 cclose
3444
3445 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003446endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003447
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003448func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003449 augroup QF_Test
3450 au!
3451 au FileType qf resize 5
3452 augroup END
3453 try
3454 " This should succeed without any exception. No other buffers are
3455 " involved in the autocmd.
3456 copen
3457 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003458 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003459 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003460 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003461 augroup! QF_Test
3462 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003463endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003464
Bram Moolenaard0fab102022-10-20 16:03:33 +01003465func Test_filetype_autocmd()
3466 " this changes the location list while it is in use to fill a buffer
3467 lexpr ''
3468 lopen
3469 augroup FT_loclist
3470 au FileType * call setloclist(0, [], 'f')
3471 augroup END
3472 silent! lolder
3473 lexpr ''
3474
3475 augroup FT_loclist
3476 au! FileType
3477 augroup END
3478endfunc
3479
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003480func Test_vimgrep_with_textlock()
3481 new
3482
zeertzjqcfe45652022-05-27 17:26:55 +01003483 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003484 " Check that vimgrep without jumping can be executed.
3485 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3486 normal ax
3487 let qflist = getqflist()
3488 call assert_true(len(qflist) > 0)
3489 call assert_match('RunTheTest', qflist[0].text)
3490 call setqflist([], 'r')
3491 au! InsertCharPre
3492
3493 " Check that vimgrepadd without jumping can be executed.
3494 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3495 normal ax
3496 let qflist = getqflist()
3497 call assert_true(len(qflist) > 0)
3498 call assert_match('RunTheTest', qflist[0].text)
3499 call setqflist([], 'r')
3500 au! InsertCharPre
3501
3502 " Check that lvimgrep without jumping can be executed.
3503 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3504 normal ax
3505 let qflist = getloclist(0)
3506 call assert_true(len(qflist) > 0)
3507 call assert_match('RunTheTest', qflist[0].text)
3508 call setloclist(0, [], 'r')
3509 au! InsertCharPre
3510
3511 " Check that lvimgrepadd without jumping can be executed.
3512 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3513 normal ax
3514 let qflist = getloclist(0)
3515 call assert_true(len(qflist) > 0)
3516 call assert_match('RunTheTest', qflist[0].text)
3517 call setloclist(0, [], 'r')
3518 au! InsertCharPre
3519
3520 " trying to jump will give an error
3521 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3522 call assert_fails('normal ax', 'E565:')
3523 au! InsertCharPre
3524
3525 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3526 call assert_fails('normal ax', 'E565:')
3527 au! InsertCharPre
3528
3529 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3530 call assert_fails('normal ax', 'E565:')
3531 au! InsertCharPre
3532
3533 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3534 call assert_fails('normal ax', 'E565:')
3535 au! InsertCharPre
3536
3537 bwipe!
3538endfunc
3539
Bram Moolenaara8788f42017-07-19 17:06:20 +02003540" Tests for the quickfix buffer b:changedtick variable
3541func Xchangedtick_tests(cchar)
3542 call s:setup_commands(a:cchar)
3543
3544 new | only
3545
3546 Xexpr "" | Xexpr "" | Xexpr ""
3547
3548 Xopen
3549 Xolder
3550 Xolder
3551 Xaddexpr "F1:10:Line10"
3552 Xaddexpr "F2:20:Line20"
3553 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3554 call g:Xsetlist([], 'f')
3555 call assert_equal(8, getbufvar('%', 'changedtick'))
3556 Xclose
3557endfunc
3558
3559func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003560 call Xchangedtick_tests('c')
3561 call Xchangedtick_tests('l')
3562endfunc
3563
3564" Tests for parsing an expression using setqflist()
3565func Xsetexpr_tests(cchar)
3566 call s:setup_commands(a:cchar)
3567
3568 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003569 call g:Xsetlist([], ' ', {'lines' : t})
3570 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003571
3572 let l = g:Xgetlist()
3573 call assert_equal(3, len(l))
3574 call assert_equal(20, l[1].lnum)
3575 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003576 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003577 let l = g:Xgetlist()
3578 call assert_equal(1, len(l))
3579 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003580 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3581 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003582
3583 call g:Xsetlist([], 'f')
3584 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003585 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3586 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3587 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3588 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003589 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3590 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003591
3592 " Adding entries using a custom efm
3593 set efm&
3594 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3595 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3596 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3597 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3598 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3599 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3600 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3601 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003602endfunc
3603
3604func Test_setexpr()
3605 call Xsetexpr_tests('c')
3606 call Xsetexpr_tests('l')
3607endfunc
3608
3609" Tests for per quickfix/location list directory stack
3610func Xmultidirstack_tests(cchar)
3611 call s:setup_commands(a:cchar)
3612
3613 call g:Xsetlist([], 'f')
3614 Xexpr "" | Xexpr ""
3615
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003616 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3617 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3618 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3619 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003620
3621 let l1 = g:Xgetlist({'nr':1, 'items':1})
3622 let l2 = g:Xgetlist({'nr':2, 'items':1})
3623 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3624 call assert_equal(3, l1.items[1].lnum)
3625 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3626 call assert_equal(5, l2.items[1].lnum)
3627endfunc
3628
3629func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003630 call mkdir('Xone/a', 'pR')
3631 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003632 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3633 call writefile(lines, 'Xone/a/one.txt')
3634 call writefile(lines, 'Xtwo/a/two.txt')
3635 let save_efm = &efm
3636 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3637
3638 call Xmultidirstack_tests('c')
3639 call Xmultidirstack_tests('l')
3640
3641 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003642endfunc
3643
3644" Tests for per quickfix/location list file stack
3645func Xmultifilestack_tests(cchar)
3646 call s:setup_commands(a:cchar)
3647
3648 call g:Xsetlist([], 'f')
3649 Xexpr "" | Xexpr ""
3650
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003651 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3652 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3653 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3654 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003655
3656 let l1 = g:Xgetlist({'nr':1, 'items':1})
3657 let l2 = g:Xgetlist({'nr':2, 'items':1})
3658 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3659 call assert_equal(3, l1.items[1].lnum)
3660 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3661 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003662
3663 " Test for start of a new error line in the same line where a previous
3664 " error line ends with a file stack.
3665 let efm_val = 'Error\ l%l\ in\ %f,'
3666 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003667 let lines =<< trim END
3668 (one.txt
3669 Error l4 in one.txt
3670 ) (two.txt
3671 Error l6 in two.txt
3672 )
3673 Error l8 in one.txt
3674 END
3675 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003676 call assert_equal(3, len(l.items))
3677 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3678 call assert_equal(4, l.items[0].lnum)
3679 call assert_equal('one.txt', l.items[0].text)
3680 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3681 call assert_equal(6, l.items[1].lnum)
3682 call assert_equal('two.txt', l.items[1].text)
3683 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3684 call assert_equal(8, l.items[2].lnum)
3685 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003686endfunc
3687
3688func Test_multifilestack()
3689 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003690 call writefile(lines, 'one.txt', 'D')
3691 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003692 let save_efm = &efm
3693 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3694
3695 call Xmultifilestack_tests('c')
3696 call Xmultifilestack_tests('l')
3697
3698 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003699endfunc
3700
3701" Tests for per buffer 'efm' setting
3702func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003703 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3704 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003705 set efm=%f#%l#%m
3706 new | only
3707 new
3708 setlocal efm=%f-%l-%m
3709 cfile one.txt
3710 wincmd w
3711 caddfile two.txt
3712
3713 let l = getqflist()
3714 call assert_equal(10, l[0].lnum)
3715 call assert_equal('Line20', l[1].text)
3716
3717 set efm&
3718 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003719endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003720
3721" Open multiple help windows using ":lhelpgrep
3722" This test used to crash Vim
3723func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003724 new | only
3725 lhelpgrep window
3726 lopen
3727 e#
3728 lhelpgrep buffer
3729 call assert_equal(3, winnr('$'))
3730 call assert_true(len(getloclist(1)) != 0)
3731 call assert_true(len(getloclist(2)) != 0)
3732 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003733endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003734
3735" Tests for adding new quickfix lists using setqflist()
3736func XaddQf_tests(cchar)
3737 call s:setup_commands(a:cchar)
3738
3739 " Create a new list using ' ' for action
3740 call g:Xsetlist([], 'f')
3741 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3742 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3743 call assert_equal(1, l.nr)
3744 call assert_equal('Test1', l.title)
3745
3746 " Create a new list using ' ' for action and '$' for 'nr'
3747 call g:Xsetlist([], 'f')
3748 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3749 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3750 call assert_equal(1, l.nr)
3751 call assert_equal('Test2', l.title)
3752
3753 " Create a new list using 'a' for action
3754 call g:Xsetlist([], 'f')
3755 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3756 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3757 call assert_equal(1, l.nr)
3758 call assert_equal('Test3', l.title)
3759
3760 " Create a new list using 'a' for action and '$' for 'nr'
3761 call g:Xsetlist([], 'f')
3762 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3763 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3764 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3765 call assert_equal(1, l.nr)
3766 call assert_equal('Test4', l.title)
3767
3768 " Adding a quickfix list should remove all the lists following the current
3769 " list.
3770 Xexpr "" | Xexpr "" | Xexpr ""
3771 silent! 10Xolder
3772 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3773 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3774 call assert_equal(2, l.nr)
3775 call assert_equal('Test5', l.title)
3776
3777 " Add a quickfix list using '$' as the list number.
3778 let lastqf = g:Xgetlist({'nr':'$'}).nr
3779 silent! 99Xolder
3780 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3781 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3782 call assert_equal(lastqf + 1, l.nr)
3783 call assert_equal('Test6', l.title)
3784
3785 " Add a quickfix list using 'nr' set to one more than the quickfix
3786 " list size.
3787 let lastqf = g:Xgetlist({'nr':'$'}).nr
3788 silent! 99Xolder
3789 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3790 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3791 call assert_equal(lastqf + 1, l.nr)
3792 call assert_equal('Test7', l.title)
3793
3794 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3795 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3796 silent! 99Xolder
3797 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3798 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3799 call assert_equal(10, l.nr)
3800 call assert_equal('Test8', l.title)
3801
3802 " Add a quickfix list using 'nr' set to a value greater than 10
3803 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3804
3805 " Try adding a quickfix list with 'nr' set to a value greater than the
3806 " quickfix list size but less than 10.
3807 call g:Xsetlist([], 'f')
3808 Xexpr "" | Xexpr "" | Xexpr ""
3809 silent! 99Xolder
3810 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3811
3812 " Add a quickfix list using 'nr' set to a some string or list
3813 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3814endfunc
3815
3816func Test_add_qf()
3817 call XaddQf_tests('c')
3818 call XaddQf_tests('l')
3819endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003820
3821" Test for getting the quickfix list items from some text without modifying
3822" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003823func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003824 call s:setup_commands(a:cchar)
3825 call g:Xsetlist([], 'f')
3826
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003827 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003828 call assert_equal(2, len(l))
3829 call assert_equal(30, l[1].lnum)
3830
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003831 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3832 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3833 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3834 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003835
Bram Moolenaar36538222017-09-02 19:51:44 +02003836 " Parse text using a custom efm
3837 set efm&
3838 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3839 call assert_equal('Line30', l[0].text)
3840 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3841 call assert_equal('File3:30:Line30', l[0].text)
3842 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3843 call assert_equal({}, l)
3844 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3845 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3846
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003847 " Make sure that the quickfix stack is not modified
3848 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3849endfunc
3850
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003851func Test_get_list_from_lines()
3852 call XgetListFromLines('c')
3853 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003854endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003855
3856" Tests for the quickfix list id
3857func Xqfid_tests(cchar)
3858 call s:setup_commands(a:cchar)
3859
3860 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003861 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003862 Xexpr ''
3863 let start_id = g:Xgetlist({'id' : 0}).id
3864 Xexpr '' | Xexpr ''
3865 Xolder
3866 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3867 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3868 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003869 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003870 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003871 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3872 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003873
3874 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3875 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003876 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003877 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3878 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3879 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3880
3881 let qfid = g:Xgetlist({'id':0, 'nr':0})
3882 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003883 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003884endfunc
3885
3886func Test_qf_id()
3887 call Xqfid_tests('c')
3888 call Xqfid_tests('l')
3889endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003890
3891func Xqfjump_tests(cchar)
3892 call s:setup_commands(a:cchar)
3893
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003894 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3895 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3896 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003897
3898 call g:Xsetlist([], 'f')
3899
3900 " Tests for
3901 " Jumping to a line using a pattern
3902 " Jumping to a column greater than the last column in a line
3903 " Jumping to a line greater than the last line in the file
3904 let l = []
3905 for i in range(1, 7)
3906 call add(l, {})
3907 endfor
3908 let l[0].filename='F1'
3909 let l[0].pattern='Line1'
3910 let l[1].filename='F2'
3911 let l[1].pattern='Line1'
3912 let l[2].filename='F3'
3913 let l[2].pattern='Line1'
3914 let l[3].filename='F3'
3915 let l[3].lnum=1
3916 let l[3].col=9
3917 let l[3].vcol=1
3918 let l[4].filename='F3'
3919 let l[4].lnum=99
3920 let l[5].filename='F3'
3921 let l[5].lnum=1
3922 let l[5].col=99
3923 let l[5].vcol=1
3924 let l[6].filename='F3'
3925 let l[6].pattern='abcxyz'
3926
3927 call g:Xsetlist([], ' ', {'items' : l})
3928 Xopen | only
3929 2Xnext
3930 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003931 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003932 Xnext
3933 call assert_equal(7, col('.'))
3934 Xnext
3935 call assert_equal(2, line('.'))
3936 Xnext
3937 call assert_equal(9, col('.'))
3938 2
3939 Xnext
3940 call assert_equal(2, line('.'))
3941
3942 if a:cchar == 'l'
3943 " When jumping to a location list entry in the location list window and
3944 " no usable windows are available, then a new window should be opened.
3945 enew! | new | only
3946 call g:Xsetlist([], 'f')
3947 setlocal buftype=nofile
3948 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003949 let lines =<< trim END
3950 F1:1:1:Line1
3951 F1:2:2:Line2
3952 F2:1:1:Line1
3953 F2:2:2:Line2
3954 F3:1:1:Line1
3955 F3:2:2:Line2
3956 END
3957 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003958 Xopen
3959 let winid = win_getid()
3960 wincmd p
3961 close
3962 call win_gotoid(winid)
3963 Xnext
3964 call assert_equal(3, winnr('$'))
3965 call assert_equal(1, winnr())
3966 call assert_equal(2, line('.'))
3967
3968 " When jumping to an entry in the location list window and the window
3969 " associated with the location list is not present and a window containing
3970 " the file is already present, then that window should be used.
3971 close
3972 belowright new
3973 call g:Xsetlist([], 'f')
3974 edit F3
3975 call win_gotoid(winid)
3976 Xlast
3977 call assert_equal(3, winnr())
3978 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3979 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3980 endif
3981
3982 " Cleanup
3983 enew!
3984 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01003985endfunc
3986
3987func Test_qfjump()
3988 call Xqfjump_tests('c')
3989 call Xqfjump_tests('l')
3990endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003991
3992" Tests for the getqflist() and getloclist() functions when the list is not
3993" present or is empty
3994func Xgetlist_empty_tests(cchar)
3995 call s:setup_commands(a:cchar)
3996
3997 " Empty quickfix stack
3998 call g:Xsetlist([], 'f')
3999 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4000 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
4001 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4002 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4003 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4004 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4005 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4006 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004007 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004008 if a:cchar == 'c'
4009 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004010 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004011 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4012 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004013 else
4014 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4015 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004016 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004017 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004018 \ g:Xgetlist({'all' : 0}))
4019 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004020
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004021 " Quickfix window with empty stack
4022 silent! Xopen
4023 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004024 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004025 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4026 Xclose
4027
Bram Moolenaara6d48492017-12-12 22:45:31 +01004028 " Empty quickfix list
4029 Xexpr ""
4030 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4031 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4032 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4033 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4034 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4035 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4036 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4037 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004038 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004039
4040 let qfid = g:Xgetlist({'id' : 0}).id
4041 call g:Xsetlist([], 'f')
4042
4043 " Non-existing quickfix identifier
4044 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4045 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4046 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4047 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4048 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4049 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4050 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4051 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004052 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004053 if a:cchar == 'c'
4054 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4055 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004056 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004057 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4058 else
4059 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4060 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004061 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4062 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004063 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4064 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004065
4066 " Non-existing quickfix list number
4067 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4068 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4069 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4070 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4071 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4072 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4073 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4074 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004075 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004076 if a:cchar == 'c'
4077 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4078 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004079 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4080 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004081 else
4082 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4083 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004084 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4085 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004086 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004087endfunc
4088
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004089func Test_empty_list_quickfixtextfunc()
4090 " This was crashing. Can only reproduce by running it in a separate Vim
4091 " instance.
4092 let lines =<< trim END
4093 func s:Func(o)
4094 cgetexpr '0'
4095 endfunc
4096 cope
4097 let &quickfixtextfunc = 's:Func'
4098 cgetfile [ex
4099 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004100 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004101 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004102endfunc
4103
Bram Moolenaara6d48492017-12-12 22:45:31 +01004104func Test_getqflist()
4105 call Xgetlist_empty_tests('c')
4106 call Xgetlist_empty_tests('l')
4107endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004108
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004109func Test_getqflist_invalid_nr()
4110 " The following commands used to crash Vim
4111 cexpr ""
4112 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4113
4114 " Cleanup
4115 call setqflist([], 'r')
4116endfunc
4117
Bram Moolenaarb254af32017-12-18 19:48:58 +01004118" Tests for the quickfix/location list changedtick
4119func Xqftick_tests(cchar)
4120 call s:setup_commands(a:cchar)
4121
4122 call g:Xsetlist([], 'f')
4123
4124 Xexpr "F1:10:Line10"
4125 let qfid = g:Xgetlist({'id' : 0}).id
4126 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4127 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4128 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4129 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4130 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4131 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4132 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4133 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4134 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4135
4136 enew!
4137 call append(0, ["F5:50:L50", "F6:60:L60"])
4138 Xaddbuffer
4139 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4140 enew!
4141
4142 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4143 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4144 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4145 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4146 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4147 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4148 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4149 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4150 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4151 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4152 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4153
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004154 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004155 Xfile Xone
4156 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4157 Xaddfile Xone
4158 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4159
4160 " Test case for updating a non-current quickfix list
4161 call g:Xsetlist([], 'f')
4162 Xexpr "F1:1:L1"
4163 Xexpr "F2:2:L2"
4164 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4165 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4166 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004167endfunc
4168
4169func Test_qf_tick()
4170 call Xqftick_tests('c')
4171 call Xqftick_tests('l')
4172endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004173
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004174" Test helpgrep with lang specifier
4175func Xtest_helpgrep_with_lang_specifier(cchar)
4176 call s:setup_commands(a:cchar)
4177 Xhelpgrep Vim@en
4178 call assert_equal('help', &filetype)
4179 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4180 new | only
4181endfunc
4182
4183func Test_helpgrep_with_lang_specifier()
4184 call Xtest_helpgrep_with_lang_specifier('c')
4185 call Xtest_helpgrep_with_lang_specifier('l')
4186endfunc
4187
Bram Moolenaar12237442017-12-19 12:38:52 +01004188" The following test used to crash Vim.
4189" Open the location list window and close the regular window associated with
4190" the location list. When the garbage collection runs now, it incorrectly
4191" marks the location list context as not in use and frees the context.
4192func Test_ll_window_ctx()
4193 call setloclist(0, [], 'f')
4194 call setloclist(0, [], 'a', {'context' : []})
4195 lopen | only
4196 call test_garbagecollect_now()
4197 echo getloclist(0, {'context' : 1}).context
4198 enew | only
4199endfunc
4200
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004201" The following test used to crash vim
4202func Test_lfile_crash()
4203 sp Xtest
4204 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004205 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004206 au! QuickFixCmdPre
4207endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004208
4209" The following test used to crash vim
4210func Test_lbuffer_crash()
4211 sv Xtest
4212 augroup QF_Test
4213 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004214 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004215 augroup END
4216 lbuffer
4217 augroup QF_Test
4218 au!
4219 augroup END
4220endfunc
4221
4222" The following test used to crash vim
4223func Test_lexpr_crash()
4224 augroup QF_Test
4225 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004226 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004227 augroup END
4228 lexpr ""
4229 augroup QF_Test
4230 au!
4231 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004232
Bram Moolenaar3c097222017-12-21 20:54:49 +01004233 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004234 augroup QF_Test
4235 au!
4236 au BufNew * call setloclist(0, [], 'f')
4237 augroup END
4238 lexpr 'x:1:x'
4239 augroup QF_Test
4240 au!
4241 augroup END
4242
4243 enew | only
4244 lexpr ''
4245 lopen
4246 augroup QF_Test
4247 au!
4248 au FileType * call setloclist(0, [], 'f')
4249 augroup END
4250 lexpr ''
4251 augroup QF_Test
4252 au!
4253 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004254endfunc
4255
4256" The following test used to crash Vim
4257func Test_lvimgrep_crash()
4258 sv Xtest
4259 augroup QF_Test
4260 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004261 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004262 augroup END
4263 lvimgrep quickfix test_quickfix.vim
4264 augroup QF_Test
4265 au!
4266 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004267
4268 new | only
4269 augroup QF_Test
4270 au!
4271 au BufEnter * call setloclist(0, [], 'r')
4272 augroup END
4273 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4274 augroup QF_Test
4275 au!
4276 augroup END
4277
Bram Moolenaar3c097222017-12-21 20:54:49 +01004278 enew | only
4279endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004280
Bram Moolenaar2573af32020-03-14 17:21:34 +01004281func Test_lvimgrep_crash2()
4282 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004283 call assert_fails('lvimgrep x x', 'E471:')
4284 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004285
4286 au! BufNewFile
4287endfunc
4288
Bram Moolenaarde046542017-12-26 13:53:11 +01004289" Test for the position of the quickfix and location list window
4290func Test_qfwin_pos()
4291 " Open two windows
4292 new | only
4293 new
4294 cexpr ['F1:10:L10']
4295 copen
4296 " Quickfix window should be the bottom most window
4297 call assert_equal(3, winnr())
4298 close
4299 " Open at the very top
4300 wincmd t
4301 topleft copen
4302 call assert_equal(1, winnr())
4303 close
4304 " open left of the current window
4305 wincmd t
4306 below new
4307 leftabove copen
4308 call assert_equal(2, winnr())
4309 close
4310 " open right of the current window
4311 rightbelow copen
4312 call assert_equal(3, winnr())
4313 close
4314endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004315
4316" Tests for quickfix/location lists changed by autocommands when
4317" :vimgrep/:lvimgrep commands are running.
4318func Test_vimgrep_autocmd()
4319 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004320 call writefile(['stars'], 'Xtest1.txt', 'D')
4321 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004322
4323 " Test 1:
4324 " When searching for a pattern using :vimgrep, if the quickfix list is
4325 " changed by an autocmd, the results should be added to the correct quickfix
4326 " list.
4327 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4328 silent vimgrep stars Xtest*.txt
4329 call assert_equal(1, getqflist({'nr' : 0}).nr)
4330 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4331 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4332 au! BufRead Xtest2.txt
4333
4334 " Test 2:
4335 " When searching for a pattern using :vimgrep, if the quickfix list is
4336 " freed, then a error should be given.
4337 silent! %bwipe!
4338 call setqflist([], 'f')
4339 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4340 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4341 au! BufRead Xtest2.txt
4342
4343 " Test 3:
4344 " When searching for a pattern using :lvimgrep, if the location list is
4345 " freed, then the command should error out.
4346 silent! %bwipe!
4347 let g:save_winid = win_getid()
4348 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4349 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4350 au! BufRead Xtest2.txt
4351
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004352 call setqflist([], 'f')
4353endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004354
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004355" Test for an autocmd changing the current directory when running vimgrep
4356func Xvimgrep_autocmd_cd(cchar)
4357 call s:setup_commands(a:cchar)
4358
4359 %bwipe
4360 let save_cwd = getcwd()
4361
4362 augroup QF_Test
4363 au!
4364 autocmd BufRead * silent cd %:p:h
4365 augroup END
4366
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004367 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004368 let l = g:Xgetlist()
4369 call assert_equal('f1.txt', bufname(l[0].bufnr))
4370 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4371
4372 augroup QF_Test
4373 au!
4374 augroup END
4375
4376 exe 'cd ' . save_cwd
4377endfunc
4378
4379func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004380 call mkdir('Xgrepdir/a', 'pR')
4381 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004382 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4383 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004384 call Xvimgrep_autocmd_cd('c')
4385 call Xvimgrep_autocmd_cd('l')
4386 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004387endfunc
4388
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004389" The following test used to crash Vim
4390func Test_lhelpgrep_autocmd()
4391 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004392 augroup QF_Test
4393 au!
4394 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4395 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004396 lhelpgrep buffer
4397 call assert_equal('help', &filetype)
4398 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4399 lhelpgrep tabpage
4400 call assert_equal('help', &filetype)
4401 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004402 augroup QF_Test
4403 au!
4404 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004405
4406 new | only
4407 augroup QF_Test
4408 au!
4409 au BufEnter * call setqflist([], 'f')
4410 augroup END
4411 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004412 " run the test with a help window already open
4413 help
4414 wincmd w
4415 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004416 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004417 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004418 augroup END
4419
4420 new | only
4421 augroup QF_Test
4422 au!
4423 au BufEnter * call setqflist([], 'r')
4424 augroup END
4425 call assert_fails('helpgrep quickfix', 'E925:')
4426 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 setloclist(0, [], 'r')
4434 augroup END
4435 call assert_fails('lhelpgrep quickfix', 'E926:')
4436 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004437 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004438 augroup END
4439
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004440 " Replace the contents of a help window location list when it is still in
4441 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004442 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004443 lhelpgrep quickfix
4444 wincmd w
4445 augroup QF_Test
4446 au!
4447 autocmd WinEnter * call setloclist(0, [], 'r')
4448 augroup END
4449 call assert_fails('lhelpgrep win_getid', 'E926:')
4450 augroup QF_Test
4451 au!
4452 augroup END
4453
4454 %bw!
4455endfunc
4456
4457" The following test used to crash Vim
4458func Test_lhelpgrep_autocmd_free_loclist()
4459 %bw!
4460 lhelpgrep quickfix
4461 wincmd w
4462 augroup QF_Test
4463 au!
4464 autocmd WinEnter * call setloclist(0, [], 'f')
4465 augroup END
4466 lhelpgrep win_getid
4467 wincmd w
4468 wincmd w
4469 wincmd w
4470 augroup QF_Test
4471 au!
4472 augroup END
4473 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004474endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004475
4476" Test for shortening/simplifying the file name when opening the
4477" quickfix window or when displaying the quickfix list
4478func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004479 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004480 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004481 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004482 let fname = getcwd() . '/test_quickfix.vim'
4483 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4484 call assert_equal(fname, bufname('test_quickfix.vim'))
4485 " Opening the quickfix window should simplify the file path
4486 cwindow
4487 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4488 cclose
4489 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004490 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004491 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4492 call assert_equal(fname, bufname('test_quickfix.vim'))
4493 " Displaying the quickfix list should simplify the file path
4494 silent! clist
4495 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004496 " Add a few entries for the same file with different paths and check whether
4497 " the buffer name is shortened
4498 %bwipe
4499 call setqflist([], 'f')
4500 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4501 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4502 \ {'filename' : fname, 'lnum' : 30}], ' ')
4503 copen
4504 call assert_equal(['test_quickfix.vim|10| ',
4505 \ 'test_quickfix.vim|20| ',
4506 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4507 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004508endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004509
4510" Quickfix title tests
4511" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4512" Otherwise due to indentation, the title is set with spaces at the beginning
4513" of the command.
4514func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004515 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004516
4517 " :cexpr
4518 exe "cexpr readfile('Xerr')"
4519 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4520
4521 " :cgetexpr
4522 exe "cgetexpr readfile('Xerr')"
4523 call assert_equal(":cgetexpr readfile('Xerr')",
4524 \ getqflist({'title' : 1}).title)
4525
4526 " :caddexpr
4527 call setqflist([], 'f')
4528 exe "caddexpr readfile('Xerr')"
4529 call assert_equal(":caddexpr readfile('Xerr')",
4530 \ getqflist({'title' : 1}).title)
4531
4532 " :cbuffer
4533 new Xerr
4534 exe "cbuffer"
4535 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4536
4537 " :cgetbuffer
4538 edit Xerr
4539 exe "cgetbuffer"
4540 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4541
4542 " :caddbuffer
4543 call setqflist([], 'f')
4544 edit Xerr
4545 exe "caddbuffer"
4546 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4547
4548 " :cfile
4549 exe "cfile Xerr"
4550 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4551
4552 " :cgetfile
4553 exe "cgetfile Xerr"
4554 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4555
4556 " :caddfile
4557 call setqflist([], 'f')
4558 exe "caddfile Xerr"
4559 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4560
4561 " :grep
4562 set grepprg=internal
4563 exe "grep F1 Xerr"
4564 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4565
4566 " :grepadd
4567 call setqflist([], 'f')
4568 exe "grepadd F1 Xerr"
4569 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4570 set grepprg&vim
4571
4572 " :vimgrep
4573 exe "vimgrep F1 Xerr"
4574 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4575
4576 " :vimgrepadd
4577 call setqflist([], 'f')
4578 exe "vimgrepadd F1 Xerr"
4579 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4580
4581 call setqflist(['F1:10:L10'], ' ')
4582 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4583
4584 call setqflist([], 'f')
4585 call setqflist(['F1:10:L10'], 'a')
4586 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4587
4588 call setqflist([], 'f')
4589 call setqflist(['F1:10:L10'], 'r')
4590 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4591
4592 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004593
4594 call setqflist([], ' ', {'title' : 'Errors'})
4595 copen
4596 call assert_equal('Errors', w:quickfix_title)
4597 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4598 call assert_equal('Errors', w:quickfix_title)
4599 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004600
4601 " Switching to another quickfix list in one tab page should update the
4602 " quickfix window title and statusline in all the other tab pages also
4603 call setqflist([], 'f')
4604 %bw!
4605 cgetexpr ['file_one:1:1: error in the first quickfix list']
4606 call setqflist([], 'a', {'title': 'first quickfix list'})
4607 cgetexpr ['file_two:2:1: error in the second quickfix list']
4608 call setqflist([], 'a', {'title': 'second quickfix list'})
4609 copen
4610 wincmd t
4611 tabnew two
4612 copen
4613 wincmd t
4614 colder
4615 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4616 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4617 call assert_equal(1, tabpagewinnr(1))
4618 call assert_equal(1, tabpagewinnr(2))
4619 tabnew
4620 call setqflist([], 'a', {'title': 'new quickfix title'})
4621 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4622 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4623 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004624endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004625
4626func Test_lbuffer_with_bwipe()
4627 new
4628 new
4629 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004630 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004631 augroup END
4632 lbuffer
4633 augroup nasty
4634 au!
4635 augroup END
4636endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004637
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004638" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4639" running
4640func Xexpr_acmd_freelist(cchar)
4641 call s:setup_commands(a:cchar)
4642
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004643 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004644 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004645 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004646 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004647 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004648 augroup nasty
4649 au!
4650 augroup END
4651endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004652
4653func Test_cexpr_acmd_freelist()
4654 call Xexpr_acmd_freelist('c')
4655 call Xexpr_acmd_freelist('l')
4656endfunc
4657
4658" Test for commands that create a new quickfix/location list and jump to the
4659" first error automatically.
4660func Xjumpto_first_error_test(cchar)
4661 call s:setup_commands(a:cchar)
4662
4663 call s:create_test_file('Xtestfile1')
4664 call s:create_test_file('Xtestfile2')
4665 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4666
4667 " Test for cexpr/lexpr
4668 enew
4669 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004670 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004671 call assert_equal(2, line('.'))
4672
4673 " Test for cfile/lfile
4674 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004675 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004676 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004677 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004678 call assert_equal(2, line('.'))
4679
4680 " Test for cbuffer/lbuffer
4681 edit Xerr
4682 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004683 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004684 call assert_equal(2, line('.'))
4685
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004686 call delete('Xtestfile1')
4687 call delete('Xtestfile2')
4688endfunc
4689
4690func Test_jumpto_first_error()
4691 call Xjumpto_first_error_test('c')
4692 call Xjumpto_first_error_test('l')
4693endfunc
4694
4695" Test for a quickfix autocmd changing the quickfix/location list before
4696" jumping to the first error in the new list.
4697func Xautocmd_changelist(cchar)
4698 call s:setup_commands(a:cchar)
4699
4700 " Test for cfile/lfile
4701 call s:create_test_file('Xtestfile1')
4702 call s:create_test_file('Xtestfile2')
4703 Xexpr 'Xtestfile1:2:Line2'
4704 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004705 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004706 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004707 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004708 call assert_equal(4, line('.'))
4709 autocmd! QuickFixCmdPost
4710
4711 " Test for cbuffer/lbuffer
4712 call g:Xsetlist([], 'f')
4713 Xexpr 'Xtestfile1:2:Line2'
4714 autocmd QuickFixCmdPost * Xolder
4715 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4716 edit Xerr
4717 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004718 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004719 call assert_equal(4, line('.'))
4720 autocmd! QuickFixCmdPost
4721
4722 " Test for cexpr/lexpr
4723 call g:Xsetlist([], 'f')
4724 Xexpr 'Xtestfile1:2:Line2'
4725 autocmd QuickFixCmdPost * Xolder
4726 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004727 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004728 call assert_equal(4, line('.'))
4729 autocmd! QuickFixCmdPost
4730
Bram Moolenaar851332e2018-07-03 19:16:00 +02004731 " The grepprg may not be set on non-Unix systems
4732 if has('unix')
4733 " Test for grep/lgrep
4734 call g:Xsetlist([], 'f')
4735 Xexpr 'Xtestfile1:2:Line2'
4736 autocmd QuickFixCmdPost * Xolder
4737 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004738 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004739 call assert_equal(5, line('.'))
4740 autocmd! QuickFixCmdPost
4741 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004742
4743 " Test for vimgrep/lvimgrep
4744 call g:Xsetlist([], 'f')
4745 Xexpr 'Xtestfile1:2:Line2'
4746 autocmd QuickFixCmdPost * Xolder
4747 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004748 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004749 call assert_equal(5, line('.'))
4750 autocmd! QuickFixCmdPost
4751
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004752 " Test for autocommands clearing the quickfix list before jumping to the
4753 " first error. This should not result in an error
4754 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4755 let v:errmsg = ''
4756 " Test for cfile/lfile
4757 Xfile Xerr
4758 call assert_true(v:errmsg !~# 'E42:')
4759 " Test for cbuffer/lbuffer
4760 edit Xerr
4761 Xbuffer
4762 call assert_true(v:errmsg !~# 'E42:')
4763 " Test for cexpr/lexpr
4764 Xexpr 'Xtestfile2:4:Line4'
4765 call assert_true(v:errmsg !~# 'E42:')
4766 " Test for grep/lgrep
4767 " The grepprg may not be set on non-Unix systems
4768 if has('unix')
4769 silent Xgrep Line5 Xtestfile2
4770 call assert_true(v:errmsg !~# 'E42:')
4771 endif
4772 " Test for vimgrep/lvimgrep
4773 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4774 autocmd! QuickFixCmdPost
4775
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004776 call delete('Xtestfile1')
4777 call delete('Xtestfile2')
4778endfunc
4779
4780func Test_autocmd_changelist()
4781 call Xautocmd_changelist('c')
4782 call Xautocmd_changelist('l')
4783endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004784
4785" Tests for the ':filter /pat/ clist' command
4786func Test_filter_clist()
4787 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4788 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4789 \ split(execute('filter /Line 15/ clist'), "\n"))
4790 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4791 \ split(execute('filter /Xfile1/ clist'), "\n"))
4792 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4793
4794 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4795 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4796 call assert_equal([' 2 pqr:pat2: '],
4797 \ split(execute('filter /pqr/ clist'), "\n"))
4798 call assert_equal([' 1 abc:pat1: '],
4799 \ split(execute('filter /pat1/ clist'), "\n"))
4800endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004801
4802" Tests for the "CTRL-W <CR>" command.
4803func Xview_result_split_tests(cchar)
4804 call s:setup_commands(a:cchar)
4805
4806 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4807 call g:Xsetlist([])
4808 Xopen
4809 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004810 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004811 call assert_equal(l:win_count, winnr('$'))
4812 Xclose
4813endfunc
4814
4815func Test_view_result_split()
4816 call Xview_result_split_tests('c')
4817 call Xview_result_split_tests('l')
4818endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004819
4820" Test that :cc sets curswant
4821func Test_curswant()
4822 helpgrep quickfix
4823 normal! llll
4824 1cc
4825 call assert_equal(getcurpos()[4], virtcol('.'))
4826 cclose | helpclose
4827endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004828
4829" Test for opening a file from the quickfix window using CTRL-W <Enter>
4830" doesn't leave an empty buffer around.
4831func Test_splitview()
4832 call s:create_test_file('Xtestfile1')
4833 call s:create_test_file('Xtestfile2')
4834 new | only
4835 let last_bufnr = bufnr('Test_sv_1', 1)
4836 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4837 cgetexpr l
4838 copen
4839 let numbufs = len(getbufinfo())
4840 exe "normal \<C-W>\<CR>"
4841 copen
4842 exe "normal j\<C-W>\<CR>"
4843 " Make sure new empty buffers are not created
4844 call assert_equal(numbufs, len(getbufinfo()))
4845 " Creating a new buffer should use the next available buffer number
4846 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4847 bwipe Test_sv_1
4848 bwipe Test_sv_2
4849 new | only
4850
4851 " When split opening files from location list window, make sure that two
4852 " windows doesn't refer to the same location list
4853 lgetexpr l
4854 let locid = getloclist(0, {'id' : 0}).id
4855 lopen
4856 exe "normal \<C-W>\<CR>"
4857 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4858 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4859 new | only
4860
4861 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004862 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004863 lhelpgrep window
4864 let locid = getloclist(0, {'id' : 0}).id
4865 lwindow
4866 exe "normal j\<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
Bram Moolenaar406cd902020-02-18 21:54:41 +01004871 " Using :split or :vsplit from a quickfix window should behave like a :new
4872 " or a :vnew command
4873 copen
4874 split
4875 call assert_equal(3, winnr('$'))
4876 let l = getwininfo()
4877 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4878 close
4879 copen
4880 vsplit
4881 let l = getwininfo()
4882 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4883 new | only
4884
Bram Moolenaarb2443732018-11-11 22:50:27 +01004885 call delete('Xtestfile1')
4886 call delete('Xtestfile2')
4887endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004888
4889" Test for parsing entries using visual screen column
4890func Test_viscol()
4891 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004892 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004893 edit Xfile1
4894
4895 " Use byte offset for column number
4896 set efm&
4897 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4898 call assert_equal([5, 8], [col('.'), virtcol('.')])
4899 cnext
4900 call assert_equal([9, 12], [col('.'), virtcol('.')])
4901 cnext
4902 call assert_equal([14, 20], [col('.'), virtcol('.')])
4903
4904 " Use screen column offset for column number
4905 set efm=%f:%l:%v:%m
4906 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4907 call assert_equal([5, 8], [col('.'), virtcol('.')])
4908 cnext
4909 call assert_equal([9, 12], [col('.'), virtcol('.')])
4910 cnext
4911 call assert_equal([14, 20], [col('.'), virtcol('.')])
4912 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4913 call assert_equal([5, 8], [col('.'), virtcol('.')])
4914 cnext
4915 call assert_equal([10, 16], [col('.'), virtcol('.')])
4916 cnext
4917 call assert_equal([14, 20], [col('.'), virtcol('.')])
4918
4919 enew
4920 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4921
4922 " Use byte offset for column number
4923 set efm&
4924 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4925 call assert_equal([8, 10], [col('.'), virtcol('.')])
4926 cnext
4927 call assert_equal([11, 17], [col('.'), virtcol('.')])
4928 cnext
4929 call assert_equal([16, 25], [col('.'), virtcol('.')])
4930
4931 " Use screen column offset for column number
4932 set efm=%f:%l:%v:%m
4933 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4934 call assert_equal([8, 10], [col('.'), virtcol('.')])
4935 cnext
4936 call assert_equal([11, 17], [col('.'), virtcol('.')])
4937 cnext
4938 call assert_equal([16, 25], [col('.'), virtcol('.')])
4939
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004940 " Use screen column number with a multi-line error message
4941 enew
4942 call writefile(["à test"], 'Xfile1')
4943 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4944 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4945 call assert_equal('Xfile1', @%)
4946 call assert_equal([0, 1, 4, 0], getpos('.'))
4947
4948 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4949 " does not break this
4950 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4951 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4952 call assert_equal('Xfile1', @%)
4953 call assert_equal([0, 1, 3, 0], getpos('.'))
4954
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004955 enew | only
4956 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004957endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004958
4959" Test for the quickfix window buffer
4960func Xqfbuf_test(cchar)
4961 call s:setup_commands(a:cchar)
4962
4963 " Quickfix buffer should be reused across closing and opening a quickfix
4964 " window
4965 Xexpr "F1:10:Line10"
4966 Xopen
4967 let qfbnum = bufnr('')
4968 Xclose
4969 " Even after the quickfix window is closed, the buffer should be loaded
4970 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004971 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004972 Xopen
4973 " Buffer should be reused when opening the window again
4974 call assert_equal(qfbnum, bufnr(''))
4975 Xclose
4976
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004977 " When quickfix buffer is wiped out, getqflist() should return 0
4978 %bw!
4979 Xexpr ""
4980 Xopen
4981 bw!
4982 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4983
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004984 if a:cchar == 'l'
4985 %bwipe
4986 " For a location list, when both the file window and the location list
4987 " window for the list are closed, then the buffer should be freed.
4988 new | only
4989 lexpr "F1:10:Line10"
4990 let wid = win_getid()
4991 lopen
4992 let qfbnum = bufnr('')
4993 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4994 close
4995 " When the location list window is closed, the buffer name should not
4996 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004997 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004998 call assert_true(bufloaded(qfbnum))
4999
Bram Moolenaard82a81c2019-03-02 07:57:18 +01005000 " After deleting a location list buffer using ":bdelete", opening the
5001 " location list window should mark the buffer as a location list buffer.
5002 exe "bdelete " . qfbnum
5003 lopen
5004 call assert_equal("quickfix", &buftype)
5005 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5006 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5007 call assert_false(&swapfile)
5008 lclose
5009
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005010 " When the location list is cleared for the window, the buffer should be
5011 " removed
5012 call setloclist(0, [], 'f')
5013 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005014 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005015
5016 " When the location list is freed with the location list window open, the
5017 " location list buffer should not be lost. It should be reused when the
5018 " location list is again populated.
5019 lexpr "F1:10:Line10"
5020 lopen
5021 let wid = win_getid()
5022 let qfbnum = bufnr('')
5023 wincmd p
5024 call setloclist(0, [], 'f')
5025 lexpr "F1:10:Line10"
5026 lopen
5027 call assert_equal(wid, win_getid())
5028 call assert_equal(qfbnum, bufnr(''))
5029 lclose
5030
5031 " When the window with the location list is closed, the buffer should be
5032 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005033 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005034 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005035 endif
5036endfunc
5037
5038func Test_qfbuf()
5039 call Xqfbuf_test('c')
5040 call Xqfbuf_test('l')
5041endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005042
5043" If there is an autocmd to use only one window, then opening the location
5044" list window used to crash Vim.
5045func Test_winonly_autocmd()
5046 call s:create_test_file('Xtest1')
5047 " Autocmd to show only one Vim window at a time
5048 autocmd WinEnter * only
5049 new
5050 " Load the location list
5051 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5052 let loclistid = getloclist(0, {'id' : 0}).id
5053 " Open the location list window. Only this window will be shown and the file
5054 " window is closed.
5055 lopen
5056 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5057 " Jump to an entry in the location list and make sure that the cursor is
5058 " positioned correctly.
5059 ll 3
5060 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005061 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005062 call assert_equal(15, line('.'))
5063 " Cleanup
5064 autocmd! WinEnter
5065 new | only
5066 call delete('Xtest1')
5067endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005068
5069" Test to make sure that an empty quickfix buffer is not reused for loading
5070" a normal buffer.
5071func Test_empty_qfbuf()
5072 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005073 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005074 call setqflist([], 'f')
5075 copen | only
5076 let qfbuf = bufnr('')
5077 edit Xfile1
5078 call assert_notequal(qfbuf, bufnr(''))
5079 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005080endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005081
5082" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005083" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005084func Xtest_below(cchar)
5085 call s:setup_commands(a:cchar)
5086
5087 " No quickfix/location list
5088 call assert_fails('Xbelow', 'E42:')
5089 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005090 call assert_fails('Xbefore', 'E42:')
5091 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005092
5093 " Empty quickfix/location list
5094 call g:Xsetlist([])
5095 call assert_fails('Xbelow', 'E42:')
5096 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005097 call assert_fails('Xbefore', 'E42:')
5098 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005099
5100 call s:create_test_file('X1')
5101 call s:create_test_file('X2')
5102 call s:create_test_file('X3')
5103 call s:create_test_file('X4')
5104
5105 " Invalid entries
5106 edit X1
5107 call g:Xsetlist(["E1", "E2"])
5108 call assert_fails('Xbelow', 'E42:')
5109 call assert_fails('Xabove', 'E42:')
5110 call assert_fails('3Xbelow', 'E42:')
5111 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005112 call assert_fails('Xbefore', 'E42:')
5113 call assert_fails('Xafter', 'E42:')
5114 call assert_fails('3Xbefore', 'E42:')
5115 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005116
5117 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005118 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 +02005119 edit +7 X2
5120 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005121 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005122 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005123 normal 7G
5124 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005125 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005126 call assert_fails('Xbefore', 'E553:')
5127
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005128 normal 2j
5129 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005130 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005131 normal 7G
5132 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005133 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005134
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005135 " Last error in this file
5136 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005137 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005138 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005139 normal gg
5140 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005141 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005142 call assert_fails('Xafter', 'E553:')
5143
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005144 " First error in this file
5145 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005146 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005147 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005148 normal G
5149 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005150 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005151 call assert_fails('Xbefore', 'E553:')
5152
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005153 normal gg
5154 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005155 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005156 normal gg
5157 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005158 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005159
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005160 normal G
5161 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005162 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005163 normal G
5164 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005165 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005166
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005167 edit X4
5168 call assert_fails('Xabove', 'E42:')
5169 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005170 call assert_fails('Xbefore', 'E42:')
5171 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005172 if a:cchar == 'l'
5173 " If a buffer has location list entries from some other window but not
5174 " from the current window, then the commands should fail.
5175 edit X1 | split | call setloclist(0, [], 'f')
5176 call assert_fails('Xabove', 'E776:')
5177 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005178 call assert_fails('Xbefore', 'E776:')
5179 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005180 close
5181 endif
5182
5183 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005184 let lines =<< trim END
5185 X1:5:L5
5186 X2:5:1:L5_1
5187 X2:5:2:L5_2
5188 X2:5:3:L5_3
5189 X2:10:1:L10_1
5190 X2:10:2:L10_2
5191 X2:10:3:L10_3
5192 X2:15:1:L15_1
5193 X2:15:2:L15_2
5194 X2:15:3:L15_3
5195 X3:3:L3
5196 END
5197 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005198 edit +1 X2
5199 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005200 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005201 normal 1G
5202 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005203 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005204
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005205 normal gg
5206 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005207 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005208 normal gg
5209 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005210 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005211
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005212 normal G
5213 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005214 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005215 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005216 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005217 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005218
5219 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005220 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005221 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005222 normal G
5223 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005224 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005225
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005226 normal 10G
5227 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005228 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005229 normal 10G$
5230 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005231 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005232
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005233 normal 10G
5234 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005235 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005236 normal 9G
5237 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005238 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005239
5240 " Invalid range
5241 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005242 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005243 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005244 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005245 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005246 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005247 endif
5248
5249 call delete('X1')
5250 call delete('X2')
5251 call delete('X3')
5252 call delete('X4')
5253endfunc
5254
5255func Test_cbelow()
5256 call Xtest_below('c')
5257 call Xtest_below('l')
5258endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005259
5260func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005261 let commands =<< trim END
5262 cNext
5263 cNfile
5264 cabove
5265 cbelow
5266 cfirst
5267 clast
5268 cnewer
5269 cnext
5270 cnfile
5271 colder
5272 cprevious
5273 crewind
5274 lNext
5275 lNfile
5276 labove
5277 lbelow
5278 lfirst
5279 llast
5280 lnewer
5281 lnext
5282 lnfile
5283 lolder
5284 lprevious
5285 lrewind
5286 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005287 for cmd in commands
5288 call assert_fails('-1' .. cmd, 'E16:')
5289 call assert_fails('.' .. cmd, 'E16:')
5290 call assert_fails('%' .. cmd, 'E16:')
5291 call assert_fails('$' .. cmd, 'E16:')
5292 endfor
5293endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005294
5295" Test for aborting quickfix commands using QuickFixCmdPre
5296func Xtest_qfcmd_abort(cchar)
5297 call s:setup_commands(a:cchar)
5298
5299 call g:Xsetlist([], 'f')
5300
5301 " cexpr/lexpr
5302 let e = ''
5303 try
5304 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5305 catch /.*/
5306 let e = v:exception
5307 endtry
5308 call assert_equal('AbortCmd', e)
5309 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5310
5311 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005312 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005313 let e = ''
5314 try
5315 Xfile Xfile1
5316 catch /.*/
5317 let e = v:exception
5318 endtry
5319 call assert_equal('AbortCmd', e)
5320 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005321
5322 " cgetbuffer/lgetbuffer
5323 enew!
5324 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5325 let e = ''
5326 try
5327 Xgetbuffer
5328 catch /.*/
5329 let e = v:exception
5330 endtry
5331 call assert_equal('AbortCmd', e)
5332 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5333 enew!
5334
5335 " vimgrep/lvimgrep
5336 let e = ''
5337 try
5338 Xvimgrep /func/ test_quickfix.vim
5339 catch /.*/
5340 let e = v:exception
5341 endtry
5342 call assert_equal('AbortCmd', e)
5343 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5344
5345 " helpgrep/lhelpgrep
5346 let e = ''
5347 try
5348 Xhelpgrep quickfix
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 " grep/lgrep
5356 if has('unix')
5357 let e = ''
5358 try
5359 silent Xgrep func test_quickfix.vim
5360 catch /.*/
5361 let e = v:exception
5362 endtry
5363 call assert_equal('AbortCmd', e)
5364 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5365 endif
5366endfunc
5367
5368func Test_qfcmd_abort()
5369 augroup QF_Test
5370 au!
5371 autocmd QuickFixCmdPre * throw "AbortCmd"
5372 augroup END
5373
5374 call Xtest_qfcmd_abort('c')
5375 call Xtest_qfcmd_abort('l')
5376
5377 augroup QF_Test
5378 au!
5379 augroup END
5380endfunc
5381
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005382" Test for using a file in one of the parent directories.
5383func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005384 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005385 let save_cwd = getcwd()
5386 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5387 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5388 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5389 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5390
5391 let lines = "Entering dir Xtestdir\n" .
5392 \ "Entering dir a\n" .
5393 \ "Entering dir b\n" .
5394 \ "Xfile2:2:X2_L2\n" .
5395 \ "Leaving dir a\n" .
5396 \ "Xfile1:2:X1_L2\n" .
5397 \ "Xfile3:1:X3_L1\n" .
5398 \ "Entering dir c\n" .
5399 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005400 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005401 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005402 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005403 call assert_equal(11, getqflist({'size' : 0}).size)
5404 call assert_equal(4, getqflist({'idx' : 0}).idx)
5405 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005406 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005407 cnext
5408 call assert_equal(6, getqflist({'idx' : 0}).idx)
5409 call assert_equal('X1_L2', getline('.'))
5410 cnext
5411 call assert_equal(7, getqflist({'idx' : 0}).idx)
5412 call assert_equal(1, line('$'))
5413 call assert_equal('', getline(1))
5414 cnext
5415 call assert_equal(9, getqflist({'idx' : 0}).idx)
5416 call assert_equal(1, line('$'))
5417 call assert_equal('', getline(1))
5418
5419 set efm&
5420 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005421endfunc
5422
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005423" Test for :cquit
5424func Test_cquit()
5425 " Exit Vim with a non-zero value
5426 if RunVim([], ["cquit 7"], '')
5427 call assert_equal(7, v:shell_error)
5428 endif
5429
5430 if RunVim([], ["50cquit"], '')
5431 call assert_equal(50, v:shell_error)
5432 endif
5433
5434 " Exit Vim with default value
5435 if RunVim([], ["cquit"], '')
5436 call assert_equal(1, v:shell_error)
5437 endif
5438
5439 " Exit Vim with zero value
5440 if RunVim([], ["cquit 0"], '')
5441 call assert_equal(0, v:shell_error)
5442 endif
5443
5444 " Exit Vim with negative value
5445 call assert_fails('-3cquit', 'E16:')
5446endfunc
5447
Bram Moolenaar858ba062020-05-31 23:11:59 +02005448" Test for getting a specific item from a quickfix list
5449func Xtest_getqflist_by_idx(cchar)
5450 call s:setup_commands(a:cchar)
5451 " Empty list
5452 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5453 Xexpr ['F1:10:L10', 'F1:20:L20']
5454 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5455 call assert_equal(bufnr('F1'), l[0].bufnr)
5456 call assert_equal(20, l[0].lnum)
5457 call assert_equal('L20', l[0].text)
5458 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5459 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005460 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005461 %bwipe!
5462endfunc
5463
5464func Test_getqflist_by_idx()
5465 call Xtest_getqflist_by_idx('c')
5466 call Xtest_getqflist_by_idx('l')
5467endfunc
5468
5469" Test for the 'quickfixtextfunc' setting
5470func Tqfexpr(info)
5471 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005472 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005473 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005474 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005475 endif
5476
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005477 let l = []
5478 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5479 let e = qfl[idx]
5480 let s = ''
5481 if e.bufnr != 0
5482 let bname = bufname(e.bufnr)
5483 let s ..= fnamemodify(bname, ':.')
5484 endif
5485 let s ..= '-'
5486 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5487 let s ..= e.text
5488 call add(l, s)
5489 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005490
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005491 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005492endfunc
5493
5494func Xtest_qftextfunc(cchar)
5495 call s:setup_commands(a:cchar)
5496
5497 set efm=%f:%l:%c:%m
5498 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005499 call assert_equal('Tqfexpr', &quickfixtextfunc)
5500 call assert_equal('',
5501 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005502 call g:Xsetlist([
5503 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5504 \ 'end_col': 7, 'text': 'green'},
5505 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5506 \ 'end_col': 8, 'text': 'blue'},
5507 \ ])
5508
Bram Moolenaar858ba062020-05-31 23:11:59 +02005509 Xwindow
5510 call assert_equal('F1-L10C2-green', getline(1))
5511 call assert_equal('F1-L20C4-blue', getline(2))
5512 Xclose
5513 set quickfixtextfunc&vim
5514 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005515 call assert_equal('F1|10 col 2-7| green', getline(1))
5516 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005517 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005518
5519 set efm=%f:%l:%c:%m
5520 set quickfixtextfunc=Tqfexpr
5521 " Update the list with only the cwindow
5522 Xwindow
5523 only
5524 call g:Xsetlist([
5525 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5526 \ 'end_col': 7, 'text': 'red'}
5527 \ ])
5528 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5529 new
5530 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005531 set efm&
5532 set quickfixtextfunc&
5533
5534 " Test for per list 'quickfixtextfunc' setting
5535 func PerQfText(info)
5536 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005537 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005538 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005539 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005540 endif
5541 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005542 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005543 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005544 let l = []
5545 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5546 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5547 endfor
5548 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005549 endfunc
5550 set quickfixtextfunc=Tqfexpr
5551 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5552 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5553 Xwindow
5554 call assert_equal('Line 10, Col 2', getline(1))
5555 call assert_equal('Line 20, Col 4', getline(2))
5556 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005557 call assert_equal(function('PerQfText'),
5558 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005559 " Add entries to the list when the quickfix buffer is hidden
5560 Xaddexpr ['F1:30:6:red']
5561 Xwindow
5562 call assert_equal('Line 30, Col 6', getline(3))
5563 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005564 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005565 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005566 set quickfixtextfunc&
5567 delfunc PerQfText
5568
5569 " Non-existing function
5570 set quickfixtextfunc=Tabc
5571 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5572 call assert_fails("Xwindow", 'E117:')
5573 Xclose
5574 set quickfixtextfunc&
5575
5576 " set option to a non-function
5577 set quickfixtextfunc=[10,\ 20]
5578 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5579 call assert_fails("Xwindow", 'E117:')
5580 Xclose
5581 set quickfixtextfunc&
5582
5583 " set option to a function with different set of arguments
5584 func Xqftext(a, b, c)
5585 return a:a .. a:b .. a:c
5586 endfunc
5587 set quickfixtextfunc=Xqftext
5588 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5589 call assert_fails("Xwindow", 'E119:')
5590 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005591
5592 " set option to a function that returns a list with non-strings
5593 func Xqftext2(d)
5594 return ['one', [], 'two']
5595 endfunc
5596 set quickfixtextfunc=Xqftext2
5597 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5598 \ 'E730:')
5599 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005600 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5601 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005602 Xclose
5603
Bram Moolenaar858ba062020-05-31 23:11:59 +02005604 set quickfixtextfunc&
5605 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005606 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005607
5608 " set the global option to a lambda function
5609 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5610 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5611 Xwindow
5612 call assert_equal(['green', 'blue'], getline(1, '$'))
5613 Xclose
5614 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)
5615 set quickfixtextfunc&
5616
5617 " use a lambda function that returns an empty list
5618 set quickfixtextfunc={d\ ->\ []}
5619 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5620 Xwindow
5621 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5622 \ getline(1, '$'))
5623 Xclose
5624 set quickfixtextfunc&
5625
5626 " use a lambda function that returns a list with empty strings
5627 set quickfixtextfunc={d\ ->\ ['',\ '']}
5628 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5629 Xwindow
5630 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5631 \ getline(1, '$'))
5632 Xclose
5633 set quickfixtextfunc&
5634
5635 " set the per-quickfix list text function to a lambda function
5636 call g:Xsetlist([], ' ',
5637 \ {'quickfixtextfunc' :
5638 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5639 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5640 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5641 Xwindow
5642 call assert_equal('Line 10, Col 2', getline(1))
5643 call assert_equal('Line 20, Col 4', getline(2))
5644 Xclose
5645 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5646 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005647endfunc
5648
5649func Test_qftextfunc()
5650 call Xtest_qftextfunc('c')
5651 call Xtest_qftextfunc('l')
5652endfunc
5653
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005654func Test_qftextfunc_callback()
5655 let lines =<< trim END
5656 set efm=%f:%l:%c:%m
5657
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005658 #" Test for using a function name
5659 LET &qftf = 'g:Tqfexpr'
5660 cexpr "F0:0:0:L0"
5661 copen
5662 call assert_equal('F0-L0C0-L0', getline(1))
5663 cclose
5664
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005665 #" Test for using a function()
5666 set qftf=function('g:Tqfexpr')
5667 cexpr "F1:1:1:L1"
5668 copen
5669 call assert_equal('F1-L1C1-L1', getline(1))
5670 cclose
5671
5672 #" Using a funcref variable to set 'quickfixtextfunc'
5673 VAR Fn = function('g:Tqfexpr')
5674 LET &qftf = Fn
5675 cexpr "F2:2:2:L2"
5676 copen
5677 call assert_equal('F2-L2C2-L2', getline(1))
5678 cclose
5679
5680 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5681 LET Fn = function('g:Tqfexpr')
5682 LET &qftf = string(Fn)
5683 cexpr "F3:3:3:L3"
5684 copen
5685 call assert_equal('F3-L3C3-L3', getline(1))
5686 cclose
5687
5688 #" Test for using a funcref()
5689 set qftf=funcref('g:Tqfexpr')
5690 cexpr "F4:4:4:L4"
5691 copen
5692 call assert_equal('F4-L4C4-L4', getline(1))
5693 cclose
5694
5695 #" Using a funcref variable to set 'quickfixtextfunc'
5696 LET Fn = funcref('g:Tqfexpr')
5697 LET &qftf = Fn
5698 cexpr "F5:5:5:L5"
5699 copen
5700 call assert_equal('F5-L5C5-L5', getline(1))
5701 cclose
5702
5703 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5704 LET Fn = funcref('g:Tqfexpr')
5705 LET &qftf = string(Fn)
5706 cexpr "F5:5:5:L5"
5707 copen
5708 call assert_equal('F5-L5C5-L5', getline(1))
5709 cclose
5710
5711 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005712 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005713 LET optval = substitute(optval, ' ', '\\ ', 'g')
5714 exe "set qftf=" .. optval
5715 cexpr "F6:6:6:L6"
5716 copen
5717 call assert_equal('F6-L6C6-L6', getline(1))
5718 cclose
5719
5720 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005721 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005722 cexpr "F7:7:7:L7"
5723 copen
5724 call assert_equal('F7-L7C7-L7', getline(1))
5725 cclose
5726
5727 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005728 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005729 cexpr "F8:8:8:L8"
5730 copen
5731 call assert_equal('F8-L8C8-L8', getline(1))
5732 cclose
5733
5734 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005735 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005736 LET &qftf = Lambda
5737 cexpr "F9:9:9:L9"
5738 copen
5739 call assert_equal('F9-L9C9-L9', getline(1))
5740 cclose
5741
5742 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005743 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005744 LET &qftf = string(Lambda)
5745 cexpr "F9:9:9:L9"
5746 copen
5747 call assert_equal('F9-L9C9-L9', getline(1))
5748 cclose
5749 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005750 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005751
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005752 " Test for using a script-local function name
5753 func s:TqfFunc2(info)
5754 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5755 return ''
5756 endfunc
5757 let g:TqfFunc2Args = []
5758 set quickfixtextfunc=s:TqfFunc2
5759 cexpr "F10:10:10:L10"
5760 cclose
5761 call assert_equal([1, 1], g:TqfFunc2Args)
5762
5763 let &quickfixtextfunc = 's:TqfFunc2'
5764 cexpr "F11:11:11:L11"
5765 cclose
5766 call assert_equal([1, 1], g:TqfFunc2Args)
5767 delfunc s:TqfFunc2
5768
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005769 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5770 func SetQftfFunc()
5771 let params = {'qftf': function('g:DictQftfFunc')}
5772 let &quickfixtextfunc = params.qftf
5773 endfunc
5774 func g:DictQftfFunc(_) dict
5775 endfunc
5776 call SetQftfFunc()
5777 new
5778 call SetQftfFunc()
5779 bw
5780 call test_garbagecollect_now()
5781 new
5782 set qftf=
5783 wincmd w
5784 set qftf=
5785 :%bw!
5786
5787 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5788 " to cause a crash.
5789 let &qftf = ''
5790 func SetLocalQftfFunc()
5791 let params = {'qftf': function('g:DictQftfFunc')}
5792 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5793 endfunc
5794 call SetLocalQftfFunc()
5795 call test_garbagecollect_now()
5796 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5797 delfunc g:DictQftfFunc
5798 delfunc SetQftfFunc
5799 delfunc SetLocalQftfFunc
5800 set efm&
5801endfunc
5802
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005803" Test for updating a location list for some other window and check that
5804" 'qftextfunc' uses the correct location list.
5805func Test_qftextfunc_other_loclist()
5806 %bw!
5807 call setloclist(0, [], 'f')
5808
5809 " create a window and a location list for it and open the location list
5810 " window
5811 lexpr ['F1:10:12:one', 'F1:20:14:two']
5812 let w1_id = win_getid()
5813 call setloclist(0, [], ' ',
5814 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5815 \ 'quickfixtextfunc':
5816 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5817 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5818 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5819 lwindow
5820 let w2_id = win_getid()
5821
5822 " create another window and a location list for it and open the location
5823 " list window
5824 topleft new
5825 let w3_id = win_getid()
5826 call setloclist(0, [], ' ',
5827 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5828 \ 'quickfixtextfunc':
5829 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5830 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5831 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5832 lwindow
5833 let w4_id = win_getid()
5834
5835 topleft new
5836 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5837 let w5_id = win_getid()
5838
5839 " change the location list for some other window
5840 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5841 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5842 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5843 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5844 \ getbufline(winbufnr(w2_id), 1, '$'))
5845 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5846 \ getbufline(winbufnr(w4_id), 1, '$'))
5847 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5848 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5849 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5850 \ getbufline(winbufnr(w2_id), 1, '$'))
5851 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5852 \ getbufline(winbufnr(w4_id), 1, '$'))
5853
5854 call win_gotoid(w5_id)
5855 lwindow
5856 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5857 \ getline(1, '$'))
5858 %bw!
5859endfunc
5860
Bram Moolenaarec98e932020-06-08 19:35:59 +02005861" Running :lhelpgrep command more than once in a help window, doesn't jump to
5862" the help topic
5863func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005864 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005865 call writefile(['window'], 'Xtestdir/doc/a.txt')
5866 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5867 let save_rtp = &rtp
5868 let &rtp = 'Xtestdir'
5869 lhelpgrep window
5870 lhelpgrep buffer
5871 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5872 lhelpgrep window
5873 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5874 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005875 new | only!
5876endfunc
5877
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005878" Test for the crash fixed by 7.3.715
5879func Test_setloclist_crash()
5880 %bw!
5881 let g:BufNum = bufnr()
5882 augroup QF_Test
5883 au!
5884 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5885 augroup END
5886
5887 try
5888 lvimgrep /.*/ *.mak
5889 catch /E926:/
5890 endtry
5891 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5892 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5893
5894 augroup QF_Test
5895 au!
5896 augroup END
5897 unlet g:BufNum
5898 %bw!
5899endfunc
5900
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005901" Test for adding an invalid entry with the quickfix window open and making
5902" sure that the window contents are not changed
5903func Test_add_invalid_entry_with_qf_window()
5904 call setqflist([], 'f')
5905 cexpr "Xfile1:10:aa"
5906 copen
5907 call setqflist(['bb'], 'a')
5908 call assert_equal(1, line('$'))
5909 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005910 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())
5911
5912 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5913 call assert_equal(1 , line('$'))
5914 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5915 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())
5916
5917 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')
5918 call assert_equal(1 , line('$'))
5919 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5920 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 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , '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': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5926
5927 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')
5928 call assert_equal(1 , line('$'))
5929 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5930 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())
5931
5932 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')
5933 call assert_equal(1 , line('$'))
5934 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5935 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())
5936
5937 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')
5938 call assert_equal(1 , line('$'))
5939 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5940 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())
5941
5942 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')
5943 call assert_equal(1 , line('$'))
5944 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5945 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 +01005946 cclose
5947endfunc
5948
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005949" Test for very weird problem: autocommand causes a failure, resulting opening
5950" the quickfix window to fail. This still splits the window, but otherwise
5951" should not mess up buffers.
5952func Test_quickfix_window_fails_to_open()
5953 CheckScreendump
5954
5955 let lines =<< trim END
5956 anything
5957 try
5958 anything
5959 endtry
5960 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005961 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005962
5963 let lines =<< trim END
5964 split XquickfixFails
5965 silent vimgrep anything %
5966 normal o
5967 au BufLeave * ++once source XquickfixFails
5968 " This will trigger the autocommand, which causes an error, what follows
5969 " is aborted but the window was already split.
5970 silent! cwindow
5971 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005972 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005973 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5974 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5975
5976 " clean up
5977 call term_sendkeys(buf, ":bwipe!\<CR>")
5978 call term_wait(buf)
5979 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005980endfunc
5981
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005982" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005983" is changed.
5984func Xqfbuf_update(cchar)
5985 call s:setup_commands(a:cchar)
5986
5987 Xexpr "F1:1:line1"
5988 Xopen
5989 call assert_equal(['F1|1| line1'], getline(1, '$'))
5990 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5991
5992 " Test setqflist() using the 'lines' key in 'what'
5993 " add a new entry
5994 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5995 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5996 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5997 " replace all the entries with a single entry
5998 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5999 call assert_equal(['F3|3| line3'], getline(1, '$'))
6000 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6001 " remove all the entries
6002 call g:Xsetlist([], 'r', {'lines' : []})
6003 call assert_equal([''], getline(1, '$'))
6004 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6005 " add a new list
6006 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6007 call assert_equal(['F4|4| line4'], getline(1, '$'))
6008 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6009
6010 " Test setqflist() using the 'items' key in 'what'
6011 " add a new entry
6012 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6013 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6014 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6015 " replace all the entries with a single entry
6016 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6017 call assert_equal(['F6|6| line6'], getline(1, '$'))
6018 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6019 " remove all the entries
6020 call g:Xsetlist([], 'r', {'items' : []})
6021 call assert_equal([''], getline(1, '$'))
6022 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6023 " add a new list
6024 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6025 call assert_equal(['F7|7| line7'], getline(1, '$'))
6026 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6027
6028 call g:Xsetlist([], ' ', {})
6029 call assert_equal([''], getline(1, '$'))
6030 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6031
6032 Xclose
6033endfunc
6034
6035func Test_qfbuf_update()
6036 call Xqfbuf_update('c')
6037 call Xqfbuf_update('l')
6038endfunc
6039
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006040func Test_vimgrep_noswapfile()
6041 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006042 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006043 vimgrep two Xgreppie
6044 call assert_equal('two', getline('.'))
6045
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006046 set swapfile
6047endfunc
6048
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006049" Test for the :vimgrep 'f' flag (fuzzy match)
6050func Xvimgrep_fuzzy_match(cchar)
6051 call s:setup_commands(a:cchar)
6052
6053 Xvimgrep /three one/f Xfile*
6054 let l = g:Xgetlist()
6055 call assert_equal(2, len(l))
6056 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6057 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6058 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6059 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6060
6061 Xvimgrep /the/f Xfile*
6062 let l = g:Xgetlist()
6063 call assert_equal(3, len(l))
6064 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6065 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6066 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6067 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6068 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6069 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6070
6071 Xvimgrep /aaa/fg Xfile*
6072 let l = g:Xgetlist()
6073 call assert_equal(4, len(l))
6074 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6075 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6076 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6077 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6078 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6079 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6080 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6081 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6082
6083 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6084endfunc
6085
6086func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006087 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6088 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006089 call Xvimgrep_fuzzy_match('c')
6090 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006091endfunc
6092
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006093func Test_locationlist_open_in_newtab()
6094 call s:create_test_file('Xqftestfile1')
6095 call s:create_test_file('Xqftestfile2')
6096 call s:create_test_file('Xqftestfile3')
6097
6098 %bwipe!
6099
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006100 let lines =<< trim END
6101 Xqftestfile1:5:Line5
6102 Xqftestfile2:10:Line10
6103 Xqftestfile3:16:Line16
6104 END
6105 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006106
6107 silent! llast
6108 call assert_equal(1, tabpagenr('$'))
6109 call assert_equal('Xqftestfile3', bufname())
6110
6111 set switchbuf=newtab
6112
6113 silent! lfirst
6114 call assert_equal(2, tabpagenr('$'))
6115 call assert_equal('Xqftestfile1', bufname())
6116
6117 silent! lnext
6118 call assert_equal(3, tabpagenr('$'))
6119 call assert_equal('Xqftestfile2', bufname())
6120
6121 call delete('Xqftestfile1')
6122 call delete('Xqftestfile2')
6123 call delete('Xqftestfile3')
6124 set switchbuf&vim
6125
6126 %bwipe!
6127endfunc
6128
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006129" Test for win_gettype() in quickfix and location list windows
6130func Test_win_gettype()
6131 copen
6132 call assert_equal("quickfix", win_gettype())
6133 let wid = win_getid()
6134 wincmd p
6135 call assert_equal("quickfix", win_gettype(wid))
6136 cclose
6137 lexpr ''
6138 lopen
6139 call assert_equal("loclist", win_gettype())
6140 let wid = win_getid()
6141 wincmd p
6142 call assert_equal("loclist", win_gettype(wid))
6143 lclose
6144endfunc
6145
Christian Brabandt0b226f62021-12-01 10:54:24 +00006146fun Test_vimgrep_nomatch()
6147 call XexprTests('c')
6148 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6149 copen
6150 if has("win32")
6151 call assert_fails('vimgrep foo *.zzz', 'E479:')
6152 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'}]
6153 else
6154 call assert_fails('vimgrep foo *.zzz', 'E480:')
6155 let expected = []
6156 endif
6157 call assert_equal(expected, getqflist())
6158 cclose
6159endfunc
6160
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006161" Test for opening the quickfix window in two tab pages and then closing one
6162" of the quickfix windows. This should not make the quickfix buffer unlisted.
6163" (github issue #9300).
6164func Test_two_qf_windows()
6165 cexpr "F1:1:line1"
6166 copen
6167 tabnew
6168 copen
6169 call assert_true(&buflisted)
6170 cclose
6171 tabfirst
6172 call assert_true(&buflisted)
6173 let bnum = bufnr()
6174 cclose
6175 " if all the quickfix windows are closed, then buffer should be unlisted.
6176 call assert_false(buflisted(bnum))
6177 %bw!
6178
6179 " Repeat the test for a location list
6180 lexpr "F2:2:line2"
6181 lopen
6182 let bnum = bufnr()
6183 tabnew
6184 exe "buffer" bnum
6185 tabfirst
6186 lclose
6187 tablast
6188 call assert_true(buflisted(bnum))
6189 tabclose
6190 lopen
6191 call assert_true(buflisted(bnum))
6192 lclose
6193 call assert_false(buflisted(bnum))
6194 %bw!
6195endfunc
6196
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006197" Weird sequence of commands that caused entering a wiped-out buffer
6198func Test_lopen_bwipe()
6199 func R()
6200 silent! tab lopen
6201 e x
6202 silent! lfile
6203 endfunc
6204
6205 cal R()
6206 cal R()
6207 cal R()
6208 bw!
6209 delfunc R
6210endfunc
6211
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006212" Another sequence of commands that caused all buffers to be wiped out
6213func Test_lopen_bwipe_all()
6214 let lines =<< trim END
6215 func R()
6216 silent! tab lopen
6217 e foo
6218 silent! lfile
6219 endfunc
6220 cal R()
6221 exe "norm \<C-W>\<C-V>0"
6222 cal R()
6223 bwipe
6224
6225 call writefile(['done'], 'Xresult')
6226 qall!
6227 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006228 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006229 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6230 call assert_equal(['done'], readfile('Xresult'))
6231 endif
6232
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006233 call delete('Xresult')
6234endfunc
6235
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006236" Test for calling setqflist() function recursively
6237func Test_recursive_setqflist()
6238 augroup QF_Test
6239 au!
6240 autocmd BufWinEnter quickfix call setqflist([], 'r')
6241 augroup END
6242
6243 copen
6244 call assert_fails("call setqflist([], 'a')", 'E952:')
6245
6246 augroup QF_Test
6247 au!
6248 augroup END
6249 %bw!
6250endfunc
6251
6252" Test for failure to create a new window when selecting a file from the
6253" quickfix window
6254func Test_cwindow_newwin_fails()
6255 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6256 cwindow
6257 only
6258 let qf_wid = win_getid()
6259 " create the maximum number of scratch windows
6260 let hor_win_count = (&lines - 1)/2
6261 let hor_split_count = hor_win_count - 1
6262 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6263 call win_gotoid(qf_wid)
6264 call assert_fails('exe "normal \<CR>"', 'E36:')
6265 %bw!
6266endfunc
6267
6268" Test for updating the location list when only the location list window is
6269" present and the corresponding file window is closed.
6270func Test_loclist_update_with_llwin_only()
6271 %bw!
6272 new
6273 wincmd w
6274 lexpr ["Xfile1:1:Line1"]
6275 lopen
6276 wincmd p
6277 close
6278 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6279 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6280 %bw!
6281endfunc
6282
6283" Test for getting the quickfix list after a buffer with an error is wiped out
6284func Test_getqflist_wiped_out_buffer()
6285 %bw!
6286 cexpr ["Xtest1:34:Wiped out"]
6287 let bnum = bufnr('Xtest1')
6288 call assert_equal(bnum, getqflist()[0].bufnr)
6289 bw Xtest1
6290 call assert_equal(0, getqflist()[0].bufnr)
6291 %bw!
6292endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006293
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006294" Test for the status message that is displayed when opening a new quickfix
6295" list
6296func Test_qflist_statusmsg()
6297 cexpr "1\n2"
6298 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6299 call assert_equal('(4 of 4): msg', v:statusmsg)
6300 call setqflist([], 'f')
6301 %bw!
6302
6303 " When creating a new quickfix list, if an autocmd changes the quickfix list
6304 " in the stack, then an error message should be displayed.
6305 augroup QF_Test
6306 au!
6307 au BufEnter test_quickfix.vim colder
6308 augroup END
6309 cexpr "1\n2"
6310 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6311 call setqflist([], 'f')
6312 augroup QF_Test
6313 au!
6314 augroup END
6315 %bw!
6316
6317 augroup QF_Test
6318 au!
6319 au BufEnter test_quickfix.vim caddexpr "4"
6320 augroup END
6321 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6322 call setqflist([], 'f')
6323 augroup QF_Test
6324 au!
6325 augroup END
6326 %bw!
6327endfunc
6328
Bram Moolenaard6c67622022-08-24 20:07:22 +01006329func Test_quickfixtextfunc_recursive()
6330 func s:QFTfunc(o)
6331 cgete '0'
6332 endfunc
6333 copen
6334 let &quickfixtextfunc = 's:QFTfunc'
6335 cex ""
6336
6337 let &quickfixtextfunc = ''
6338 cclose
6339endfunc
6340
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006341" Test for replacing the location list from an autocmd. This used to cause a
6342" read from freed memory.
6343func Test_loclist_replace_autocmd()
6344 %bw!
6345 call setloclist(0, [], 'f')
6346 let s:bufnr = bufnr()
6347 cal setloclist(0, [{'0': 0, '': ''}])
6348 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6349 lopen
6350 try
6351 exe "norm j\<CR>"
6352 catch
6353 endtry
6354 lnext
6355 %bw!
6356 call setloclist(0, [], 'f')
6357endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006358
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006359" Test for a very long error line and a very long information line
6360func Test_very_long_error_line()
6361 let msg = repeat('abcdefghijklmn', 146)
6362 let emsg = 'Xlonglines.c:1:' . msg
6363 call writefile([msg, emsg], 'Xerror', 'D')
6364 cfile Xerror
6365 cwindow
6366 call assert_equal($'|| {msg}', getline(1))
6367 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6368 cclose
6369
6370 let l = execute('clist!')->split("\n")
6371 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6372
6373 let l = execute('cc')->split("\n")
6374 call assert_equal([$'(2 of 2): {msg}'], l)
6375
6376 call setqflist([], 'f')
6377endfunc
6378
6379" In the quickfix window, spaces at the beginning of an informational line
6380" should not be removed but should be removed from an error line.
6381func Test_info_line_with_space()
6382 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6383 \ ' 20 | Afunc():', '', ' | ^']
6384 copen
6385 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6386 \ '|| 20 | Afunc():', '|| ',
6387 \ '|| | ^'], getline(1, '$'))
6388 cclose
6389
6390 let l = execute('clist!')->split("\n")
6391 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6392 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6393
6394 call setqflist([], 'f')
6395endfunc
6396
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006397func s:QfTf(_)
6398endfunc
6399
6400func Test_setqflist_cb_arg()
6401 " This was changing the callback name in the dictionary.
6402 let d = #{quickfixtextfunc: 's:QfTf'}
6403 call setqflist([], 'a', d)
6404 call assert_equal('s:QfTf', d.quickfixtextfunc)
6405
6406 call setqflist([], 'f')
6407endfunc
6408
zeertzjqa40c0bc2023-05-27 14:10:08 +01006409" Test that setqflist() should not prevent :stopinsert from working
6410func Test_setqflist_stopinsert()
6411 new
6412 call setqflist([], 'f')
6413 copen
6414 cclose
6415 func StopInsert()
6416 stopinsert
6417 call setqflist([{'text': 'foo'}])
6418 return ''
6419 endfunc
6420
6421 call setline(1, 'abc')
6422 call cursor(1, 1)
6423 call feedkeys("i\<C-R>=StopInsert()\<CR>$", 'tnix')
6424 call assert_equal('foo', getqflist()[0].text)
6425 call assert_equal([0, 1, 3, 0, v:maxcol], getcurpos())
6426 call assert_equal(['abc'], getline(1, '$'))
6427
6428 delfunc StopInsert
6429 call setqflist([], 'f')
6430 bwipe!
6431endfunc
Bram Moolenaard0fab102022-10-20 16:03:33 +01006432
Shane Harper5bf04282023-06-07 19:09:57 +01006433func Test_quickfix_buffer_contents()
6434 call setqflist([{'filename':'filename', 'pattern':'pattern', 'text':'text'}])
6435 copen
6436 call assert_equal(['filename|pattern| text'], getline(1, '$')) " The assert failed with Vim v9.0.0736; '| text' did not appear after the pattern.
6437 call setqflist([], 'f')
6438endfunc
6439
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006440" vim: shiftwidth=2 sts=2 expandtab