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