blob: 9e79864275c1ecce4a8a9d043aedbc7a1a3d5d40 [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()
3397 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3398 " 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 Moolenaar33aecb12020-11-14 17:25:51 +01003458func Test_vimgrep_with_textlock()
3459 new
3460
zeertzjqcfe45652022-05-27 17:26:55 +01003461 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003462 " Check that vimgrep without jumping can be executed.
3463 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3464 normal ax
3465 let qflist = getqflist()
3466 call assert_true(len(qflist) > 0)
3467 call assert_match('RunTheTest', qflist[0].text)
3468 call setqflist([], 'r')
3469 au! InsertCharPre
3470
3471 " Check that vimgrepadd without jumping can be executed.
3472 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3473 normal ax
3474 let qflist = getqflist()
3475 call assert_true(len(qflist) > 0)
3476 call assert_match('RunTheTest', qflist[0].text)
3477 call setqflist([], 'r')
3478 au! InsertCharPre
3479
3480 " Check that lvimgrep without jumping can be executed.
3481 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3482 normal ax
3483 let qflist = getloclist(0)
3484 call assert_true(len(qflist) > 0)
3485 call assert_match('RunTheTest', qflist[0].text)
3486 call setloclist(0, [], 'r')
3487 au! InsertCharPre
3488
3489 " Check that lvimgrepadd without jumping can be executed.
3490 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3491 normal ax
3492 let qflist = getloclist(0)
3493 call assert_true(len(qflist) > 0)
3494 call assert_match('RunTheTest', qflist[0].text)
3495 call setloclist(0, [], 'r')
3496 au! InsertCharPre
3497
3498 " trying to jump will give an error
3499 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3500 call assert_fails('normal ax', 'E565:')
3501 au! InsertCharPre
3502
3503 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3504 call assert_fails('normal ax', 'E565:')
3505 au! InsertCharPre
3506
3507 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3508 call assert_fails('normal ax', 'E565:')
3509 au! InsertCharPre
3510
3511 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3512 call assert_fails('normal ax', 'E565:')
3513 au! InsertCharPre
3514
3515 bwipe!
3516endfunc
3517
Bram Moolenaara8788f42017-07-19 17:06:20 +02003518" Tests for the quickfix buffer b:changedtick variable
3519func Xchangedtick_tests(cchar)
3520 call s:setup_commands(a:cchar)
3521
3522 new | only
3523
3524 Xexpr "" | Xexpr "" | Xexpr ""
3525
3526 Xopen
3527 Xolder
3528 Xolder
3529 Xaddexpr "F1:10:Line10"
3530 Xaddexpr "F2:20:Line20"
3531 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3532 call g:Xsetlist([], 'f')
3533 call assert_equal(8, getbufvar('%', 'changedtick'))
3534 Xclose
3535endfunc
3536
3537func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003538 call Xchangedtick_tests('c')
3539 call Xchangedtick_tests('l')
3540endfunc
3541
3542" Tests for parsing an expression using setqflist()
3543func Xsetexpr_tests(cchar)
3544 call s:setup_commands(a:cchar)
3545
3546 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003547 call g:Xsetlist([], ' ', {'lines' : t})
3548 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003549
3550 let l = g:Xgetlist()
3551 call assert_equal(3, len(l))
3552 call assert_equal(20, l[1].lnum)
3553 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003554 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003555 let l = g:Xgetlist()
3556 call assert_equal(1, len(l))
3557 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003558 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3559 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003560
3561 call g:Xsetlist([], 'f')
3562 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003563 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3564 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3565 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3566 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003567 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3568 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003569
3570 " Adding entries using a custom efm
3571 set efm&
3572 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3573 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3574 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3575 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3576 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3577 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3578 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3579 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003580endfunc
3581
3582func Test_setexpr()
3583 call Xsetexpr_tests('c')
3584 call Xsetexpr_tests('l')
3585endfunc
3586
3587" Tests for per quickfix/location list directory stack
3588func Xmultidirstack_tests(cchar)
3589 call s:setup_commands(a:cchar)
3590
3591 call g:Xsetlist([], 'f')
3592 Xexpr "" | Xexpr ""
3593
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003594 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3595 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3596 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3597 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003598
3599 let l1 = g:Xgetlist({'nr':1, 'items':1})
3600 let l2 = g:Xgetlist({'nr':2, 'items':1})
3601 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3602 call assert_equal(3, l1.items[1].lnum)
3603 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3604 call assert_equal(5, l2.items[1].lnum)
3605endfunc
3606
3607func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003608 call mkdir('Xone/a', 'pR')
3609 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003610 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3611 call writefile(lines, 'Xone/a/one.txt')
3612 call writefile(lines, 'Xtwo/a/two.txt')
3613 let save_efm = &efm
3614 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3615
3616 call Xmultidirstack_tests('c')
3617 call Xmultidirstack_tests('l')
3618
3619 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003620endfunc
3621
3622" Tests for per quickfix/location list file stack
3623func Xmultifilestack_tests(cchar)
3624 call s:setup_commands(a:cchar)
3625
3626 call g:Xsetlist([], 'f')
3627 Xexpr "" | Xexpr ""
3628
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003629 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3630 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3631 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3632 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003633
3634 let l1 = g:Xgetlist({'nr':1, 'items':1})
3635 let l2 = g:Xgetlist({'nr':2, 'items':1})
3636 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3637 call assert_equal(3, l1.items[1].lnum)
3638 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3639 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003640
3641 " Test for start of a new error line in the same line where a previous
3642 " error line ends with a file stack.
3643 let efm_val = 'Error\ l%l\ in\ %f,'
3644 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003645 let lines =<< trim END
3646 (one.txt
3647 Error l4 in one.txt
3648 ) (two.txt
3649 Error l6 in two.txt
3650 )
3651 Error l8 in one.txt
3652 END
3653 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003654 call assert_equal(3, len(l.items))
3655 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3656 call assert_equal(4, l.items[0].lnum)
3657 call assert_equal('one.txt', l.items[0].text)
3658 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3659 call assert_equal(6, l.items[1].lnum)
3660 call assert_equal('two.txt', l.items[1].text)
3661 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3662 call assert_equal(8, l.items[2].lnum)
3663 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003664endfunc
3665
3666func Test_multifilestack()
3667 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003668 call writefile(lines, 'one.txt', 'D')
3669 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003670 let save_efm = &efm
3671 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3672
3673 call Xmultifilestack_tests('c')
3674 call Xmultifilestack_tests('l')
3675
3676 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003677endfunc
3678
3679" Tests for per buffer 'efm' setting
3680func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003681 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3682 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003683 set efm=%f#%l#%m
3684 new | only
3685 new
3686 setlocal efm=%f-%l-%m
3687 cfile one.txt
3688 wincmd w
3689 caddfile two.txt
3690
3691 let l = getqflist()
3692 call assert_equal(10, l[0].lnum)
3693 call assert_equal('Line20', l[1].text)
3694
3695 set efm&
3696 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003697endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003698
3699" Open multiple help windows using ":lhelpgrep
3700" This test used to crash Vim
3701func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003702 new | only
3703 lhelpgrep window
3704 lopen
3705 e#
3706 lhelpgrep buffer
3707 call assert_equal(3, winnr('$'))
3708 call assert_true(len(getloclist(1)) != 0)
3709 call assert_true(len(getloclist(2)) != 0)
3710 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003711endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003712
3713" Tests for adding new quickfix lists using setqflist()
3714func XaddQf_tests(cchar)
3715 call s:setup_commands(a:cchar)
3716
3717 " Create a new list using ' ' for action
3718 call g:Xsetlist([], 'f')
3719 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3720 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3721 call assert_equal(1, l.nr)
3722 call assert_equal('Test1', l.title)
3723
3724 " Create a new list using ' ' for action and '$' for 'nr'
3725 call g:Xsetlist([], 'f')
3726 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3727 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3728 call assert_equal(1, l.nr)
3729 call assert_equal('Test2', l.title)
3730
3731 " Create a new list using 'a' for action
3732 call g:Xsetlist([], 'f')
3733 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3734 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3735 call assert_equal(1, l.nr)
3736 call assert_equal('Test3', l.title)
3737
3738 " Create a new list using 'a' for action and '$' for 'nr'
3739 call g:Xsetlist([], 'f')
3740 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3741 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3742 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3743 call assert_equal(1, l.nr)
3744 call assert_equal('Test4', l.title)
3745
3746 " Adding a quickfix list should remove all the lists following the current
3747 " list.
3748 Xexpr "" | Xexpr "" | Xexpr ""
3749 silent! 10Xolder
3750 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3751 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3752 call assert_equal(2, l.nr)
3753 call assert_equal('Test5', l.title)
3754
3755 " Add a quickfix list using '$' as the list number.
3756 let lastqf = g:Xgetlist({'nr':'$'}).nr
3757 silent! 99Xolder
3758 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3759 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3760 call assert_equal(lastqf + 1, l.nr)
3761 call assert_equal('Test6', l.title)
3762
3763 " Add a quickfix list using 'nr' set to one more than the quickfix
3764 " list size.
3765 let lastqf = g:Xgetlist({'nr':'$'}).nr
3766 silent! 99Xolder
3767 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3768 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3769 call assert_equal(lastqf + 1, l.nr)
3770 call assert_equal('Test7', l.title)
3771
3772 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3773 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3774 silent! 99Xolder
3775 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3776 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3777 call assert_equal(10, l.nr)
3778 call assert_equal('Test8', l.title)
3779
3780 " Add a quickfix list using 'nr' set to a value greater than 10
3781 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3782
3783 " Try adding a quickfix list with 'nr' set to a value greater than the
3784 " quickfix list size but less than 10.
3785 call g:Xsetlist([], 'f')
3786 Xexpr "" | Xexpr "" | Xexpr ""
3787 silent! 99Xolder
3788 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3789
3790 " Add a quickfix list using 'nr' set to a some string or list
3791 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3792endfunc
3793
3794func Test_add_qf()
3795 call XaddQf_tests('c')
3796 call XaddQf_tests('l')
3797endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003798
3799" Test for getting the quickfix list items from some text without modifying
3800" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003801func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003802 call s:setup_commands(a:cchar)
3803 call g:Xsetlist([], 'f')
3804
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003805 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003806 call assert_equal(2, len(l))
3807 call assert_equal(30, l[1].lnum)
3808
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003809 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3810 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3811 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3812 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003813
Bram Moolenaar36538222017-09-02 19:51:44 +02003814 " Parse text using a custom efm
3815 set efm&
3816 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3817 call assert_equal('Line30', l[0].text)
3818 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3819 call assert_equal('File3:30:Line30', l[0].text)
3820 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3821 call assert_equal({}, l)
3822 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3823 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3824
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003825 " Make sure that the quickfix stack is not modified
3826 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3827endfunc
3828
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003829func Test_get_list_from_lines()
3830 call XgetListFromLines('c')
3831 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003832endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003833
3834" Tests for the quickfix list id
3835func Xqfid_tests(cchar)
3836 call s:setup_commands(a:cchar)
3837
3838 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003839 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003840 Xexpr ''
3841 let start_id = g:Xgetlist({'id' : 0}).id
3842 Xexpr '' | Xexpr ''
3843 Xolder
3844 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3845 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3846 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003847 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003848 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003849 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3850 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003851
3852 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3853 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003854 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003855 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3856 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3857 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3858
3859 let qfid = g:Xgetlist({'id':0, 'nr':0})
3860 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003861 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003862endfunc
3863
3864func Test_qf_id()
3865 call Xqfid_tests('c')
3866 call Xqfid_tests('l')
3867endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003868
3869func Xqfjump_tests(cchar)
3870 call s:setup_commands(a:cchar)
3871
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003872 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3873 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3874 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003875
3876 call g:Xsetlist([], 'f')
3877
3878 " Tests for
3879 " Jumping to a line using a pattern
3880 " Jumping to a column greater than the last column in a line
3881 " Jumping to a line greater than the last line in the file
3882 let l = []
3883 for i in range(1, 7)
3884 call add(l, {})
3885 endfor
3886 let l[0].filename='F1'
3887 let l[0].pattern='Line1'
3888 let l[1].filename='F2'
3889 let l[1].pattern='Line1'
3890 let l[2].filename='F3'
3891 let l[2].pattern='Line1'
3892 let l[3].filename='F3'
3893 let l[3].lnum=1
3894 let l[3].col=9
3895 let l[3].vcol=1
3896 let l[4].filename='F3'
3897 let l[4].lnum=99
3898 let l[5].filename='F3'
3899 let l[5].lnum=1
3900 let l[5].col=99
3901 let l[5].vcol=1
3902 let l[6].filename='F3'
3903 let l[6].pattern='abcxyz'
3904
3905 call g:Xsetlist([], ' ', {'items' : l})
3906 Xopen | only
3907 2Xnext
3908 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003909 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003910 Xnext
3911 call assert_equal(7, col('.'))
3912 Xnext
3913 call assert_equal(2, line('.'))
3914 Xnext
3915 call assert_equal(9, col('.'))
3916 2
3917 Xnext
3918 call assert_equal(2, line('.'))
3919
3920 if a:cchar == 'l'
3921 " When jumping to a location list entry in the location list window and
3922 " no usable windows are available, then a new window should be opened.
3923 enew! | new | only
3924 call g:Xsetlist([], 'f')
3925 setlocal buftype=nofile
3926 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003927 let lines =<< trim END
3928 F1:1:1:Line1
3929 F1:2:2:Line2
3930 F2:1:1:Line1
3931 F2:2:2:Line2
3932 F3:1:1:Line1
3933 F3:2:2:Line2
3934 END
3935 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003936 Xopen
3937 let winid = win_getid()
3938 wincmd p
3939 close
3940 call win_gotoid(winid)
3941 Xnext
3942 call assert_equal(3, winnr('$'))
3943 call assert_equal(1, winnr())
3944 call assert_equal(2, line('.'))
3945
3946 " When jumping to an entry in the location list window and the window
3947 " associated with the location list is not present and a window containing
3948 " the file is already present, then that window should be used.
3949 close
3950 belowright new
3951 call g:Xsetlist([], 'f')
3952 edit F3
3953 call win_gotoid(winid)
3954 Xlast
3955 call assert_equal(3, winnr())
3956 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3957 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3958 endif
3959
3960 " Cleanup
3961 enew!
3962 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01003963endfunc
3964
3965func Test_qfjump()
3966 call Xqfjump_tests('c')
3967 call Xqfjump_tests('l')
3968endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003969
3970" Tests for the getqflist() and getloclist() functions when the list is not
3971" present or is empty
3972func Xgetlist_empty_tests(cchar)
3973 call s:setup_commands(a:cchar)
3974
3975 " Empty quickfix stack
3976 call g:Xsetlist([], 'f')
3977 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3978 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3979 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3980 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3981 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3982 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3983 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3984 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003985 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003986 if a:cchar == 'c'
3987 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003988 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003989 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3990 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003991 else
3992 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3993 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003994 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003995 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003996 \ g:Xgetlist({'all' : 0}))
3997 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003998
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003999 " Quickfix window with empty stack
4000 silent! Xopen
4001 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004002 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004003 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4004 Xclose
4005
Bram Moolenaara6d48492017-12-12 22:45:31 +01004006 " Empty quickfix list
4007 Xexpr ""
4008 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4009 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4010 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4011 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4012 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4013 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4014 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4015 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004016 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004017
4018 let qfid = g:Xgetlist({'id' : 0}).id
4019 call g:Xsetlist([], 'f')
4020
4021 " Non-existing quickfix identifier
4022 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4023 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4024 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4025 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4026 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4027 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4028 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4029 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004030 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004031 if a:cchar == 'c'
4032 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4033 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004034 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004035 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4036 else
4037 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4038 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004039 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4040 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004041 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4042 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004043
4044 " Non-existing quickfix list number
4045 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4046 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4047 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4048 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4049 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4050 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4051 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4052 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004053 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004054 if a:cchar == 'c'
4055 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4056 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004057 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4058 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004059 else
4060 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4061 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004062 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4063 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004064 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004065endfunc
4066
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004067func Test_empty_list_quickfixtextfunc()
4068 " This was crashing. Can only reproduce by running it in a separate Vim
4069 " instance.
4070 let lines =<< trim END
4071 func s:Func(o)
4072 cgetexpr '0'
4073 endfunc
4074 cope
4075 let &quickfixtextfunc = 's:Func'
4076 cgetfile [ex
4077 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004078 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004079 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004080endfunc
4081
Bram Moolenaara6d48492017-12-12 22:45:31 +01004082func Test_getqflist()
4083 call Xgetlist_empty_tests('c')
4084 call Xgetlist_empty_tests('l')
4085endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004086
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004087func Test_getqflist_invalid_nr()
4088 " The following commands used to crash Vim
4089 cexpr ""
4090 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4091
4092 " Cleanup
4093 call setqflist([], 'r')
4094endfunc
4095
Bram Moolenaarb254af32017-12-18 19:48:58 +01004096" Tests for the quickfix/location list changedtick
4097func Xqftick_tests(cchar)
4098 call s:setup_commands(a:cchar)
4099
4100 call g:Xsetlist([], 'f')
4101
4102 Xexpr "F1:10:Line10"
4103 let qfid = g:Xgetlist({'id' : 0}).id
4104 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4105 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4106 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4107 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4108 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4109 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4110 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4111 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4112 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4113
4114 enew!
4115 call append(0, ["F5:50:L50", "F6:60:L60"])
4116 Xaddbuffer
4117 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4118 enew!
4119
4120 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4121 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4122 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4123 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4124 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4125 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4126 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4127 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4128 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4129 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4130 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4131
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004132 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004133 Xfile Xone
4134 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4135 Xaddfile Xone
4136 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4137
4138 " Test case for updating a non-current quickfix list
4139 call g:Xsetlist([], 'f')
4140 Xexpr "F1:1:L1"
4141 Xexpr "F2:2:L2"
4142 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4143 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4144 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004145endfunc
4146
4147func Test_qf_tick()
4148 call Xqftick_tests('c')
4149 call Xqftick_tests('l')
4150endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004151
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004152" Test helpgrep with lang specifier
4153func Xtest_helpgrep_with_lang_specifier(cchar)
4154 call s:setup_commands(a:cchar)
4155 Xhelpgrep Vim@en
4156 call assert_equal('help', &filetype)
4157 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4158 new | only
4159endfunc
4160
4161func Test_helpgrep_with_lang_specifier()
4162 call Xtest_helpgrep_with_lang_specifier('c')
4163 call Xtest_helpgrep_with_lang_specifier('l')
4164endfunc
4165
Bram Moolenaar12237442017-12-19 12:38:52 +01004166" The following test used to crash Vim.
4167" Open the location list window and close the regular window associated with
4168" the location list. When the garbage collection runs now, it incorrectly
4169" marks the location list context as not in use and frees the context.
4170func Test_ll_window_ctx()
4171 call setloclist(0, [], 'f')
4172 call setloclist(0, [], 'a', {'context' : []})
4173 lopen | only
4174 call test_garbagecollect_now()
4175 echo getloclist(0, {'context' : 1}).context
4176 enew | only
4177endfunc
4178
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004179" The following test used to crash vim
4180func Test_lfile_crash()
4181 sp Xtest
4182 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004183 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004184 au! QuickFixCmdPre
4185endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004186
4187" The following test used to crash vim
4188func Test_lbuffer_crash()
4189 sv Xtest
4190 augroup QF_Test
4191 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004192 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004193 augroup END
4194 lbuffer
4195 augroup QF_Test
4196 au!
4197 augroup END
4198endfunc
4199
4200" The following test used to crash vim
4201func Test_lexpr_crash()
4202 augroup QF_Test
4203 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004204 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004205 augroup END
4206 lexpr ""
4207 augroup QF_Test
4208 au!
4209 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004210
Bram Moolenaar3c097222017-12-21 20:54:49 +01004211 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004212 augroup QF_Test
4213 au!
4214 au BufNew * call setloclist(0, [], 'f')
4215 augroup END
4216 lexpr 'x:1:x'
4217 augroup QF_Test
4218 au!
4219 augroup END
4220
4221 enew | only
4222 lexpr ''
4223 lopen
4224 augroup QF_Test
4225 au!
4226 au FileType * call setloclist(0, [], 'f')
4227 augroup END
4228 lexpr ''
4229 augroup QF_Test
4230 au!
4231 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004232endfunc
4233
4234" The following test used to crash Vim
4235func Test_lvimgrep_crash()
4236 sv Xtest
4237 augroup QF_Test
4238 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004239 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004240 augroup END
4241 lvimgrep quickfix test_quickfix.vim
4242 augroup QF_Test
4243 au!
4244 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004245
4246 new | only
4247 augroup QF_Test
4248 au!
4249 au BufEnter * call setloclist(0, [], 'r')
4250 augroup END
4251 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4252 augroup QF_Test
4253 au!
4254 augroup END
4255
Bram Moolenaar3c097222017-12-21 20:54:49 +01004256 enew | only
4257endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004258
Bram Moolenaar2573af32020-03-14 17:21:34 +01004259func Test_lvimgrep_crash2()
4260 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004261 call assert_fails('lvimgrep x x', 'E471:')
4262 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004263
4264 au! BufNewFile
4265endfunc
4266
Bram Moolenaarde046542017-12-26 13:53:11 +01004267" Test for the position of the quickfix and location list window
4268func Test_qfwin_pos()
4269 " Open two windows
4270 new | only
4271 new
4272 cexpr ['F1:10:L10']
4273 copen
4274 " Quickfix window should be the bottom most window
4275 call assert_equal(3, winnr())
4276 close
4277 " Open at the very top
4278 wincmd t
4279 topleft copen
4280 call assert_equal(1, winnr())
4281 close
4282 " open left of the current window
4283 wincmd t
4284 below new
4285 leftabove copen
4286 call assert_equal(2, winnr())
4287 close
4288 " open right of the current window
4289 rightbelow copen
4290 call assert_equal(3, winnr())
4291 close
4292endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004293
4294" Tests for quickfix/location lists changed by autocommands when
4295" :vimgrep/:lvimgrep commands are running.
4296func Test_vimgrep_autocmd()
4297 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004298 call writefile(['stars'], 'Xtest1.txt', 'D')
4299 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004300
4301 " Test 1:
4302 " When searching for a pattern using :vimgrep, if the quickfix list is
4303 " changed by an autocmd, the results should be added to the correct quickfix
4304 " list.
4305 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4306 silent vimgrep stars Xtest*.txt
4307 call assert_equal(1, getqflist({'nr' : 0}).nr)
4308 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4309 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4310 au! BufRead Xtest2.txt
4311
4312 " Test 2:
4313 " When searching for a pattern using :vimgrep, if the quickfix list is
4314 " freed, then a error should be given.
4315 silent! %bwipe!
4316 call setqflist([], 'f')
4317 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4318 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4319 au! BufRead Xtest2.txt
4320
4321 " Test 3:
4322 " When searching for a pattern using :lvimgrep, if the location list is
4323 " freed, then the command should error out.
4324 silent! %bwipe!
4325 let g:save_winid = win_getid()
4326 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4327 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4328 au! BufRead Xtest2.txt
4329
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004330 call setqflist([], 'f')
4331endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004332
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004333" Test for an autocmd changing the current directory when running vimgrep
4334func Xvimgrep_autocmd_cd(cchar)
4335 call s:setup_commands(a:cchar)
4336
4337 %bwipe
4338 let save_cwd = getcwd()
4339
4340 augroup QF_Test
4341 au!
4342 autocmd BufRead * silent cd %:p:h
4343 augroup END
4344
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004345 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004346 let l = g:Xgetlist()
4347 call assert_equal('f1.txt', bufname(l[0].bufnr))
4348 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4349
4350 augroup QF_Test
4351 au!
4352 augroup END
4353
4354 exe 'cd ' . save_cwd
4355endfunc
4356
4357func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004358 call mkdir('Xgrepdir/a', 'pR')
4359 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004360 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4361 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004362 call Xvimgrep_autocmd_cd('c')
4363 call Xvimgrep_autocmd_cd('l')
4364 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004365endfunc
4366
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004367" The following test used to crash Vim
4368func Test_lhelpgrep_autocmd()
4369 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004370 augroup QF_Test
4371 au!
4372 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4373 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004374 lhelpgrep buffer
4375 call assert_equal('help', &filetype)
4376 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4377 lhelpgrep tabpage
4378 call assert_equal('help', &filetype)
4379 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004380 augroup QF_Test
4381 au!
4382 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004383
4384 new | only
4385 augroup QF_Test
4386 au!
4387 au BufEnter * call setqflist([], 'f')
4388 augroup END
4389 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004390 " run the test with a help window already open
4391 help
4392 wincmd w
4393 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004394 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004395 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004396 augroup END
4397
4398 new | only
4399 augroup QF_Test
4400 au!
4401 au BufEnter * call setqflist([], 'r')
4402 augroup END
4403 call assert_fails('helpgrep quickfix', 'E925:')
4404 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004405 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004406 augroup END
4407
4408 new | only
4409 augroup QF_Test
4410 au!
4411 au BufEnter * call setloclist(0, [], 'r')
4412 augroup END
4413 call assert_fails('lhelpgrep quickfix', 'E926:')
4414 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004415 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004416 augroup END
4417
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004418 " Replace the contents of a help window location list when it is still in
4419 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004420 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004421 lhelpgrep quickfix
4422 wincmd w
4423 augroup QF_Test
4424 au!
4425 autocmd WinEnter * call setloclist(0, [], 'r')
4426 augroup END
4427 call assert_fails('lhelpgrep win_getid', 'E926:')
4428 augroup QF_Test
4429 au!
4430 augroup END
4431
4432 %bw!
4433endfunc
4434
4435" The following test used to crash Vim
4436func Test_lhelpgrep_autocmd_free_loclist()
4437 %bw!
4438 lhelpgrep quickfix
4439 wincmd w
4440 augroup QF_Test
4441 au!
4442 autocmd WinEnter * call setloclist(0, [], 'f')
4443 augroup END
4444 lhelpgrep win_getid
4445 wincmd w
4446 wincmd w
4447 wincmd w
4448 augroup QF_Test
4449 au!
4450 augroup END
4451 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004452endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004453
4454" Test for shortening/simplifying the file name when opening the
4455" quickfix window or when displaying the quickfix list
4456func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004457 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004458 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004459 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004460 let fname = getcwd() . '/test_quickfix.vim'
4461 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4462 call assert_equal(fname, bufname('test_quickfix.vim'))
4463 " Opening the quickfix window should simplify the file path
4464 cwindow
4465 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4466 cclose
4467 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004468 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004469 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4470 call assert_equal(fname, bufname('test_quickfix.vim'))
4471 " Displaying the quickfix list should simplify the file path
4472 silent! clist
4473 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004474 " Add a few entries for the same file with different paths and check whether
4475 " the buffer name is shortened
4476 %bwipe
4477 call setqflist([], 'f')
4478 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4479 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4480 \ {'filename' : fname, 'lnum' : 30}], ' ')
4481 copen
4482 call assert_equal(['test_quickfix.vim|10| ',
4483 \ 'test_quickfix.vim|20| ',
4484 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4485 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004486endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004487
4488" Quickfix title tests
4489" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4490" Otherwise due to indentation, the title is set with spaces at the beginning
4491" of the command.
4492func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004493 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004494
4495 " :cexpr
4496 exe "cexpr readfile('Xerr')"
4497 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4498
4499 " :cgetexpr
4500 exe "cgetexpr readfile('Xerr')"
4501 call assert_equal(":cgetexpr readfile('Xerr')",
4502 \ getqflist({'title' : 1}).title)
4503
4504 " :caddexpr
4505 call setqflist([], 'f')
4506 exe "caddexpr readfile('Xerr')"
4507 call assert_equal(":caddexpr readfile('Xerr')",
4508 \ getqflist({'title' : 1}).title)
4509
4510 " :cbuffer
4511 new Xerr
4512 exe "cbuffer"
4513 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4514
4515 " :cgetbuffer
4516 edit Xerr
4517 exe "cgetbuffer"
4518 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4519
4520 " :caddbuffer
4521 call setqflist([], 'f')
4522 edit Xerr
4523 exe "caddbuffer"
4524 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4525
4526 " :cfile
4527 exe "cfile Xerr"
4528 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4529
4530 " :cgetfile
4531 exe "cgetfile Xerr"
4532 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4533
4534 " :caddfile
4535 call setqflist([], 'f')
4536 exe "caddfile Xerr"
4537 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4538
4539 " :grep
4540 set grepprg=internal
4541 exe "grep F1 Xerr"
4542 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4543
4544 " :grepadd
4545 call setqflist([], 'f')
4546 exe "grepadd F1 Xerr"
4547 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4548 set grepprg&vim
4549
4550 " :vimgrep
4551 exe "vimgrep F1 Xerr"
4552 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4553
4554 " :vimgrepadd
4555 call setqflist([], 'f')
4556 exe "vimgrepadd F1 Xerr"
4557 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4558
4559 call setqflist(['F1:10:L10'], ' ')
4560 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4561
4562 call setqflist([], 'f')
4563 call setqflist(['F1:10:L10'], 'a')
4564 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4565
4566 call setqflist([], 'f')
4567 call setqflist(['F1:10:L10'], 'r')
4568 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4569
4570 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004571
4572 call setqflist([], ' ', {'title' : 'Errors'})
4573 copen
4574 call assert_equal('Errors', w:quickfix_title)
4575 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4576 call assert_equal('Errors', w:quickfix_title)
4577 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004578
4579 " Switching to another quickfix list in one tab page should update the
4580 " quickfix window title and statusline in all the other tab pages also
4581 call setqflist([], 'f')
4582 %bw!
4583 cgetexpr ['file_one:1:1: error in the first quickfix list']
4584 call setqflist([], 'a', {'title': 'first quickfix list'})
4585 cgetexpr ['file_two:2:1: error in the second quickfix list']
4586 call setqflist([], 'a', {'title': 'second quickfix list'})
4587 copen
4588 wincmd t
4589 tabnew two
4590 copen
4591 wincmd t
4592 colder
4593 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4594 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4595 call assert_equal(1, tabpagewinnr(1))
4596 call assert_equal(1, tabpagewinnr(2))
4597 tabnew
4598 call setqflist([], 'a', {'title': 'new quickfix title'})
4599 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4600 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4601 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004602endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004603
4604func Test_lbuffer_with_bwipe()
4605 new
4606 new
4607 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004608 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004609 augroup END
4610 lbuffer
4611 augroup nasty
4612 au!
4613 augroup END
4614endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004615
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004616" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4617" running
4618func Xexpr_acmd_freelist(cchar)
4619 call s:setup_commands(a:cchar)
4620
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004621 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004622 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004623 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004624 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004625 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004626 augroup nasty
4627 au!
4628 augroup END
4629endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004630
4631func Test_cexpr_acmd_freelist()
4632 call Xexpr_acmd_freelist('c')
4633 call Xexpr_acmd_freelist('l')
4634endfunc
4635
4636" Test for commands that create a new quickfix/location list and jump to the
4637" first error automatically.
4638func Xjumpto_first_error_test(cchar)
4639 call s:setup_commands(a:cchar)
4640
4641 call s:create_test_file('Xtestfile1')
4642 call s:create_test_file('Xtestfile2')
4643 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4644
4645 " Test for cexpr/lexpr
4646 enew
4647 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004648 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004649 call assert_equal(2, line('.'))
4650
4651 " Test for cfile/lfile
4652 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004653 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004654 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004655 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004656 call assert_equal(2, line('.'))
4657
4658 " Test for cbuffer/lbuffer
4659 edit Xerr
4660 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004661 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004662 call assert_equal(2, line('.'))
4663
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004664 call delete('Xtestfile1')
4665 call delete('Xtestfile2')
4666endfunc
4667
4668func Test_jumpto_first_error()
4669 call Xjumpto_first_error_test('c')
4670 call Xjumpto_first_error_test('l')
4671endfunc
4672
4673" Test for a quickfix autocmd changing the quickfix/location list before
4674" jumping to the first error in the new list.
4675func Xautocmd_changelist(cchar)
4676 call s:setup_commands(a:cchar)
4677
4678 " Test for cfile/lfile
4679 call s:create_test_file('Xtestfile1')
4680 call s:create_test_file('Xtestfile2')
4681 Xexpr 'Xtestfile1:2:Line2'
4682 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004683 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004684 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004685 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004686 call assert_equal(4, line('.'))
4687 autocmd! QuickFixCmdPost
4688
4689 " Test for cbuffer/lbuffer
4690 call g:Xsetlist([], 'f')
4691 Xexpr 'Xtestfile1:2:Line2'
4692 autocmd QuickFixCmdPost * Xolder
4693 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4694 edit Xerr
4695 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004696 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004697 call assert_equal(4, line('.'))
4698 autocmd! QuickFixCmdPost
4699
4700 " Test for cexpr/lexpr
4701 call g:Xsetlist([], 'f')
4702 Xexpr 'Xtestfile1:2:Line2'
4703 autocmd QuickFixCmdPost * Xolder
4704 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004705 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004706 call assert_equal(4, line('.'))
4707 autocmd! QuickFixCmdPost
4708
Bram Moolenaar851332e2018-07-03 19:16:00 +02004709 " The grepprg may not be set on non-Unix systems
4710 if has('unix')
4711 " Test for grep/lgrep
4712 call g:Xsetlist([], 'f')
4713 Xexpr 'Xtestfile1:2:Line2'
4714 autocmd QuickFixCmdPost * Xolder
4715 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004716 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004717 call assert_equal(5, line('.'))
4718 autocmd! QuickFixCmdPost
4719 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004720
4721 " Test for vimgrep/lvimgrep
4722 call g:Xsetlist([], 'f')
4723 Xexpr 'Xtestfile1:2:Line2'
4724 autocmd QuickFixCmdPost * Xolder
4725 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004726 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004727 call assert_equal(5, line('.'))
4728 autocmd! QuickFixCmdPost
4729
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004730 " Test for autocommands clearing the quickfix list before jumping to the
4731 " first error. This should not result in an error
4732 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4733 let v:errmsg = ''
4734 " Test for cfile/lfile
4735 Xfile Xerr
4736 call assert_true(v:errmsg !~# 'E42:')
4737 " Test for cbuffer/lbuffer
4738 edit Xerr
4739 Xbuffer
4740 call assert_true(v:errmsg !~# 'E42:')
4741 " Test for cexpr/lexpr
4742 Xexpr 'Xtestfile2:4:Line4'
4743 call assert_true(v:errmsg !~# 'E42:')
4744 " Test for grep/lgrep
4745 " The grepprg may not be set on non-Unix systems
4746 if has('unix')
4747 silent Xgrep Line5 Xtestfile2
4748 call assert_true(v:errmsg !~# 'E42:')
4749 endif
4750 " Test for vimgrep/lvimgrep
4751 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4752 autocmd! QuickFixCmdPost
4753
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004754 call delete('Xtestfile1')
4755 call delete('Xtestfile2')
4756endfunc
4757
4758func Test_autocmd_changelist()
4759 call Xautocmd_changelist('c')
4760 call Xautocmd_changelist('l')
4761endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004762
4763" Tests for the ':filter /pat/ clist' command
4764func Test_filter_clist()
4765 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4766 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4767 \ split(execute('filter /Line 15/ clist'), "\n"))
4768 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4769 \ split(execute('filter /Xfile1/ clist'), "\n"))
4770 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4771
4772 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4773 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4774 call assert_equal([' 2 pqr:pat2: '],
4775 \ split(execute('filter /pqr/ clist'), "\n"))
4776 call assert_equal([' 1 abc:pat1: '],
4777 \ split(execute('filter /pat1/ clist'), "\n"))
4778endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004779
4780" Tests for the "CTRL-W <CR>" command.
4781func Xview_result_split_tests(cchar)
4782 call s:setup_commands(a:cchar)
4783
4784 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4785 call g:Xsetlist([])
4786 Xopen
4787 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004788 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004789 call assert_equal(l:win_count, winnr('$'))
4790 Xclose
4791endfunc
4792
4793func Test_view_result_split()
4794 call Xview_result_split_tests('c')
4795 call Xview_result_split_tests('l')
4796endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004797
4798" Test that :cc sets curswant
4799func Test_curswant()
4800 helpgrep quickfix
4801 normal! llll
4802 1cc
4803 call assert_equal(getcurpos()[4], virtcol('.'))
4804 cclose | helpclose
4805endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004806
4807" Test for opening a file from the quickfix window using CTRL-W <Enter>
4808" doesn't leave an empty buffer around.
4809func Test_splitview()
4810 call s:create_test_file('Xtestfile1')
4811 call s:create_test_file('Xtestfile2')
4812 new | only
4813 let last_bufnr = bufnr('Test_sv_1', 1)
4814 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4815 cgetexpr l
4816 copen
4817 let numbufs = len(getbufinfo())
4818 exe "normal \<C-W>\<CR>"
4819 copen
4820 exe "normal j\<C-W>\<CR>"
4821 " Make sure new empty buffers are not created
4822 call assert_equal(numbufs, len(getbufinfo()))
4823 " Creating a new buffer should use the next available buffer number
4824 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4825 bwipe Test_sv_1
4826 bwipe Test_sv_2
4827 new | only
4828
4829 " When split opening files from location list window, make sure that two
4830 " windows doesn't refer to the same location list
4831 lgetexpr l
4832 let locid = getloclist(0, {'id' : 0}).id
4833 lopen
4834 exe "normal \<C-W>\<CR>"
4835 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4836 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4837 new | only
4838
4839 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004840 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004841 lhelpgrep window
4842 let locid = getloclist(0, {'id' : 0}).id
4843 lwindow
4844 exe "normal j\<C-W>\<CR>"
4845 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4846 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4847 new | only
4848
Bram Moolenaar406cd902020-02-18 21:54:41 +01004849 " Using :split or :vsplit from a quickfix window should behave like a :new
4850 " or a :vnew command
4851 copen
4852 split
4853 call assert_equal(3, winnr('$'))
4854 let l = getwininfo()
4855 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4856 close
4857 copen
4858 vsplit
4859 let l = getwininfo()
4860 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4861 new | only
4862
Bram Moolenaarb2443732018-11-11 22:50:27 +01004863 call delete('Xtestfile1')
4864 call delete('Xtestfile2')
4865endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004866
4867" Test for parsing entries using visual screen column
4868func Test_viscol()
4869 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004870 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004871 edit Xfile1
4872
4873 " Use byte offset for column number
4874 set efm&
4875 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4876 call assert_equal([5, 8], [col('.'), virtcol('.')])
4877 cnext
4878 call assert_equal([9, 12], [col('.'), virtcol('.')])
4879 cnext
4880 call assert_equal([14, 20], [col('.'), virtcol('.')])
4881
4882 " Use screen column offset for column number
4883 set efm=%f:%l:%v:%m
4884 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4885 call assert_equal([5, 8], [col('.'), virtcol('.')])
4886 cnext
4887 call assert_equal([9, 12], [col('.'), virtcol('.')])
4888 cnext
4889 call assert_equal([14, 20], [col('.'), virtcol('.')])
4890 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4891 call assert_equal([5, 8], [col('.'), virtcol('.')])
4892 cnext
4893 call assert_equal([10, 16], [col('.'), virtcol('.')])
4894 cnext
4895 call assert_equal([14, 20], [col('.'), virtcol('.')])
4896
4897 enew
4898 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4899
4900 " Use byte offset for column number
4901 set efm&
4902 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4903 call assert_equal([8, 10], [col('.'), virtcol('.')])
4904 cnext
4905 call assert_equal([11, 17], [col('.'), virtcol('.')])
4906 cnext
4907 call assert_equal([16, 25], [col('.'), virtcol('.')])
4908
4909 " Use screen column offset for column number
4910 set efm=%f:%l:%v:%m
4911 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4912 call assert_equal([8, 10], [col('.'), virtcol('.')])
4913 cnext
4914 call assert_equal([11, 17], [col('.'), virtcol('.')])
4915 cnext
4916 call assert_equal([16, 25], [col('.'), virtcol('.')])
4917
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004918 " Use screen column number with a multi-line error message
4919 enew
4920 call writefile(["à test"], 'Xfile1')
4921 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4922 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4923 call assert_equal('Xfile1', @%)
4924 call assert_equal([0, 1, 4, 0], getpos('.'))
4925
4926 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4927 " does not break this
4928 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4929 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4930 call assert_equal('Xfile1', @%)
4931 call assert_equal([0, 1, 3, 0], getpos('.'))
4932
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004933 enew | only
4934 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004935endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004936
4937" Test for the quickfix window buffer
4938func Xqfbuf_test(cchar)
4939 call s:setup_commands(a:cchar)
4940
4941 " Quickfix buffer should be reused across closing and opening a quickfix
4942 " window
4943 Xexpr "F1:10:Line10"
4944 Xopen
4945 let qfbnum = bufnr('')
4946 Xclose
4947 " Even after the quickfix window is closed, the buffer should be loaded
4948 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004949 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004950 Xopen
4951 " Buffer should be reused when opening the window again
4952 call assert_equal(qfbnum, bufnr(''))
4953 Xclose
4954
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004955 " When quickfix buffer is wiped out, getqflist() should return 0
4956 %bw!
4957 Xexpr ""
4958 Xopen
4959 bw!
4960 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4961
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004962 if a:cchar == 'l'
4963 %bwipe
4964 " For a location list, when both the file window and the location list
4965 " window for the list are closed, then the buffer should be freed.
4966 new | only
4967 lexpr "F1:10:Line10"
4968 let wid = win_getid()
4969 lopen
4970 let qfbnum = bufnr('')
4971 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4972 close
4973 " When the location list window is closed, the buffer name should not
4974 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004975 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004976 call assert_true(bufloaded(qfbnum))
4977
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004978 " After deleting a location list buffer using ":bdelete", opening the
4979 " location list window should mark the buffer as a location list buffer.
4980 exe "bdelete " . qfbnum
4981 lopen
4982 call assert_equal("quickfix", &buftype)
4983 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4984 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4985 call assert_false(&swapfile)
4986 lclose
4987
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004988 " When the location list is cleared for the window, the buffer should be
4989 " removed
4990 call setloclist(0, [], 'f')
4991 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004992 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004993
4994 " When the location list is freed with the location list window open, the
4995 " location list buffer should not be lost. It should be reused when the
4996 " location list is again populated.
4997 lexpr "F1:10:Line10"
4998 lopen
4999 let wid = win_getid()
5000 let qfbnum = bufnr('')
5001 wincmd p
5002 call setloclist(0, [], 'f')
5003 lexpr "F1:10:Line10"
5004 lopen
5005 call assert_equal(wid, win_getid())
5006 call assert_equal(qfbnum, bufnr(''))
5007 lclose
5008
5009 " When the window with the location list is closed, the buffer should be
5010 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005011 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005012 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005013 endif
5014endfunc
5015
5016func Test_qfbuf()
5017 call Xqfbuf_test('c')
5018 call Xqfbuf_test('l')
5019endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005020
5021" If there is an autocmd to use only one window, then opening the location
5022" list window used to crash Vim.
5023func Test_winonly_autocmd()
5024 call s:create_test_file('Xtest1')
5025 " Autocmd to show only one Vim window at a time
5026 autocmd WinEnter * only
5027 new
5028 " Load the location list
5029 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5030 let loclistid = getloclist(0, {'id' : 0}).id
5031 " Open the location list window. Only this window will be shown and the file
5032 " window is closed.
5033 lopen
5034 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5035 " Jump to an entry in the location list and make sure that the cursor is
5036 " positioned correctly.
5037 ll 3
5038 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005039 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005040 call assert_equal(15, line('.'))
5041 " Cleanup
5042 autocmd! WinEnter
5043 new | only
5044 call delete('Xtest1')
5045endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005046
5047" Test to make sure that an empty quickfix buffer is not reused for loading
5048" a normal buffer.
5049func Test_empty_qfbuf()
5050 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005051 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005052 call setqflist([], 'f')
5053 copen | only
5054 let qfbuf = bufnr('')
5055 edit Xfile1
5056 call assert_notequal(qfbuf, bufnr(''))
5057 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005058endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005059
5060" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005061" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005062func Xtest_below(cchar)
5063 call s:setup_commands(a:cchar)
5064
5065 " No quickfix/location list
5066 call assert_fails('Xbelow', 'E42:')
5067 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005068 call assert_fails('Xbefore', 'E42:')
5069 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005070
5071 " Empty quickfix/location list
5072 call g:Xsetlist([])
5073 call assert_fails('Xbelow', 'E42:')
5074 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005075 call assert_fails('Xbefore', 'E42:')
5076 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005077
5078 call s:create_test_file('X1')
5079 call s:create_test_file('X2')
5080 call s:create_test_file('X3')
5081 call s:create_test_file('X4')
5082
5083 " Invalid entries
5084 edit X1
5085 call g:Xsetlist(["E1", "E2"])
5086 call assert_fails('Xbelow', 'E42:')
5087 call assert_fails('Xabove', 'E42:')
5088 call assert_fails('3Xbelow', 'E42:')
5089 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005090 call assert_fails('Xbefore', 'E42:')
5091 call assert_fails('Xafter', 'E42:')
5092 call assert_fails('3Xbefore', 'E42:')
5093 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005094
5095 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005096 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 +02005097 edit +7 X2
5098 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005099 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005100 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005101 normal 7G
5102 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005103 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005104 call assert_fails('Xbefore', 'E553:')
5105
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005106 normal 2j
5107 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005108 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005109 normal 7G
5110 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005111 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005112
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005113 " Last error in this file
5114 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005115 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005116 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005117 normal gg
5118 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005119 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005120 call assert_fails('Xafter', 'E553:')
5121
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005122 " First error in this file
5123 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005124 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005125 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005126 normal G
5127 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005128 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005129 call assert_fails('Xbefore', 'E553:')
5130
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005131 normal gg
5132 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005133 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005134 normal gg
5135 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005136 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005137
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005138 normal G
5139 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005140 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005141 normal G
5142 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005143 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005144
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005145 edit X4
5146 call assert_fails('Xabove', 'E42:')
5147 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005148 call assert_fails('Xbefore', 'E42:')
5149 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005150 if a:cchar == 'l'
5151 " If a buffer has location list entries from some other window but not
5152 " from the current window, then the commands should fail.
5153 edit X1 | split | call setloclist(0, [], 'f')
5154 call assert_fails('Xabove', 'E776:')
5155 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005156 call assert_fails('Xbefore', 'E776:')
5157 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005158 close
5159 endif
5160
5161 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005162 let lines =<< trim END
5163 X1:5:L5
5164 X2:5:1:L5_1
5165 X2:5:2:L5_2
5166 X2:5:3:L5_3
5167 X2:10:1:L10_1
5168 X2:10:2:L10_2
5169 X2:10:3:L10_3
5170 X2:15:1:L15_1
5171 X2:15:2:L15_2
5172 X2:15:3:L15_3
5173 X3:3:L3
5174 END
5175 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005176 edit +1 X2
5177 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005178 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005179 normal 1G
5180 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005181 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005182
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005183 normal gg
5184 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005185 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005186 normal gg
5187 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005188 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005189
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005190 normal G
5191 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005192 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005193 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005194 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005195 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005196
5197 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005198 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005199 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005200 normal G
5201 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005202 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005203
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005204 normal 10G
5205 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005206 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005207 normal 10G$
5208 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005209 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005210
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005211 normal 10G
5212 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005213 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005214 normal 9G
5215 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005216 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005217
5218 " Invalid range
5219 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005220 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005221 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005222 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005223 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005224 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005225 endif
5226
5227 call delete('X1')
5228 call delete('X2')
5229 call delete('X3')
5230 call delete('X4')
5231endfunc
5232
5233func Test_cbelow()
5234 call Xtest_below('c')
5235 call Xtest_below('l')
5236endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005237
5238func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005239 let commands =<< trim END
5240 cNext
5241 cNfile
5242 cabove
5243 cbelow
5244 cfirst
5245 clast
5246 cnewer
5247 cnext
5248 cnfile
5249 colder
5250 cprevious
5251 crewind
5252 lNext
5253 lNfile
5254 labove
5255 lbelow
5256 lfirst
5257 llast
5258 lnewer
5259 lnext
5260 lnfile
5261 lolder
5262 lprevious
5263 lrewind
5264 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005265 for cmd in commands
5266 call assert_fails('-1' .. cmd, 'E16:')
5267 call assert_fails('.' .. cmd, 'E16:')
5268 call assert_fails('%' .. cmd, 'E16:')
5269 call assert_fails('$' .. cmd, 'E16:')
5270 endfor
5271endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005272
5273" Test for aborting quickfix commands using QuickFixCmdPre
5274func Xtest_qfcmd_abort(cchar)
5275 call s:setup_commands(a:cchar)
5276
5277 call g:Xsetlist([], 'f')
5278
5279 " cexpr/lexpr
5280 let e = ''
5281 try
5282 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5283 catch /.*/
5284 let e = v:exception
5285 endtry
5286 call assert_equal('AbortCmd', e)
5287 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5288
5289 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005290 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005291 let e = ''
5292 try
5293 Xfile Xfile1
5294 catch /.*/
5295 let e = v:exception
5296 endtry
5297 call assert_equal('AbortCmd', e)
5298 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005299
5300 " cgetbuffer/lgetbuffer
5301 enew!
5302 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5303 let e = ''
5304 try
5305 Xgetbuffer
5306 catch /.*/
5307 let e = v:exception
5308 endtry
5309 call assert_equal('AbortCmd', e)
5310 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5311 enew!
5312
5313 " vimgrep/lvimgrep
5314 let e = ''
5315 try
5316 Xvimgrep /func/ test_quickfix.vim
5317 catch /.*/
5318 let e = v:exception
5319 endtry
5320 call assert_equal('AbortCmd', e)
5321 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5322
5323 " helpgrep/lhelpgrep
5324 let e = ''
5325 try
5326 Xhelpgrep quickfix
5327 catch /.*/
5328 let e = v:exception
5329 endtry
5330 call assert_equal('AbortCmd', e)
5331 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5332
5333 " grep/lgrep
5334 if has('unix')
5335 let e = ''
5336 try
5337 silent Xgrep func test_quickfix.vim
5338 catch /.*/
5339 let e = v:exception
5340 endtry
5341 call assert_equal('AbortCmd', e)
5342 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5343 endif
5344endfunc
5345
5346func Test_qfcmd_abort()
5347 augroup QF_Test
5348 au!
5349 autocmd QuickFixCmdPre * throw "AbortCmd"
5350 augroup END
5351
5352 call Xtest_qfcmd_abort('c')
5353 call Xtest_qfcmd_abort('l')
5354
5355 augroup QF_Test
5356 au!
5357 augroup END
5358endfunc
5359
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005360" Test for using a file in one of the parent directories.
5361func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005362 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005363 let save_cwd = getcwd()
5364 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5365 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5366 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5367 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5368
5369 let lines = "Entering dir Xtestdir\n" .
5370 \ "Entering dir a\n" .
5371 \ "Entering dir b\n" .
5372 \ "Xfile2:2:X2_L2\n" .
5373 \ "Leaving dir a\n" .
5374 \ "Xfile1:2:X1_L2\n" .
5375 \ "Xfile3:1:X3_L1\n" .
5376 \ "Entering dir c\n" .
5377 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005378 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005379 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005380 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005381 call assert_equal(11, getqflist({'size' : 0}).size)
5382 call assert_equal(4, getqflist({'idx' : 0}).idx)
5383 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005384 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005385 cnext
5386 call assert_equal(6, getqflist({'idx' : 0}).idx)
5387 call assert_equal('X1_L2', getline('.'))
5388 cnext
5389 call assert_equal(7, getqflist({'idx' : 0}).idx)
5390 call assert_equal(1, line('$'))
5391 call assert_equal('', getline(1))
5392 cnext
5393 call assert_equal(9, getqflist({'idx' : 0}).idx)
5394 call assert_equal(1, line('$'))
5395 call assert_equal('', getline(1))
5396
5397 set efm&
5398 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005399endfunc
5400
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005401" Test for :cquit
5402func Test_cquit()
5403 " Exit Vim with a non-zero value
5404 if RunVim([], ["cquit 7"], '')
5405 call assert_equal(7, v:shell_error)
5406 endif
5407
5408 if RunVim([], ["50cquit"], '')
5409 call assert_equal(50, v:shell_error)
5410 endif
5411
5412 " Exit Vim with default value
5413 if RunVim([], ["cquit"], '')
5414 call assert_equal(1, v:shell_error)
5415 endif
5416
5417 " Exit Vim with zero value
5418 if RunVim([], ["cquit 0"], '')
5419 call assert_equal(0, v:shell_error)
5420 endif
5421
5422 " Exit Vim with negative value
5423 call assert_fails('-3cquit', 'E16:')
5424endfunc
5425
Bram Moolenaar858ba062020-05-31 23:11:59 +02005426" Test for getting a specific item from a quickfix list
5427func Xtest_getqflist_by_idx(cchar)
5428 call s:setup_commands(a:cchar)
5429 " Empty list
5430 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5431 Xexpr ['F1:10:L10', 'F1:20:L20']
5432 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5433 call assert_equal(bufnr('F1'), l[0].bufnr)
5434 call assert_equal(20, l[0].lnum)
5435 call assert_equal('L20', l[0].text)
5436 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5437 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005438 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005439 %bwipe!
5440endfunc
5441
5442func Test_getqflist_by_idx()
5443 call Xtest_getqflist_by_idx('c')
5444 call Xtest_getqflist_by_idx('l')
5445endfunc
5446
5447" Test for the 'quickfixtextfunc' setting
5448func Tqfexpr(info)
5449 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005450 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005451 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005452 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005453 endif
5454
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005455 let l = []
5456 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5457 let e = qfl[idx]
5458 let s = ''
5459 if e.bufnr != 0
5460 let bname = bufname(e.bufnr)
5461 let s ..= fnamemodify(bname, ':.')
5462 endif
5463 let s ..= '-'
5464 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5465 let s ..= e.text
5466 call add(l, s)
5467 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005468
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005469 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005470endfunc
5471
5472func Xtest_qftextfunc(cchar)
5473 call s:setup_commands(a:cchar)
5474
5475 set efm=%f:%l:%c:%m
5476 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005477 call assert_equal('Tqfexpr', &quickfixtextfunc)
5478 call assert_equal('',
5479 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005480 call g:Xsetlist([
5481 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5482 \ 'end_col': 7, 'text': 'green'},
5483 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5484 \ 'end_col': 8, 'text': 'blue'},
5485 \ ])
5486
Bram Moolenaar858ba062020-05-31 23:11:59 +02005487 Xwindow
5488 call assert_equal('F1-L10C2-green', getline(1))
5489 call assert_equal('F1-L20C4-blue', getline(2))
5490 Xclose
5491 set quickfixtextfunc&vim
5492 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005493 call assert_equal('F1|10 col 2-7| green', getline(1))
5494 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005495 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005496
5497 set efm=%f:%l:%c:%m
5498 set quickfixtextfunc=Tqfexpr
5499 " Update the list with only the cwindow
5500 Xwindow
5501 only
5502 call g:Xsetlist([
5503 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5504 \ 'end_col': 7, 'text': 'red'}
5505 \ ])
5506 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5507 new
5508 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005509 set efm&
5510 set quickfixtextfunc&
5511
5512 " Test for per list 'quickfixtextfunc' setting
5513 func PerQfText(info)
5514 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005515 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005516 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005517 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005518 endif
5519 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005520 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005521 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005522 let l = []
5523 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5524 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5525 endfor
5526 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005527 endfunc
5528 set quickfixtextfunc=Tqfexpr
5529 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5530 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5531 Xwindow
5532 call assert_equal('Line 10, Col 2', getline(1))
5533 call assert_equal('Line 20, Col 4', getline(2))
5534 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005535 call assert_equal(function('PerQfText'),
5536 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005537 " Add entries to the list when the quickfix buffer is hidden
5538 Xaddexpr ['F1:30:6:red']
5539 Xwindow
5540 call assert_equal('Line 30, Col 6', getline(3))
5541 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005542 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005543 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005544 set quickfixtextfunc&
5545 delfunc PerQfText
5546
5547 " Non-existing function
5548 set quickfixtextfunc=Tabc
5549 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5550 call assert_fails("Xwindow", 'E117:')
5551 Xclose
5552 set quickfixtextfunc&
5553
5554 " set option to a non-function
5555 set quickfixtextfunc=[10,\ 20]
5556 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5557 call assert_fails("Xwindow", 'E117:')
5558 Xclose
5559 set quickfixtextfunc&
5560
5561 " set option to a function with different set of arguments
5562 func Xqftext(a, b, c)
5563 return a:a .. a:b .. a:c
5564 endfunc
5565 set quickfixtextfunc=Xqftext
5566 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5567 call assert_fails("Xwindow", 'E119:')
5568 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005569
5570 " set option to a function that returns a list with non-strings
5571 func Xqftext2(d)
5572 return ['one', [], 'two']
5573 endfunc
5574 set quickfixtextfunc=Xqftext2
5575 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5576 \ 'E730:')
5577 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005578 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5579 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005580 Xclose
5581
Bram Moolenaar858ba062020-05-31 23:11:59 +02005582 set quickfixtextfunc&
5583 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005584 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005585
5586 " set the global option to a lambda function
5587 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5588 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5589 Xwindow
5590 call assert_equal(['green', 'blue'], getline(1, '$'))
5591 Xclose
5592 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)
5593 set quickfixtextfunc&
5594
5595 " use a lambda function that returns an empty list
5596 set quickfixtextfunc={d\ ->\ []}
5597 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5598 Xwindow
5599 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5600 \ getline(1, '$'))
5601 Xclose
5602 set quickfixtextfunc&
5603
5604 " use a lambda function that returns a list with empty strings
5605 set quickfixtextfunc={d\ ->\ ['',\ '']}
5606 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5607 Xwindow
5608 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5609 \ getline(1, '$'))
5610 Xclose
5611 set quickfixtextfunc&
5612
5613 " set the per-quickfix list text function to a lambda function
5614 call g:Xsetlist([], ' ',
5615 \ {'quickfixtextfunc' :
5616 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5617 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5618 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5619 Xwindow
5620 call assert_equal('Line 10, Col 2', getline(1))
5621 call assert_equal('Line 20, Col 4', getline(2))
5622 Xclose
5623 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5624 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005625endfunc
5626
5627func Test_qftextfunc()
5628 call Xtest_qftextfunc('c')
5629 call Xtest_qftextfunc('l')
5630endfunc
5631
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005632func Test_qftextfunc_callback()
5633 let lines =<< trim END
5634 set efm=%f:%l:%c:%m
5635
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005636 #" Test for using a function name
5637 LET &qftf = 'g:Tqfexpr'
5638 cexpr "F0:0:0:L0"
5639 copen
5640 call assert_equal('F0-L0C0-L0', getline(1))
5641 cclose
5642
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005643 #" Test for using a function()
5644 set qftf=function('g:Tqfexpr')
5645 cexpr "F1:1:1:L1"
5646 copen
5647 call assert_equal('F1-L1C1-L1', getline(1))
5648 cclose
5649
5650 #" Using a funcref variable to set 'quickfixtextfunc'
5651 VAR Fn = function('g:Tqfexpr')
5652 LET &qftf = Fn
5653 cexpr "F2:2:2:L2"
5654 copen
5655 call assert_equal('F2-L2C2-L2', getline(1))
5656 cclose
5657
5658 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5659 LET Fn = function('g:Tqfexpr')
5660 LET &qftf = string(Fn)
5661 cexpr "F3:3:3:L3"
5662 copen
5663 call assert_equal('F3-L3C3-L3', getline(1))
5664 cclose
5665
5666 #" Test for using a funcref()
5667 set qftf=funcref('g:Tqfexpr')
5668 cexpr "F4:4:4:L4"
5669 copen
5670 call assert_equal('F4-L4C4-L4', getline(1))
5671 cclose
5672
5673 #" Using a funcref variable to set 'quickfixtextfunc'
5674 LET Fn = funcref('g:Tqfexpr')
5675 LET &qftf = Fn
5676 cexpr "F5:5:5:L5"
5677 copen
5678 call assert_equal('F5-L5C5-L5', getline(1))
5679 cclose
5680
5681 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5682 LET Fn = funcref('g:Tqfexpr')
5683 LET &qftf = string(Fn)
5684 cexpr "F5:5:5:L5"
5685 copen
5686 call assert_equal('F5-L5C5-L5', getline(1))
5687 cclose
5688
5689 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005690 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005691 LET optval = substitute(optval, ' ', '\\ ', 'g')
5692 exe "set qftf=" .. optval
5693 cexpr "F6:6:6:L6"
5694 copen
5695 call assert_equal('F6-L6C6-L6', getline(1))
5696 cclose
5697
5698 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005699 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005700 cexpr "F7:7:7:L7"
5701 copen
5702 call assert_equal('F7-L7C7-L7', getline(1))
5703 cclose
5704
5705 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005706 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005707 cexpr "F8:8:8:L8"
5708 copen
5709 call assert_equal('F8-L8C8-L8', getline(1))
5710 cclose
5711
5712 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005713 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005714 LET &qftf = Lambda
5715 cexpr "F9:9:9:L9"
5716 copen
5717 call assert_equal('F9-L9C9-L9', getline(1))
5718 cclose
5719
5720 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005721 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005722 LET &qftf = string(Lambda)
5723 cexpr "F9:9:9:L9"
5724 copen
5725 call assert_equal('F9-L9C9-L9', getline(1))
5726 cclose
5727 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005728 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005729
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005730 " Test for using a script-local function name
5731 func s:TqfFunc2(info)
5732 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5733 return ''
5734 endfunc
5735 let g:TqfFunc2Args = []
5736 set quickfixtextfunc=s:TqfFunc2
5737 cexpr "F10:10:10:L10"
5738 cclose
5739 call assert_equal([1, 1], g:TqfFunc2Args)
5740
5741 let &quickfixtextfunc = 's:TqfFunc2'
5742 cexpr "F11:11:11:L11"
5743 cclose
5744 call assert_equal([1, 1], g:TqfFunc2Args)
5745 delfunc s:TqfFunc2
5746
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005747 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5748 func SetQftfFunc()
5749 let params = {'qftf': function('g:DictQftfFunc')}
5750 let &quickfixtextfunc = params.qftf
5751 endfunc
5752 func g:DictQftfFunc(_) dict
5753 endfunc
5754 call SetQftfFunc()
5755 new
5756 call SetQftfFunc()
5757 bw
5758 call test_garbagecollect_now()
5759 new
5760 set qftf=
5761 wincmd w
5762 set qftf=
5763 :%bw!
5764
5765 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5766 " to cause a crash.
5767 let &qftf = ''
5768 func SetLocalQftfFunc()
5769 let params = {'qftf': function('g:DictQftfFunc')}
5770 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5771 endfunc
5772 call SetLocalQftfFunc()
5773 call test_garbagecollect_now()
5774 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5775 delfunc g:DictQftfFunc
5776 delfunc SetQftfFunc
5777 delfunc SetLocalQftfFunc
5778 set efm&
5779endfunc
5780
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005781" Test for updating a location list for some other window and check that
5782" 'qftextfunc' uses the correct location list.
5783func Test_qftextfunc_other_loclist()
5784 %bw!
5785 call setloclist(0, [], 'f')
5786
5787 " create a window and a location list for it and open the location list
5788 " window
5789 lexpr ['F1:10:12:one', 'F1:20:14:two']
5790 let w1_id = win_getid()
5791 call setloclist(0, [], ' ',
5792 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5793 \ 'quickfixtextfunc':
5794 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5795 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5796 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5797 lwindow
5798 let w2_id = win_getid()
5799
5800 " create another window and a location list for it and open the location
5801 " list window
5802 topleft new
5803 let w3_id = win_getid()
5804 call setloclist(0, [], ' ',
5805 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5806 \ 'quickfixtextfunc':
5807 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5808 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5809 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5810 lwindow
5811 let w4_id = win_getid()
5812
5813 topleft new
5814 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5815 let w5_id = win_getid()
5816
5817 " change the location list for some other window
5818 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5819 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5820 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5821 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5822 \ getbufline(winbufnr(w2_id), 1, '$'))
5823 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5824 \ getbufline(winbufnr(w4_id), 1, '$'))
5825 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5826 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5827 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5828 \ getbufline(winbufnr(w2_id), 1, '$'))
5829 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5830 \ getbufline(winbufnr(w4_id), 1, '$'))
5831
5832 call win_gotoid(w5_id)
5833 lwindow
5834 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5835 \ getline(1, '$'))
5836 %bw!
5837endfunc
5838
Bram Moolenaarec98e932020-06-08 19:35:59 +02005839" Running :lhelpgrep command more than once in a help window, doesn't jump to
5840" the help topic
5841func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005842 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005843 call writefile(['window'], 'Xtestdir/doc/a.txt')
5844 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5845 let save_rtp = &rtp
5846 let &rtp = 'Xtestdir'
5847 lhelpgrep window
5848 lhelpgrep buffer
5849 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5850 lhelpgrep window
5851 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5852 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005853 new | only!
5854endfunc
5855
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005856" Test for the crash fixed by 7.3.715
5857func Test_setloclist_crash()
5858 %bw!
5859 let g:BufNum = bufnr()
5860 augroup QF_Test
5861 au!
5862 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5863 augroup END
5864
5865 try
5866 lvimgrep /.*/ *.mak
5867 catch /E926:/
5868 endtry
5869 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5870 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5871
5872 augroup QF_Test
5873 au!
5874 augroup END
5875 unlet g:BufNum
5876 %bw!
5877endfunc
5878
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005879" Test for adding an invalid entry with the quickfix window open and making
5880" sure that the window contents are not changed
5881func Test_add_invalid_entry_with_qf_window()
5882 call setqflist([], 'f')
5883 cexpr "Xfile1:10:aa"
5884 copen
5885 call setqflist(['bb'], 'a')
5886 call assert_equal(1, line('$'))
5887 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005888 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())
5889
5890 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5891 call assert_equal(1 , line('$'))
5892 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5893 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())
5894
5895 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')
5896 call assert_equal(1 , line('$'))
5897 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5898 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())
5899
5900 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')
5901 call assert_equal(1 , line('$'))
5902 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5903 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())
5904
5905 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')
5906 call assert_equal(1 , line('$'))
5907 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5908 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())
5909
5910 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')
5911 call assert_equal(1 , line('$'))
5912 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5913 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())
5914
5915 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')
5916 call assert_equal(1 , line('$'))
5917 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5918 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())
5919
5920 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')
5921 call assert_equal(1 , line('$'))
5922 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5923 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 +01005924 cclose
5925endfunc
5926
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005927" Test for very weird problem: autocommand causes a failure, resulting opening
5928" the quickfix window to fail. This still splits the window, but otherwise
5929" should not mess up buffers.
5930func Test_quickfix_window_fails_to_open()
5931 CheckScreendump
5932
5933 let lines =<< trim END
5934 anything
5935 try
5936 anything
5937 endtry
5938 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005939 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005940
5941 let lines =<< trim END
5942 split XquickfixFails
5943 silent vimgrep anything %
5944 normal o
5945 au BufLeave * ++once source XquickfixFails
5946 " This will trigger the autocommand, which causes an error, what follows
5947 " is aborted but the window was already split.
5948 silent! cwindow
5949 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005950 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005951 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5952 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5953
5954 " clean up
5955 call term_sendkeys(buf, ":bwipe!\<CR>")
5956 call term_wait(buf)
5957 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005958endfunc
5959
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005960" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005961" is changed.
5962func Xqfbuf_update(cchar)
5963 call s:setup_commands(a:cchar)
5964
5965 Xexpr "F1:1:line1"
5966 Xopen
5967 call assert_equal(['F1|1| line1'], getline(1, '$'))
5968 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5969
5970 " Test setqflist() using the 'lines' key in 'what'
5971 " add a new entry
5972 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5973 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5974 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5975 " replace all the entries with a single entry
5976 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5977 call assert_equal(['F3|3| line3'], getline(1, '$'))
5978 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5979 " remove all the entries
5980 call g:Xsetlist([], 'r', {'lines' : []})
5981 call assert_equal([''], getline(1, '$'))
5982 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5983 " add a new list
5984 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5985 call assert_equal(['F4|4| line4'], getline(1, '$'))
5986 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5987
5988 " Test setqflist() using the 'items' key in 'what'
5989 " add a new entry
5990 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5991 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5992 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5993 " replace all the entries with a single entry
5994 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5995 call assert_equal(['F6|6| line6'], getline(1, '$'))
5996 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5997 " remove all the entries
5998 call g:Xsetlist([], 'r', {'items' : []})
5999 call assert_equal([''], getline(1, '$'))
6000 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6001 " add a new list
6002 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6003 call assert_equal(['F7|7| line7'], getline(1, '$'))
6004 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6005
6006 call g:Xsetlist([], ' ', {})
6007 call assert_equal([''], getline(1, '$'))
6008 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6009
6010 Xclose
6011endfunc
6012
6013func Test_qfbuf_update()
6014 call Xqfbuf_update('c')
6015 call Xqfbuf_update('l')
6016endfunc
6017
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006018func Test_vimgrep_noswapfile()
6019 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006020 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006021 vimgrep two Xgreppie
6022 call assert_equal('two', getline('.'))
6023
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006024 set swapfile
6025endfunc
6026
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006027" Test for the :vimgrep 'f' flag (fuzzy match)
6028func Xvimgrep_fuzzy_match(cchar)
6029 call s:setup_commands(a:cchar)
6030
6031 Xvimgrep /three one/f Xfile*
6032 let l = g:Xgetlist()
6033 call assert_equal(2, len(l))
6034 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6035 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6036 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6037 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6038
6039 Xvimgrep /the/f Xfile*
6040 let l = g:Xgetlist()
6041 call assert_equal(3, len(l))
6042 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6043 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6044 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6045 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6046 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6047 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6048
6049 Xvimgrep /aaa/fg Xfile*
6050 let l = g:Xgetlist()
6051 call assert_equal(4, len(l))
6052 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6053 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6054 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6055 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6056 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6057 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6058 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6059 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6060
6061 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6062endfunc
6063
6064func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006065 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6066 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006067 call Xvimgrep_fuzzy_match('c')
6068 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006069endfunc
6070
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006071func Test_locationlist_open_in_newtab()
6072 call s:create_test_file('Xqftestfile1')
6073 call s:create_test_file('Xqftestfile2')
6074 call s:create_test_file('Xqftestfile3')
6075
6076 %bwipe!
6077
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006078 let lines =<< trim END
6079 Xqftestfile1:5:Line5
6080 Xqftestfile2:10:Line10
6081 Xqftestfile3:16:Line16
6082 END
6083 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006084
6085 silent! llast
6086 call assert_equal(1, tabpagenr('$'))
6087 call assert_equal('Xqftestfile3', bufname())
6088
6089 set switchbuf=newtab
6090
6091 silent! lfirst
6092 call assert_equal(2, tabpagenr('$'))
6093 call assert_equal('Xqftestfile1', bufname())
6094
6095 silent! lnext
6096 call assert_equal(3, tabpagenr('$'))
6097 call assert_equal('Xqftestfile2', bufname())
6098
6099 call delete('Xqftestfile1')
6100 call delete('Xqftestfile2')
6101 call delete('Xqftestfile3')
6102 set switchbuf&vim
6103
6104 %bwipe!
6105endfunc
6106
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006107" Test for win_gettype() in quickfix and location list windows
6108func Test_win_gettype()
6109 copen
6110 call assert_equal("quickfix", win_gettype())
6111 let wid = win_getid()
6112 wincmd p
6113 call assert_equal("quickfix", win_gettype(wid))
6114 cclose
6115 lexpr ''
6116 lopen
6117 call assert_equal("loclist", win_gettype())
6118 let wid = win_getid()
6119 wincmd p
6120 call assert_equal("loclist", win_gettype(wid))
6121 lclose
6122endfunc
6123
Christian Brabandt0b226f62021-12-01 10:54:24 +00006124fun Test_vimgrep_nomatch()
6125 call XexprTests('c')
6126 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6127 copen
6128 if has("win32")
6129 call assert_fails('vimgrep foo *.zzz', 'E479:')
6130 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'}]
6131 else
6132 call assert_fails('vimgrep foo *.zzz', 'E480:')
6133 let expected = []
6134 endif
6135 call assert_equal(expected, getqflist())
6136 cclose
6137endfunc
6138
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006139" Test for opening the quickfix window in two tab pages and then closing one
6140" of the quickfix windows. This should not make the quickfix buffer unlisted.
6141" (github issue #9300).
6142func Test_two_qf_windows()
6143 cexpr "F1:1:line1"
6144 copen
6145 tabnew
6146 copen
6147 call assert_true(&buflisted)
6148 cclose
6149 tabfirst
6150 call assert_true(&buflisted)
6151 let bnum = bufnr()
6152 cclose
6153 " if all the quickfix windows are closed, then buffer should be unlisted.
6154 call assert_false(buflisted(bnum))
6155 %bw!
6156
6157 " Repeat the test for a location list
6158 lexpr "F2:2:line2"
6159 lopen
6160 let bnum = bufnr()
6161 tabnew
6162 exe "buffer" bnum
6163 tabfirst
6164 lclose
6165 tablast
6166 call assert_true(buflisted(bnum))
6167 tabclose
6168 lopen
6169 call assert_true(buflisted(bnum))
6170 lclose
6171 call assert_false(buflisted(bnum))
6172 %bw!
6173endfunc
6174
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006175" Weird sequence of commands that caused entering a wiped-out buffer
6176func Test_lopen_bwipe()
6177 func R()
6178 silent! tab lopen
6179 e x
6180 silent! lfile
6181 endfunc
6182
6183 cal R()
6184 cal R()
6185 cal R()
6186 bw!
6187 delfunc R
6188endfunc
6189
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006190" Another sequence of commands that caused all buffers to be wiped out
6191func Test_lopen_bwipe_all()
6192 let lines =<< trim END
6193 func R()
6194 silent! tab lopen
6195 e foo
6196 silent! lfile
6197 endfunc
6198 cal R()
6199 exe "norm \<C-W>\<C-V>0"
6200 cal R()
6201 bwipe
6202
6203 call writefile(['done'], 'Xresult')
6204 qall!
6205 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006206 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006207 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6208 call assert_equal(['done'], readfile('Xresult'))
6209 endif
6210
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006211 call delete('Xresult')
6212endfunc
6213
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006214" Test for calling setqflist() function recursively
6215func Test_recursive_setqflist()
6216 augroup QF_Test
6217 au!
6218 autocmd BufWinEnter quickfix call setqflist([], 'r')
6219 augroup END
6220
6221 copen
6222 call assert_fails("call setqflist([], 'a')", 'E952:')
6223
6224 augroup QF_Test
6225 au!
6226 augroup END
6227 %bw!
6228endfunc
6229
6230" Test for failure to create a new window when selecting a file from the
6231" quickfix window
6232func Test_cwindow_newwin_fails()
6233 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6234 cwindow
6235 only
6236 let qf_wid = win_getid()
6237 " create the maximum number of scratch windows
6238 let hor_win_count = (&lines - 1)/2
6239 let hor_split_count = hor_win_count - 1
6240 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6241 call win_gotoid(qf_wid)
6242 call assert_fails('exe "normal \<CR>"', 'E36:')
6243 %bw!
6244endfunc
6245
6246" Test for updating the location list when only the location list window is
6247" present and the corresponding file window is closed.
6248func Test_loclist_update_with_llwin_only()
6249 %bw!
6250 new
6251 wincmd w
6252 lexpr ["Xfile1:1:Line1"]
6253 lopen
6254 wincmd p
6255 close
6256 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6257 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6258 %bw!
6259endfunc
6260
6261" Test for getting the quickfix list after a buffer with an error is wiped out
6262func Test_getqflist_wiped_out_buffer()
6263 %bw!
6264 cexpr ["Xtest1:34:Wiped out"]
6265 let bnum = bufnr('Xtest1')
6266 call assert_equal(bnum, getqflist()[0].bufnr)
6267 bw Xtest1
6268 call assert_equal(0, getqflist()[0].bufnr)
6269 %bw!
6270endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006271
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006272" Test for the status message that is displayed when opening a new quickfix
6273" list
6274func Test_qflist_statusmsg()
6275 cexpr "1\n2"
6276 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6277 call assert_equal('(4 of 4): msg', v:statusmsg)
6278 call setqflist([], 'f')
6279 %bw!
6280
6281 " When creating a new quickfix list, if an autocmd changes the quickfix list
6282 " in the stack, then an error message should be displayed.
6283 augroup QF_Test
6284 au!
6285 au BufEnter test_quickfix.vim colder
6286 augroup END
6287 cexpr "1\n2"
6288 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6289 call setqflist([], 'f')
6290 augroup QF_Test
6291 au!
6292 augroup END
6293 %bw!
6294
6295 augroup QF_Test
6296 au!
6297 au BufEnter test_quickfix.vim caddexpr "4"
6298 augroup END
6299 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6300 call setqflist([], 'f')
6301 augroup QF_Test
6302 au!
6303 augroup END
6304 %bw!
6305endfunc
6306
Bram Moolenaard6c67622022-08-24 20:07:22 +01006307func Test_quickfixtextfunc_recursive()
6308 func s:QFTfunc(o)
6309 cgete '0'
6310 endfunc
6311 copen
6312 let &quickfixtextfunc = 's:QFTfunc'
6313 cex ""
6314
6315 let &quickfixtextfunc = ''
6316 cclose
6317endfunc
6318
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006319" Test for replacing the location list from an autocmd. This used to cause a
6320" read from freed memory.
6321func Test_loclist_replace_autocmd()
6322 %bw!
6323 call setloclist(0, [], 'f')
6324 let s:bufnr = bufnr()
6325 cal setloclist(0, [{'0': 0, '': ''}])
6326 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6327 lopen
6328 try
6329 exe "norm j\<CR>"
6330 catch
6331 endtry
6332 lnext
6333 %bw!
6334 call setloclist(0, [], 'f')
6335endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006336
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006337" vim: shiftwidth=2 sts=2 expandtab