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