blob: fed9dcf8d4905fa39ea5f9b648c91dc1a1722c3d [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Christian Brabandteb380b92025-07-07 20:53:55 +02003import './util/vim9.vim' as v9
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02004CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01005
Christian Brabandteb380b92025-07-07 20:53:55 +02006source util/screendump.vim
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01008set encoding=utf-8
9
Bram Moolenaar2b946c92016-11-12 18:14:44 +010010func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020011 if a:cchar == 'c'
12 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
13 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020014 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020015 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020016 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010017 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020018 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020019 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020020 command! -nargs=* Xclose <mods>cclose <args>
21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
22 command! -nargs=* Xgetfile <mods>cgetfile <args>
23 command! -nargs=* Xaddfile <mods>caddfile <args>
24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
27 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020028 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020030 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
31 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020032 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020033 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020034 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020035 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010036 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020037 command! -nargs=* Xgrep <mods> grep <args>
38 command! -nargs=* Xgrepadd <mods> grepadd <args>
39 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010040 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020041 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
42 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020043 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
44 command! -count=1 -nargs=0 Xafter <mods><count>cafter
64-bitman88d41ab2025-04-06 17:20:39 +020045 command! -nargs=1 Xsethist <mods>set chistory=<args>
46 command! -nargs=0 Xsethistdefault <mods>set chistory&
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020047 let g:Xgetlist = function('getqflist')
48 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020049 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020050 else
51 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
52 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020053 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020054 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020055 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010056 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020057 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020058 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020059 command! -nargs=* Xclose <mods>lclose <args>
60 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
61 command! -nargs=* Xgetfile <mods>lgetfile <args>
62 command! -nargs=* Xaddfile <mods>laddfile <args>
63 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
64 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
65 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
66 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020067 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
68 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020069 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
70 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020071 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020072 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020073 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020074 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010075 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020076 command! -nargs=* Xgrep <mods> lgrep <args>
77 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
78 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010079 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020080 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
81 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020082 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
83 command! -count=1 -nargs=0 Xafter <mods><count>lafter
64-bitman88d41ab2025-04-06 17:20:39 +020084 command! -nargs=1 Xsethist <mods>set lhistory=<args>
85 command! -nargs=1 Xsetlocalhist <mods>setlocal lhistory=<args>
86 command! -nargs=0 Xsethistdefault <mods>set lhistory&
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020087 let g:Xgetlist = function('getloclist', [0])
88 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020089 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020090 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010091endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020092
Bram Moolenaara5d78d12021-12-15 12:28:22 +000093" This must be run before any error lists are created.
94func Test_AA_cc_no_errors()
95 call assert_fails('cc', 'E42:')
96 call assert_fails('ll', 'E42:')
97endfunc
98
Bram Moolenaarda59dd52016-01-05 21:59:58 +010099" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100100func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200101 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200103 if a:cchar == 'l'
104 call assert_fails('llist', 'E776:')
105 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100106 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200107 Xgetexpr []
108 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100109 call assert_true(v:errmsg ==# 'E42: No Errors')
110
111 " Populate the list and then try
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100112 let lines =<< trim END
113 non-error 1
114 Xtestfile1:1:3:Line1
115 non-error 2
116 Xtestfile2:2:2:Line2
117 non-error| 3
118 Xtestfile3:3:1:Line3
119 END
120 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100121
122 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100123 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100124 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
125 \ ' 4 Xtestfile2:2 col 2: Line2',
126 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
127
128 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100129 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100130 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
131 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100132 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100133
134 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100135 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100136 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
137 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
138
Bram Moolenaaree85df32017-03-19 14:19:50 +0100139 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100140 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
141
Bram Moolenaaree85df32017-03-19 14:19:50 +0100142 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100143 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
144
Bram Moolenaaree85df32017-03-19 14:19:50 +0100145 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100146 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
147 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100148
149 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100150 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100151 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
152 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100153
thinca6864efa2021-06-19 20:45:20 +0200154 " Ranged entries
155 call g:Xsetlist([{'lnum':10,'text':'Line1'},
156 \ {'lnum':20,'col':10,'text':'Line2'},
157 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
158 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
159 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
160 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
161 let l = split(execute('Xlist', ""), "\n")
162 call assert_equal([' 1:10: Line1',
163 \ ' 2:20 col 10: Line2',
164 \ ' 3:30 col 15-20: Line3',
165 \ ' 4:40-45: Line4',
166 \ ' 5:50-55 col 15: Line5',
167 \ ' 6:60-65 col 25-35: Line6'], l)
168
Bram Moolenaaree85df32017-03-19 14:19:50 +0100169 " Different types of errors
170 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
171 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
172 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
173 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
Shane Harper5bf04282023-06-07 19:09:57 +0100174 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55},
175 \ {'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 +0100176 let l = split(execute('Xlist', ""), "\n")
177 call assert_equal([' 1:10 col 5 warning 11: Warning',
178 \ ' 2:20 col 10 error 22: Error',
179 \ ' 3:30 col 15 info 33: Info',
180 \ ' 4:40 col 20 x 44: Other',
Shane Harper5bf04282023-06-07 19:09:57 +0100181 \ ' 5:50 col 25 55: one',
182 \ ' 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 +0100183
Bram Moolenaard76ce852018-05-01 15:02:04 +0200184 " Test for module names, one needs to explicitly set `'valid':v:true` so
185 call g:Xsetlist([
186 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
187 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
188 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
189 let l = split(execute('Xlist', ""), "\n")
190 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
191 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
192 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
193
Bram Moolenaar5f30e262022-07-28 11:56:01 +0100194 " Very long line should be displayed.
195 let text = 'Line' .. repeat('1234567890', 130)
196 let lines = ['Xtestfile9:2:9:' .. text]
197 Xgetexpr lines
198
199 let l = split(execute('Xlist', ''), "\n")
200 call assert_equal([' 1 Xtestfile9:2 col 9: ' .. text] , l)
201
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100202 " For help entries in the quickfix list, only the filename without directory
203 " should be displayed
204 Xhelpgrep setqflist()
205 let l = split(execute('Xlist 1', ''), "\n")
206 call assert_match('^ 1 [^\\/]\{-}:', l[0])
207
Bram Moolenaaree85df32017-03-19 14:19:50 +0100208 " Error cases
209 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100210endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100211
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100212func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100213 call XlistTests('c')
214 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100215endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100216
217" Tests for the :colder, :cnewer, :lolder and :lnewer commands
218" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100219" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100220func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200221 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100222
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200223 if a:cchar == 'l'
224 " No location list for the current window
225 call assert_fails('lolder', 'E776:')
226 call assert_fails('lnewer', 'E776:')
227 endif
228
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200229 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200230 call g:Xsetlist(list)
231
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100232 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200233 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100234 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
235
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200236 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
238
239 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200240 Xgetexpr ['Xtestfile1:1:3:Line1']
241 Xgetexpr ['Xtestfile2:2:2:Line2']
242 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100243
244 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200245 Xolder
246 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100247 call assert_equal('Line2', l[0].text)
248
249 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200250 Xnewer
251 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100252 call assert_equal('Line3', l[0].text)
253
254 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200255 Xolder 2
256 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100257 call assert_equal('Line1', l[0].text)
258
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200259 Xnewer 2
260 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100261 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100262endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100263
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100264func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100265 call XageTests('c')
266 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100267endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100268
269" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
270" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100271func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200272 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100273
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200274 " Opening the location list window without any errors should fail
275 if a:cchar == 'l'
276 call assert_fails('lopen', 'E776:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000277 call assert_fails('lwindow', 'E776:')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200278 endif
279
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100280 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200281 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100282
283 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200284 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100285 call assert_true(winnr('$') == 1)
286
287 " Create a list with valid entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100288 let lines =<< trim END
289 Xtestfile1:1:3:Line1
290 Xtestfile2:2:2:Line2
291 Xtestfile3:3:1:Line3
292 END
293 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100294
295 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200296 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100297 call assert_true(winnr('$') == 2 && winnr() == 2 &&
298 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200299 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100300
301 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200302 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100303 call assert_true(winnr('$') == 1)
304
305 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200306 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100307
308 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200309 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100310 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200311 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100312
313 " Opening the window again, should move the cursor to that window
314 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200315 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100316 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200317 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100318 \ getline('.') ==# '|| non-error 1')
319
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100320 " :cnext in quickfix window should move to the next entry
321 Xnext
322 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100323
324 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200325 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100326 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200327
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100328 " Specifying the width should adjust the width for a vertically split
329 " quickfix window.
330 vert Xopen
331 call assert_equal(10, winwidth(0))
332 vert Xopen 12
333 call assert_equal(12, winwidth(0))
334 Xclose
335
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200336 " Horizontally or vertically splitting the quickfix window should create a
337 " normal window/buffer
338 Xopen
339 wincmd s
340 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
341 call assert_equal(0, getwininfo(win_getid())[0].loclist)
342 call assert_notequal('quickfix', &buftype)
343 close
344 Xopen
345 wincmd v
346 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
347 call assert_equal(0, getwininfo(win_getid())[0].loclist)
348 call assert_notequal('quickfix', &buftype)
349 close
350 Xopen
351 Xclose
352
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200353 if a:cchar == 'c'
354 " Opening the quickfix window in multiple tab pages should reuse the
355 " quickfix buffer
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100356 let lines =<< trim END
357 Xtestfile1:1:3:Line1
358 Xtestfile2:2:2:Line2
359 Xtestfile3:3:1:Line3
360 END
361 Xgetexpr lines
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200362 Xopen
363 let qfbufnum = bufnr('%')
364 tabnew
365 Xopen
366 call assert_equal(qfbufnum, bufnr('%'))
367 new | only | tabonly
368 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100369endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100370
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100371func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100372 call XwindowTests('c')
373 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100374endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100375
Bram Moolenaar36d50222019-05-02 20:17:40 +0200376func Test_copenHeight()
377 copen
378 wincmd H
379 let height = winheight(0)
380 copen 10
381 call assert_equal(height, winheight(0))
382 quit
383endfunc
384
Bram Moolenaar1142a312019-10-16 14:51:39 +0200385func Test_copenHeight_tabline()
386 set tabline=foo showtabline=2
387 copen
388 wincmd H
389 let height = winheight(0)
390 copen 10
391 call assert_equal(height, winheight(0))
392 quit
393 set tabline& showtabline&
394endfunc
395
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100396" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
397" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100398func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200399 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100400
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100401 let lines =<< trim END
402 Xtestfile1:700:10:Line 700
403 Xtestfile2:800:15:Line 800
404 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100405 call writefile(lines, 'Xqftestfile1', 'D')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100406
407 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200408 Xfile Xqftestfile1
409 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100410 call assert_true(len(l) == 2 &&
411 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
412 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
413
Bram Moolenaar049cba92016-06-26 14:38:04 +0200414 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200415 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200416
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100417 " Run cfile/lfile from a modified buffer
418 enew!
419 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200420 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100421 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
422
423 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200424 Xaddfile Xqftestfile1
425 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100426 call assert_true(len(l) == 3 &&
427 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
428
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100429 let lines =<< trim END
430 Xtestfile1:222:77:Line 222
431 Xtestfile2:333:88:Line 333
432 END
433 call writefile(lines, 'Xqftestfile1')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434
435 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200436 Xgetfile Xqftestfile1
437 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100438 call assert_true(len(l) == 2 &&
439 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
440 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
441
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100442 " Test for a file with a long line and without a newline at the end
443 let text = repeat('x', 1024)
444 let t = 'a.txt:18:' . text
445 call writefile([t], 'Xqftestfile1', 'b')
446 silent! Xfile Xqftestfile1
447 call assert_equal(text, g:Xgetlist()[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100448endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100449
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100450func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100451 call XfileTests('c')
452 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100453endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100454
455" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
456" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100457func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200458 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100459
460 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100461 let lines =<< trim END
462 Xtestfile7:700:10:Line 700
463 Xtestfile8:800:15:Line 800
464 END
465 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200466 Xbuffer!
467 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100468 call assert_true(len(l) == 2 &&
469 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
470 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
471
472 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100473 let lines =<< trim END
474 Xtestfile9:900:55:Line 900
475 Xtestfile10:950:66:Line 950
476 END
477 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200478 Xgetbuffer
479 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100480 call assert_true(len(l) == 2 &&
481 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
482 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
483
484 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100485 let lines =<< trim END
486 Xtestfile11:700:20:Line 700
487 Xtestfile12:750:25:Line 750
488 END
489 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200490 Xaddbuffer
491 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100492 call assert_true(len(l) == 4 &&
493 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
494 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
495 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200496 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100497
Bram Moolenaaree85df32017-03-19 14:19:50 +0100498 " Check for invalid buffer
499 call assert_fails('Xbuffer 199', 'E474:')
500
501 " Check for unloaded buffer
502 edit Xtestfile1
503 let bnr = bufnr('%')
504 enew!
505 call assert_fails('Xbuffer ' . bnr, 'E681:')
506
507 " Check for invalid range
508 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
509 " commands. So directly call the commands.
510 if (a:cchar == 'c')
511 call assert_fails('900,999cbuffer', 'E16:')
512 else
513 call assert_fails('900,999lbuffer', 'E16:')
514 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100515endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100516
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100517func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100518 call XbufferTests('c')
519 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100520endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100521
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100522func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200523 call s:setup_commands(a:cchar)
524
525 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100526endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200527
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100528func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200529 call XexprTests('c')
530 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100531endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200532
533" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100534func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200535 call s:setup_commands(a:cchar)
536
Bram Moolenaar74240d32017-12-10 15:26:15 +0100537 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200538 " Jumping to first or next location list entry without any error should
539 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100540 if a:cchar == 'c'
541 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100542 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100543 else
544 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100545 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200546 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100547 call assert_fails('Xnext', err)
548 call assert_fails('Xprev', err)
549 call assert_fails('Xnfile', err)
550 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100551 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200552
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100553 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100554 call assert_fails(cmd, 'E42:')
555
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200556 call s:create_test_file('Xqftestfile1')
557 call s:create_test_file('Xqftestfile2')
558
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100559 let lines =<< trim END
560 Xqftestfile1:5:Line5
561 Xqftestfile1:6:Line6
562 Xqftestfile2:10:Line10
563 Xqftestfile2:11:Line11
564 RegularLine1
565 RegularLine2
566 END
567 Xgetexpr lines
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200568
569 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100570 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200571 call assert_fails('Xprev', 'E553:')
572 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200573 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200574 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200575 call assert_equal(10, line('.'))
576 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200577 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200578 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100579 5Xcc
580 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
581 2Xcc
582 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100583 if a:cchar == 'c'
584 cc
585 else
586 ll
587 endif
588 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100589 10Xcc
590 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200591 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200592 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200593 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200594 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200595 call assert_fails('Xnext', 'E553:')
596 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100597 " To process the range using quickfix list entries, directly use the
598 " quickfix commands (don't use the user defined commands)
599 if a:cchar == 'c'
600 $cc
601 else
602 $ll
603 endif
604 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200605 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200606 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200607 call assert_equal(5, line('.'))
608
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200609 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200610 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200611 call assert_equal(11, line('.'))
612 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200613 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200614 call assert_equal(5, line('.'))
615
Bram Moolenaar74240d32017-12-10 15:26:15 +0100616 " Jumping to an error from the error window using cc command
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100617 let lines =<< trim END
618 Xqftestfile1:5:Line5
619 Xqftestfile1:6:Line6
620 Xqftestfile2:10:Line10
621 Xqftestfile2:11:Line11
622 END
623 Xgetexpr lines
Bram Moolenaar74240d32017-12-10 15:26:15 +0100624 Xopen
625 10Xcc
626 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200627 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100628 Xopen
629 call cursor(2, 1)
630 if a:cchar == 'c'
631 .cc
632 else
633 .ll
634 endif
635 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200636 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100637
638 " Jumping to an error from the error window (when only the error window is
639 " present)
640 Xopen | only
641 Xlast 1
642 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200643 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100644
Bram Moolenaaree85df32017-03-19 14:19:50 +0100645 Xexpr ""
646 call assert_fails('Xnext', 'E42:')
647
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200648 call delete('Xqftestfile1')
649 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200650
651 " Should be able to use next/prev with invalid entries
652 Xexpr ""
653 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
654 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100655 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200656 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
657 Xlast
658 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
659 Xfirst
660 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
661 2Xnext
662 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100663endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200664
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100665func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200666 call Xtest_browse('c')
667 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100668endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200669
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000670" Test for memory allocation failures
671func Xnomem_tests(cchar)
672 call s:setup_commands(a:cchar)
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100673
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000674 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
675 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
676
677 call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
678 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100679
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200680 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000681 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100682
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200683 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000684 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100685
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200686 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000687 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100688
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000689 call test_alloc_fail(GetAllocId('qf_efm_fmtstr'), 0, 0)
690 set efm=%f
691 call assert_fails('Xexpr ["Xfile1"]', 'E342:')
692 set efm&
693
694 call test_alloc_fail(GetAllocId('qf_efm_fmtpart'), 0, 0)
695 set efm=%f:%l:%m,%f-%l-%m
696 call assert_fails('Xaddexpr ["Xfile2", "Xfile3"]', 'E342:')
697 set efm&
698
699 call test_alloc_fail(GetAllocId('qf_title'), 0, 0)
700 call assert_fails('Xexpr ""', 'E342:')
701 call assert_equal('', g:Xgetlist({'all': 1}).title)
702
703 call test_alloc_fail(GetAllocId('qf_mef_name'), 0, 0)
704 set makeef=Xtmp##.err
705 call assert_fails('Xgrep needle haystack', 'E342:')
706 set makeef&
707
708 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
709 call assert_fails('Xexpr "Xfile1:10:Line10"', 'E342:')
710
711 if a:cchar == 'l'
712 for id in ['qf_qfline', 'qf_qfinfo']
713 lgetexpr ["Xfile1:10:L10", "Xfile2:20:L20"]
714 call test_alloc_fail(GetAllocId(id), 0, 0)
715 call assert_fails('new', 'E342:')
716 call assert_equal(2, winnr('$'))
717 call assert_equal([], getloclist(0))
718 %bw!
719 endfor
720 endif
721
722 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
723 try
724 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
725 catch /^Vim:Interrupt$/
726 endtry
727
728 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
729 try
730 call assert_fails('Xvimgrep /vim/f runtest.vim', 'E342:')
731 catch /^Vim:Interrupt$/
732 endtry
733
734 let l = getqflist({"lines": ["Xfile1:10:L10"]})
735 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
736 call assert_fails('call g:Xsetlist(l.items)', 'E342:')
737
738 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
739 try
740 call assert_fails('Xhelpgrep quickfix', 'E342:')
741 catch /^Vim:Interrupt$/
742 endtry
743
744 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
745 call assert_fails('let l = g:Xgetlist({"lines": ["Xfile1:10:L10"]})', 'E342:')
746 call assert_equal(#{items: []}, l)
747
748 if a:cchar == 'l'
749 call setqflist([], 'f')
750 call setloclist(0, [], 'f')
751 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
752 call assert_fails('lhelpgrep quickfix', 'E342:')
753 call assert_equal([], getloclist(0))
754
755 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
756 call assert_fails('lvimgrep vim runtest.vim', 'E342:')
757
758 let l = getqflist({"lines": ["Xfile1:10:L10"]})
759 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
760 call assert_fails('call setloclist(0, l.items)', 'E342:')
761
762 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
763 call assert_fails('lbuffer', 'E342:')
764
765 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
766 call assert_fails('lexpr ["Xfile1:10:L10", "Xfile2:20:L20"]', 'E342:')
767
768 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
769 call assert_fails('lfile runtest.vim', 'E342:')
770 endif
771
772 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
773 set efm=%DEntering\ dir\ %f,%f:%l:%m
774 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E342:')
775 set efm&
776
777 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
778 set efm=%+P[%f],(%l)%m
779 call assert_fails('Xexpr ["[runtest.vim]", "(1)Hello"]', 'E342:')
780 set efm&
781
782 call test_alloc_fail(GetAllocId('qf_multiline_pfx'), 0, 0)
783 set efm=%EError,%Cline\ %l,%Z%m
784 call assert_fails('Xexpr ["Error", "line 1", "msg"]', 'E342:')
785 set efm&
786
787 call test_alloc_fail(GetAllocId('qf_makecmd'), 0, 0)
788 call assert_fails('Xgrep vim runtest.vim', 'E342:')
789
790 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
791 call assert_fails('Xexpr repeat("a", 8192)', 'E342:')
792
793 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
794 call assert_fails('Xexpr [repeat("a", 8192)]', 'E342:')
795
796 new
797 call setline(1, repeat('a', 8192))
798 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
799 call assert_fails('Xbuffer', 'E342:')
800 %bw!
801
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100802 call writefile([repeat('a', 8192)], 'Xtest', 'D')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000803 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
804 call assert_fails('Xfile Xtest', 'E342:')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000805endfunc
806
807func Test_nomem()
808 call Xnomem_tests('c')
809 call Xnomem_tests('l')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100810endfunc
811
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100812func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200813 call s:setup_commands(a:cchar)
814 Xhelpgrep quickfix
815 Xopen
816 if a:cchar == 'c'
817 let title_text = ':helpgrep quickfix'
818 else
819 let title_text = ':lhelpgrep quickfix'
820 endif
821 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200822
823 " Jumping to a help topic should open the help window
824 only
825 Xnext
826 call assert_true(&buftype == 'help')
827 call assert_true(winnr('$') == 2)
828 " Jumping to the next match should reuse the help window
829 Xnext
830 call assert_true(&buftype == 'help')
831 call assert_true(winnr() == 1)
832 call assert_true(winnr('$') == 2)
833 " Jumping to the next match from the quickfix window should reuse the help
834 " window
835 Xopen
836 Xnext
837 call assert_true(&buftype == 'help')
838 call assert_true(winnr() == 1)
839 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200840 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200841
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100842 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200843 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100844
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100845 " When the current window is vertically split, jumping to a help match
846 " should open the help window at the top.
847 only | enew
848 let w1 = win_getid()
849 vert new
850 let w2 = win_getid()
851 Xnext
852 let w3 = win_getid()
853 call assert_true(&buftype == 'help')
854 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100855 " See jump_to_help_window() for details
856 let w2_width = winwidth(w2)
857 if w2_width != &columns && w2_width < 80
858 call assert_equal(['col', [['leaf', w3],
859 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
860 else
861 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
862 \ ['leaf', w1]]] , winlayout())
863 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100864
865 new | only
866 set buftype=help
867 set modified
868 call assert_fails('Xnext', 'E37:')
869 set nomodified
870 new | only
871
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200872 if a:cchar == 'l'
873 " When a help window is present, running :lhelpgrep should reuse the
874 " help window and not the current window
875 new | only
876 call g:Xsetlist([], 'f')
877 help index.txt
878 wincmd w
879 lhelpgrep quickfix
880 call assert_equal(1, winnr())
881 call assert_notequal([], getloclist(1))
882 call assert_equal([], getloclist(2))
883 endif
884
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200885 new | only
886
Bram Moolenaaree85df32017-03-19 14:19:50 +0100887 " Search for non existing help string
888 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200889 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200890 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100891endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200892
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100893func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200894 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200895 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200896 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100897endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100898
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100899def Test_helpgrep_vim9_restore_cpo()
Christian Brabandt22105fd2024-07-15 20:51:11 +0200900 assert_equal('aABceFsz', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100901
902 var rtp_save = &rtp
903 var dir = 'Xruntime/after'
904 &rtp ..= ',' .. dir
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100905 mkdir(dir .. '/ftplugin', 'pR')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100906 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100907 filetype plugin on
908 silent helpgrep grail
909 cwindow
910 silent helpgrep grail
911
Christian Brabandt22105fd2024-07-15 20:51:11 +0200912 assert_equal('aABceFsz', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100913 &rtp = rtp_save
914 cclose
915 helpclose
916enddef
917
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000918" When running the :helpgrep command, if an autocmd modifies the 'cpoptions'
919" value, then Vim crashes. (issue fixed by 7.2b-004 and 8.2.4453)
Bram Moolenaar4791fcd2022-02-23 12:06:00 +0000920func Test_helpgrep_restore_cpo_aucmd()
921 let save_cpo = &cpo
922 augroup QF_Test
923 au!
924 autocmd BufNew * set cpo=acd
925 augroup END
926
927 helpgrep quickfix
928 call assert_equal('acd', &cpo)
929 %bw!
930
931 set cpo&vim
932 augroup QF_Test
933 au!
934 autocmd BufReadPost * set cpo=
935 augroup END
936
937 helpgrep buffer
938 call assert_equal('', &cpo)
939
940 augroup QF_Test
941 au!
942 augroup END
943 %bw!
944 let &cpo = save_cpo
945endfunc
946
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200947def Test_vim9_cexpr()
948 var text = 'somefile:95:error'
949 cexpr text
950 var l = getqflist()
951 assert_equal(1, l->len())
952 assert_equal(95, l[0].lnum)
953 assert_equal('error', l[0].text)
954
955 text = 'somefile:77:warning'
956 caddexpr text
957 l = getqflist()
958 assert_equal(2, l->len())
959 assert_equal(77, l[1].lnum)
960 assert_equal('warning', l[1].text)
961enddef
962
Bram Moolenaar6920c722016-01-22 22:44:10 +0100963func Test_errortitle()
964 augroup QfBufWinEnter
965 au!
966 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
967 augroup END
968 copen
969 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'')'}]
970 call setqflist(a)
971 call assert_equal(':setqflist()', g:a)
972 augroup QfBufWinEnter
973 au!
974 augroup END
975 augroup! QfBufWinEnter
976endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100977
Bram Moolenaar5584df62016-03-18 21:00:51 +0100978func Test_vimgreptitle()
979 augroup QfBufWinEnter
980 au!
981 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
982 augroup END
983 try
984 vimgrep /pattern/j file
985 catch /E480/
986 endtry
987 copen
988 call assert_equal(': vimgrep /pattern/j file', g:a)
989 augroup QfBufWinEnter
990 au!
991 augroup END
992 augroup! QfBufWinEnter
993endfunc
994
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100995func Test_bufwinenter_once()
996 augroup QfBufWinEnter
997 au!
998 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
999 augroup END
1000 let g:got_afile = ''
1001 copen
1002 call assert_equal('got quickfix', g:got_afile)
1003
1004 cclose
1005 unlet g:got_afile
1006 augroup QfBufWinEnter
1007 au!
1008 augroup END
1009 augroup! QfBufWinEnter
1010endfunc
1011
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001012func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001013 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +01001014
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001015 Xgetexpr ['file:1:1:message']
1016 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001017 if a:cchar == 'c'
1018 call setqflist(l, 'r')
1019 else
1020 call setloclist(0, l, 'r')
1021 endif
1022
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001023 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +01001024 if a:cchar == 'c'
1025 let title = ':setqflist()'
1026 else
1027 let title = ':setloclist()'
1028 endif
1029 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001030 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001031endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001032
1033" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001034func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001035 call XqfTitleTests('c')
1036 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001037endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001038
1039" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001040func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001041 let save_efm = &efm
1042 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
1043 cgetexpr ['WWWW', 'EEEE', 'CCCC']
1044 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1045 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1046 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
1047 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1048 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1049 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
1050 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1051 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
1052 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001053endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001054
1055" This will test for problems in quickfix:
1056" A. incorrectly copying location lists which caused the location list to show
1057" a different name than the file that was actually being displayed.
1058" B. not reusing the window for which the location list window is opened but
1059" instead creating new windows.
1060" C. make sure that the location list window is not reused instead of the
1061" window it belongs to.
1062"
1063" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001064func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001065 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
1066 let word = substitute(base, '\v(.*)\..*', '\1', '')
1067
1068 setl modifiable
1069 setl noreadonly
1070 setl noswapfile
1071 setl bufhidden=delete
1072 %del _
1073 " For problem 2:
1074 " 'buftype' has to be set to reproduce the constant opening of new windows
1075 setl buftype=nofile
1076
1077 call setline(1, word)
1078
1079 setl nomodified
1080 setl nomodifiable
1081 setl readonly
1082 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001083endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001084
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001085func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001086 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001087
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001088 augroup testgroup
1089 au!
1090 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
1091 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001092
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001093 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001094
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001095 let qflist = []
1096 for word in words
1097 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
1098 " NOTE: problem 1:
1099 " intentionally not setting 'lnum' so that the quickfix entries are not
1100 " valid
1101 eval qflist->setloclist(0, ' ')
1102 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001103
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001104 " Test A
1105 lrewind
1106 enew
1107 lopen
1108 4lnext
1109 vert split
1110 wincmd L
1111 lopen
1112 wincmd p
1113 lnext
1114 let fileName = expand("%")
1115 wincmd p
1116 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
1117 let fileName = substitute(fileName, '\\', '/', 'g')
1118 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
1119 call assert_equal("test://bar.txt", fileName)
1120 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001121
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001122 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001123
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001124 " Test B:
1125 lrewind
1126 lopen
1127 2
1128 exe "normal \<CR>"
1129 wincmd p
1130 3
1131 exe "normal \<CR>"
1132 wincmd p
1133 4
1134 exe "normal \<CR>"
1135 call assert_equal(2, winnr('$'))
1136 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001137
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001138 " Test C:
1139 lrewind
1140 lopen
1141 " Let's move the location list window to the top to check whether it (the
1142 " first window found) will be reused when we try to open new windows:
1143 wincmd K
1144 2
1145 exe "normal \<CR>"
1146 wincmd p
1147 3
1148 exe "normal \<CR>"
1149 wincmd p
1150 4
1151 exe "normal \<CR>"
1152 1wincmd w
1153 call assert_equal('quickfix', &buftype)
1154 2wincmd w
1155 let bufferName = expand("%")
1156 let bufferName = substitute(bufferName, '\\', '/', 'g')
1157 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001158
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001159 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001160
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001161 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +01001162endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001163
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001164func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001165 augroup testgroup
1166 au!
1167 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
1168 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +01001169
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001170 func! R(n)
1171 quit
1172 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001173
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001174 new
1175 let q = []
1176 call add(q, {'filename': 'test_curwin.txt' })
1177 call setloclist(0, q)
1178 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001179
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001180 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001181 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001182endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001183
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001184func Test_locationlist_cross_tab_jump()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001185 call writefile(['loclistfoo'], 'loclistfoo', 'D')
1186 call writefile(['loclistbar'], 'loclistbar', 'D')
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001187 set switchbuf=usetab
1188
1189 edit loclistfoo
1190 tabedit loclistbar
1191 silent lgrep loclistfoo loclist*
1192 call assert_equal(1, tabpagenr())
1193
1194 enew | only | tabonly
1195 set switchbuf&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001196endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001197
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001198" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001199func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001200 " The 'errorformat' setting is different on non-Unix systems.
1201 " This test works only on Unix-like systems.
1202 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001203
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001204 let l =<< trim [DATA]
1205 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1206 "Xtestfile", line 6 col 19; this is an error
1207 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1208 Xtestfile:9: parse error before `asd'
Gregory Andersd1911a82023-06-05 21:52:46 +01001209 make: *** [src/vim/testdir/Makefile:100: test_quickfix] Error 1
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001210 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001211
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001212 2 returned
1213 "Xtestfile", line 11 col 1; this is an error
1214 "Xtestfile", line 12 col 2; this is another error
1215 "Xtestfile", line 14:10; this is an error in column 10
1216 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1217 "Xtestfile", linenr 16: yet another problem
1218 Error in "Xtestfile" at line 17:
1219 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001220 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001221 ^
1222 Error in "Xtestfile" at line 18:
1223 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001224 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001225 .............^
1226 Error in "Xtestfile" at line 19:
1227 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001228 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001229 --------------^
1230 Error in "Xtestfile" at line 20:
1231 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001232 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1233 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001234
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001235 Does anyone know what is the problem and how to correction it?
1236 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1237 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1238 [DATA]
1239
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001240 call writefile(l, 'Xerrorfile1', 'D')
1241 call delete('loclistbar')
1242 call writefile(l[:-2], 'Xerrorfile2', 'D')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001243
1244 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001245 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1246 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1247 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1248 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1249 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1250 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1251 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1252 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1253 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1254 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1255 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1256 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1257 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1258 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1259 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1260 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1261 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1262 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1263 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1264 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1265 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1266[DATA]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001267 call writefile(m, 'Xtestfile', 'D')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001268
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001269 let save_efm = &efm
1270 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1271 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001272
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001273 exe 'cf Xerrorfile2'
1274 clast
1275 copen
1276 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1277 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001278
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001279 exe 'cf Xerrorfile1'
1280 call assert_equal([4, 12], [line('.'), col('.')])
1281 cn
1282 call assert_equal([6, 19], [line('.'), col('.')])
1283 cn
1284 call assert_equal([9, 2], [line('.'), col('.')])
1285 cn
1286 call assert_equal([10, 2], [line('.'), col('.')])
1287 cn
1288 call assert_equal([11, 1], [line('.'), col('.')])
1289 cn
1290 call assert_equal([12, 2], [line('.'), col('.')])
1291 cn
1292 call assert_equal([14, 10], [line('.'), col('.')])
1293 cn
1294 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1295 cn
1296 call assert_equal([16, 2], [line('.'), col('.')])
1297 cn
1298 call assert_equal([17, 6], [line('.'), col('.')])
1299 cn
1300 call assert_equal([18, 7], [line('.'), col('.')])
1301 cn
1302 call assert_equal([19, 8], [line('.'), col('.')])
1303 cn
1304 call assert_equal([20, 9], [line('.'), col('.')])
1305 clast
1306 cprev
1307 cprev
1308 wincmd w
1309 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1310 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001311
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001312 let &efm = save_efm
Bram Moolenaaree85df32017-03-19 14:19:50 +01001313endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001314
Bram Moolenaarab47c612016-06-14 22:02:26 +02001315" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001316func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001317 call s:setup_commands(a:cchar)
1318
Bram Moolenaarab47c612016-06-14 22:02:26 +02001319 let save_efm=&efm
1320 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1321
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001322 let lines =<< trim END
1323 Entering dir 'dir1/a'
1324 habits2.txt:1:Nine Healthy Habits
1325 Entering dir 'b'
1326 habits3.txt:2:0 Hours of television
1327 habits2.txt:7:5 Small meals
1328 Entering dir 'dir1/c'
1329 habits4.txt:3:1 Hour of exercise
1330 Leaving dir 'dir1/c'
1331 Leaving dir 'dir1/a'
1332 habits1.txt:4:2 Liters of water
1333 Entering dir 'dir2'
1334 habits5.txt:5:3 Cups of hot green tea
1335 Leaving dir 'dir2'
1336 END
Bram Moolenaarab47c612016-06-14 22:02:26 +02001337
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001338 Xexpr ""
1339 for l in lines
1340 Xaddexpr l
1341 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001342
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001343 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001344
1345 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1346 call assert_equal(1, qf[1].lnum)
1347 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1348 call assert_equal(2, qf[3].lnum)
1349 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1350 call assert_equal(7, qf[4].lnum)
1351 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1352 call assert_equal(3, qf[6].lnum)
1353 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1354 call assert_equal(4, qf[9].lnum)
1355 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1356 call assert_equal(5, qf[11].lnum)
1357
1358 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001359endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001360
1361" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001362func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001363 " Create the directory stack and files
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001364 call mkdir('dir1', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001365 call mkdir('dir1/a')
1366 call mkdir('dir1/a/b')
1367 call mkdir('dir1/c')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001368 call mkdir('dir2', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001369
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001370 let lines =<< trim END
1371 Nine Healthy Habits
1372 0 Hours of television
1373 1 Hour of exercise
1374 2 Liters of water
1375 3 Cups of hot green tea
1376 4 Short mental breaks
1377 5 Small meals
1378 6 AM wake up time
1379 7 Minutes of laughter
1380 8 Hours of sleep (at least)
1381 9 PM end of the day and off to bed
1382 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001383 call writefile(lines, 'habits1.txt', 'D')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001384 call writefile(lines, 'dir1/a/habits2.txt')
1385 call writefile(lines, 'dir1/a/b/habits3.txt')
1386 call writefile(lines, 'dir1/c/habits4.txt')
1387 call writefile(lines, 'dir2/habits5.txt')
1388
1389 call s:dir_stack_tests('c')
1390 call s:dir_stack_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001391endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001392
Bram Moolenaar9b457942016-10-09 16:10:05 +02001393" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001394func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001395 call s:setup_commands(a:cchar)
1396
1397 let save_efm = &efm
1398
1399 let &efm =
1400 \ '%Eerror %m %l,' .
1401 \ '%-Wignored %m %l,' .
1402 \ '%+Cmore ignored %m %l,' .
1403 \ '%Zignored end'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001404 let lines =<< trim END
1405 ignored warning 1
1406 more ignored continuation 2
1407 ignored end
1408 error resync 4
1409 END
1410 Xgetexpr lines
Bram Moolenaar9b457942016-10-09 16:10:05 +02001411 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1412 call assert_equal([['resync', 1, 4, 'E']], l)
1413
1414 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001415endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001416
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001417func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001418 call Xefm_ignore_continuations('c')
1419 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001420endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001421
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001422" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001423func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001424 call s:setup_commands(a:cchar)
1425
Bram Moolenaar049cba92016-06-26 14:38:04 +02001426 let save_efm = &efm
1427
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001428 set efm=%f:%l:%m,%f:%f:%l:%m
1429 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1430
1431 set efm=%f:%l:%m,%f:%l:%r:%m
1432 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1433
1434 set efm=%f:%l:%m,%O:%f:%l:%m
1435 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1436
1437 set efm=%f:%l:%m,%f:%l:%*[^a-z
1438 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1439
1440 set efm=%f:%l:%m,%f:%l:%*c
1441 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1442
1443 set efm=%f:%l:%m,%L%M%N
1444 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1445
1446 set efm=%f:%l:%m,%f:%l:%m:%R
1447 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1448
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001449 " Invalid regular expression
1450 set efm=%\\%%k
1451 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1452
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001453 set efm=
1454 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1455
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001456 " Empty directory name. When there is an error in parsing new entries, make
1457 " sure the previous quickfix list is made the current list.
1458 set efm&
1459 cexpr ["one", "two"]
1460 let qf_id = getqflist(#{id: 0}).id
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001461 set efm=%DEntering\ dir\ abc,%f:%l:%m
1462 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001463 call assert_equal(qf_id, getqflist(#{id: 0}).id)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001464
1465 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001466endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001467
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001468func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001469 call Xinvalid_efm_Tests('c')
1470 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001471endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001472
1473" TODO:
1474" Add tests for the following formats in 'errorformat'
1475" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001476func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001477 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001478
1479 " Test for %s format in efm
1480 set efm=%f:%s
1481 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001482 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001483 call assert_equal('^\VLine search text\$', l[0].pattern)
1484 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001485
Bram Moolenaaree85df32017-03-19 14:19:50 +01001486 let l = split(execute('clist', ''), "\n")
1487 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1488
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001489 " Test for a long line
1490 cexpr 'Xtestfile:' . repeat('a', 1026)
1491 let l = getqflist()
1492 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1493
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001494 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001495 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001496 [Xtestfile1]
1497 (1,17) error: ';' missing
1498 (21,2) warning: variable 'z' not defined
1499 (67,3) error: end of file found before string ended
1500 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001501
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001502 [Xtestfile2]
1503 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001504
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001505 [Xtestfile3]
1506 NEW compiler v1.1
1507 (2,2) warning: variable 'x' not defined
1508 (67,3) warning: 's' already defined
1509 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001510 [DATA]
1511
Bram Moolenaaree85df32017-03-19 14:19:50 +01001512 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001513 " To exercise the push/pop file functionality in quickfix, the test files
1514 " need to be created.
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001515 call writefile(['Line1'], 'Xtestfile1', 'D')
1516 call writefile(['Line2'], 'Xtestfile2', 'D')
1517 call writefile(['Line3'], 'Xtestfile3', 'D')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001518 cexpr ""
1519 for l in lines
1520 caddexpr l
1521 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001522 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001523 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001524 call assert_equal(21, l[2].lnum)
1525 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001526 call assert_equal('w', l[2].type)
1527 call assert_equal('e', l[3].type)
1528
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001529 " Test for %P, %Q with non-existing files
1530 cexpr lines
1531 let l = getqflist()
1532 call assert_equal(14, len(l))
1533 call assert_equal('[Xtestfile1]', l[0].text)
1534 call assert_equal('[Xtestfile2]', l[6].text)
1535 call assert_equal('[Xtestfile3]', l[9].text)
1536
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001537 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001538 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001539 Error 275
1540 line 42
1541 column 3
1542 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001543 [DATA]
1544
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001545 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1546 cgetexpr lines
1547 let l = getqflist()
1548 call assert_equal(275, l[0].nr)
1549 call assert_equal(42, l[0].lnum)
1550 call assert_equal(3, l[0].col)
1551 call assert_equal('E', l[0].type)
1552 call assert_equal("\n' ' expected after '--'", l[0].text)
1553
1554 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001555 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001556 Error in line 147 of foo.c:
1557 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001558 [DATA]
1559
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001560 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1561 cgetexpr lines
1562 let l = getqflist()
1563 call assert_equal(147, l[0].lnum)
1564 call assert_equal('E', l[0].type)
1565 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001566
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001567 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001568 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001569 ==============================================================
1570 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1571 --------------------------------------------------------------
1572 Traceback (most recent call last):
1573 File "unittests/dbfacadeTest.py", line 89, in testFoo
1574 self.assertEquals(34, dtid)
1575 File "/usr/lib/python2.2/unittest.py", line 286, in
1576 failUnlessEqual
1577 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001578 W:AssertionError: 34 != 33
Bram Moolenaar94722c52023-01-28 19:19:03 +00001579
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001580 --------------------------------------------------------------
1581 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001582 [DATA]
1583
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001584 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001585 cgetexpr lines
1586 let l = getqflist()
1587 call assert_equal(8, len(l))
1588 call assert_equal(89, l[4].lnum)
1589 call assert_equal(1, l[4].valid)
1590 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001591 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001592
Bram Moolenaard76ce852018-05-01 15:02:04 +02001593 " Test for %o
1594 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001595 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001596 call writefile(['Line1'], 'Xotestfile', 'D')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001597 let l = getqflist()
1598 call assert_equal(1, len(l), string(l))
1599 call assert_equal('Language.PureScript.Types', l[0].module)
1600 copen
1601 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1602 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001603 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001604 cclose
1605 bd
Bram Moolenaard76ce852018-05-01 15:02:04 +02001606
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001607 " Test for a long module name
1608 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1609 let l = getqflist()
1610 call assert_equal(repeat('m', 1024), l[0].module)
1611 call assert_equal(15, l[0].lnum)
1612 call assert_equal('message', l[0].text)
1613
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001614 " The following sequence of commands used to crash Vim
1615 set efm=%W%m
1616 cgetexpr ['msg1']
1617 let l = getqflist()
1618 call assert_equal(1, len(l), string(l))
1619 call assert_equal('msg1', l[0].text)
1620 set efm=%C%m
1621 lexpr 'msg2'
1622 let l = getloclist(0)
1623 call assert_equal(1, len(l), string(l))
1624 call assert_equal('msg2', l[0].text)
1625 lopen
1626 call setqflist([], 'r')
1627 caddbuf
1628 let l = getqflist()
1629 call assert_equal(1, len(l), string(l))
1630 call assert_equal('|| msg2', l[0].text)
1631
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001632 " When matching error lines, case should be ignored. Test for this.
1633 set noignorecase
1634 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1635 call assert_equal(10, l.items[0].lnum)
1636 call assert_equal('Line 20', l.items[0].text)
1637 set ignorecase&
1638
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001639 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001640 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001641endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001642
Bram Moolenaare9283662020-06-07 14:10:47 +02001643" Test for '%t' (error type) field in 'efm'
1644func Test_efm_error_type()
1645 let save_efm = &efm
1646
1647 " error type
1648 set efm=%f:%l:%t:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001649 let lines =<< trim END
1650 Xfile1:10:E:msg1
1651 Xfile1:20:W:msg2
1652 Xfile1:30:I:msg3
1653 Xfile1:40:N:msg4
1654 Xfile1:50:R:msg5
1655 END
1656 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001657 let output = split(execute('clist'), "\n")
1658 call assert_equal([
1659 \ ' 1 Xfile1:10 error: msg1',
1660 \ ' 2 Xfile1:20 warning: msg2',
1661 \ ' 3 Xfile1:30 info: msg3',
1662 \ ' 4 Xfile1:40 note: msg4',
1663 \ ' 5 Xfile1:50 R: msg5'], output)
1664
1665 " error type and a error number
1666 set efm=%f:%l:%t:%n:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001667 let lines =<< trim END
1668 Xfile1:10:E:2:msg1
1669 Xfile1:20:W:4:msg2
1670 Xfile1:30:I:6:msg3
1671 Xfile1:40:N:8:msg4
1672 Xfile1:50:R:3:msg5
1673 END
1674 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001675 let output = split(execute('clist'), "\n")
1676 call assert_equal([
1677 \ ' 1 Xfile1:10 error 2: msg1',
1678 \ ' 2 Xfile1:20 warning 4: msg2',
1679 \ ' 3 Xfile1:30 info 6: msg3',
1680 \ ' 4 Xfile1:40 note 8: msg4',
1681 \ ' 5 Xfile1:50 R 3: msg5'], output)
1682 let &efm = save_efm
1683endfunc
1684
haya14busae023d492022-02-08 18:09:29 +00001685" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1686func Test_efm_end_lnum_col()
1687 let save_efm = &efm
1688
1689 " single line
1690 set efm=%f:%l-%e:%c-%k:%t:%m
1691 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1692 let output = split(execute('clist'), "\n")
1693 call assert_equal([
1694 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1695 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1696
1697 " multiple lines
1698 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001699 let lines =<< trim END
1700 1)msg1
1701 Xfile1:14-24:1-2
1702 2)msg2
1703 Xfile1:24-34:3-4
1704 END
1705 cexpr lines
haya14busae023d492022-02-08 18:09:29 +00001706 let output = split(execute('clist'), "\n")
1707 call assert_equal([
1708 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1709 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1710 let &efm = save_efm
1711endfunc
1712
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001713func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001714 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001715 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001716 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001717 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001718 colder
1719 cgetexpr []
1720 endfunc
1721 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001722 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001723 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001724 lolder
1725 lgetexpr []
1726 endfunc
1727 endif
1728
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001729 augroup QF_Test
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001730 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001731 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001732 augroup END
1733
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001734 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001735 let words = [ "a", "b" ]
1736 let qflist = []
1737 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001738 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001740 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001741 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001742
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001743 augroup QF_Test
1744 au!
1745 augroup END
1746
1747 if a:cchar == 'c'
1748 cexpr ["Xtest1:1:Line"]
1749 cwindow
1750 only
1751 augroup QF_Test
1752 au!
1753 autocmd WinEnter * call setqflist([], 'f')
1754 augroup END
1755 call assert_fails('exe "normal \<CR>"', 'E925:')
1756 augroup QF_Test
1757 au!
1758 augroup END
1759 endif
1760 %bw!
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001761endfunc
1762
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001763func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001764 call XquickfixChangedByAutocmd('c')
1765 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001766endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001767
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001768func Test_setloclist_in_autocommand()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001769 call writefile(['test1', 'test2'], 'Xfile', 'D')
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001770 edit Xfile
1771 let s:bufnr = bufnr()
1772 call setloclist(1,
1773 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1774 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1775
1776 augroup Test_LocList
1777 au!
1778 autocmd BufEnter * call setloclist(1,
1779 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1780 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1781 augroup END
1782
1783 lopen
1784 call assert_fails('exe "normal j\<CR>"', 'E926:')
1785
1786 augroup Test_LocList
1787 au!
1788 augroup END
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001789endfunc
1790
Bram Moolenaar8b201792016-03-25 15:01:10 +01001791func Test_caddbuffer_to_empty()
1792 helpgr quickfix
1793 call setqflist([], 'r')
1794 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001795 try
1796 cn
1797 catch
1798 " number of matches is unknown
1799 call assert_true(v:exception =~ 'E553:')
1800 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001801 quit!
1802endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001803
1804func Test_cgetexpr_works()
1805 " this must not crash Vim
1806 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001807 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001808endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001809
1810" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001811func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001812 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001813
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001814 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Tom Praschanca6ac992023-08-11 23:26:12 +02001815 \ {'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 +02001816 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001817 call assert_equal(2, len(l))
1818 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001819 call assert_equal(3, l[1].end_lnum)
1820 call assert_equal(4, l[1].col)
1821 call assert_equal(5, l[1].end_col)
Tom Praschanca6ac992023-08-11 23:26:12 +02001822 call assert_equal({'6': [7, 8]}, l[1].user_data)
1823
1824 " Test that user_data is garbage collected
1825 call g:Xsetlist([{'user_data': ['high', 5]},
1826 \ {'user_data': {'this': [7, 'eight'], 'is': ['a', 'dictionary']}}])
1827 call test_garbagecollect_now()
1828 let l = g:Xgetlist()
1829 call assert_equal(2, len(l))
1830 call assert_equal(['high', 5], l[0].user_data)
1831 call assert_equal({'this': [7, 'eight'], 'is': ['a', 'dictionary']}, l[1].user_data)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001832
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 Xnext
1834 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1835 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001836 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001837 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001838 call assert_equal(3, line('.'))
1839
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001840 " Appending entries to the list should not change the cursor position
1841 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001842 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001843 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001844 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001845 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1846 call assert_equal(1, line('.'))
1847 close
1848
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001849 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001850 \ {'bufnr': a:bnum, 'lnum': 4},
1851 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001852 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001853 call assert_equal(3, len(l))
1854 call assert_equal(5, l[2].lnum)
1855
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001856 call g:Xsetlist([])
1857 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001858 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001859
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001860 " Tests for setting the 'valid' flag
1861 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1862 Xwindow
1863 call assert_equal(1, winnr('$'))
1864 let l = g:Xgetlist()
1865 call g:Xsetlist(l)
1866 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001867 " Adding a non-valid entry should not mark the list as having valid entries
1868 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1869 Xwindow
1870 call assert_equal(1, winnr('$'))
1871
1872 " :cnext/:cprev should still work even with invalid entries in the list
1873 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1874 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1875 call g:Xsetlist(l)
1876 Xnext
1877 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1878 Xprev
1879 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1880 " :cnext/:cprev should still work after appending invalid entries to an
1881 " empty list
1882 call g:Xsetlist([])
1883 call g:Xsetlist(l, 'a')
1884 Xnext
1885 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1886 Xprev
1887 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1888
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001889 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1890 Xwindow
1891 call assert_equal(2, winnr('$'))
1892 Xclose
1893 let save_efm = &efm
1894 set efm=%m
1895 Xgetexpr 'TestMessage'
1896 let l = g:Xgetlist()
1897 call g:Xsetlist(l)
1898 call assert_equal(1, g:Xgetlist()[0].valid)
1899 let &efm = save_efm
1900
Bram Moolenaaree85df32017-03-19 14:19:50 +01001901 " Error cases:
1902 " Refer to a non-existing buffer and pass a non-dictionary type
1903 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1904 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1905 call g:Xsetlist([[1, 2,3]])
1906 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001907 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001908 call g:Xsetlist([test_null_dict()])
1909 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001910endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001911
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001912func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001913 new Xtestfile | only
1914 let bnum = bufnr('%')
1915 call setline(1, range(1,5))
1916
1917 call SetXlistTests('c', bnum)
1918 call SetXlistTests('l', bnum)
1919
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001920 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001921 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001922endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001923
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001924func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001925 call s:setup_commands(a:cchar)
1926
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001927 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001928 let @/ = 'Test_'
1929 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001930 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001931 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001932 Xvimgrep empty test_quickfix.vim
1933 call assert_true(len(g:Xgetlist()) > 0)
1934 Xvimgrep matches test_quickfix.vim
1935 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001936 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001937 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001938 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001939 call g:Xsetlist([], 'r')
1940 call assert_true(len(g:Xgetlist()) == 0)
1941 Xolder
1942 call assert_equal(testlen, len(g:Xgetlist()))
1943 Xnewer
1944 Xnewer
1945 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001946endfunc
1947
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001948func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001949 call Xlist_empty_middle('c')
1950 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001951endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001952
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001953func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001954 call s:setup_commands(a:cchar)
1955
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001956 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001957 Xvimgrep one test_quickfix.vim
1958 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001959 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001960 Xvimgrep two test_quickfix.vim
1961 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001962 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001963 Xvimgrep three test_quickfix.vim
1964 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001965 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001966 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001967 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001968 call g:Xsetlist([], 'r')
1969 call assert_true(len(g:Xgetlist()) == 0)
1970 Xnewer
1971 call assert_equal(twolen, len(g:Xgetlist()))
1972 Xnewer
1973 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001974endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001975
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001976func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001977 call Xlist_empty_older('c')
1978 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001979endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001980
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001981func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001982 call s:setup_commands(a:cchar)
1983
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001984 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1985 \ {'filename': 'fnameB', 'text': 'B'}]
1986 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1987 \ {'filename': 'fnameD', 'text': 'D'},
1988 \ {'filename': 'fnameE', 'text': 'E'}]
1989
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001990 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001991 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001992 silent! Xnewer 99
1993 call g:Xsetlist(list1)
1994 call g:Xsetlist(list2)
1995 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001996 call assert_equal(3, len(li))
1997 call assert_equal('C', li[0]['text'])
1998 call assert_equal('D', li[1]['text'])
1999 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002000 silent! Xolder
2001 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002002 call assert_equal(2, len(li))
2003 call assert_equal('A', li[0]['text'])
2004 call assert_equal('B', li[1]['text'])
2005
2006 " {action} is specified ' '.
2007 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002008 silent! Xnewer 99
2009 call g:Xsetlist(list1)
2010 call g:Xsetlist(list2, ' ')
2011 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002012 call assert_equal(3, len(li))
2013 call assert_equal('C', li[0]['text'])
2014 call assert_equal('D', li[1]['text'])
2015 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002016 silent! Xolder
2017 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002018 call assert_equal(2, len(li))
2019 call assert_equal('A', li[0]['text'])
2020 call assert_equal('B', li[1]['text'])
2021
2022 " {action} is specified 'a'.
2023 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002024 silent! Xnewer 99
2025 call g:Xsetlist(list1)
2026 call g:Xsetlist(list2, 'a')
2027 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002028 call assert_equal(5, len(li))
2029 call assert_equal('A', li[0]['text'])
2030 call assert_equal('B', li[1]['text'])
2031 call assert_equal('C', li[2]['text'])
2032 call assert_equal('D', li[3]['text'])
2033 call assert_equal('E', li[4]['text'])
2034
2035 " {action} is specified 'r'.
2036 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002037 silent! Xnewer 99
2038 call g:Xsetlist(list1)
2039 call g:Xsetlist(list2, 'r')
2040 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002041 call assert_equal(3, len(li))
2042 call assert_equal('C', li[0]['text'])
2043 call assert_equal('D', li[1]['text'])
2044 call assert_equal('E', li[2]['text'])
2045
2046 " Test for wrong value.
2047 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002048 call assert_fails("call g:Xsetlist(0)", 'E714:')
2049 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
2050 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
2051 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
2052 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002053endfunc
2054
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002055func Test_setqflist_invalid_nr()
2056 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02002057 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002058endfunc
2059
Bram Moolenaar99234f22020-02-10 22:56:54 +01002060func Test_setqflist_user_sets_buftype()
2061 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
2062 set buftype=quickfix
2063 call setqflist([], 'a')
2064 enew
2065endfunc
2066
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002067func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002068 call XquickfixSetListWithAct('c')
2069 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002070endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002071
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002072func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002073 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002074
Bram Moolenaar049cba92016-06-26 14:38:04 +02002075 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002076 call assert_equal(1, l[0].lnum)
2077 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002078 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002079 call assert_equal(2, l[1].lnum)
2080 call assert_equal(1, l[1].col)
2081 call assert_equal(4070, len(l[1].text))
2082 call assert_equal(3, l[2].lnum)
2083 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002084 call assert_equal(4070, len(l[2].text))
2085 call assert_equal(4, l[3].lnum)
2086 call assert_equal(1, l[3].col)
2087 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002088
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002089 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002090endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002091
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002092func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002093 call s:setup_commands(a:cchar)
2094
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002095 let testfile = 'samples/quickfix.txt'
2096
2097 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002098 exe 'Xgetfile' testfile
2099 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002100
2101 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002102 Xexpr readfile(testfile)
2103 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002104
2105 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002106 Xexpr join(readfile(testfile), "\n")
2107 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002108
2109 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002110 exe 'edit' testfile
2111 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02002112 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002113endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002114
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002115func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002116 call s:long_lines_tests('c')
2117 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002118endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002119
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002120func Test_cgetfile_on_long_lines()
2121 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
2122 " are read at a time.
2123 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002124 let lines =<< trim END
2125 /tmp/file1:1:1:aaa
2126 /tmp/file2:1:1:%s
2127 /tmp/file3:1:1:bbb
2128 /tmp/file4:1:1:ccc
2129 END
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002130 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002131 call writefile(lines, 'Xcqetfile.txt', 'D')
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002132 cgetfile Xcqetfile.txt
2133 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
2134 endfor
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002135endfunc
2136
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002137func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002138 let l = []
2139 for i in range(1, 20)
2140 call add(l, 'Line' . i)
2141 endfor
2142 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002143endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002144
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002145func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002146 call s:create_test_file('Xqftestfile1')
2147 call s:create_test_file('Xqftestfile2')
2148 call s:create_test_file('Xqftestfile3')
2149
2150 new | only
2151 edit Xqftestfile1
2152 let file1_winid = win_getid()
2153 new Xqftestfile2
2154 let file2_winid = win_getid()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002155 let lines =<< trim END
2156 Xqftestfile1:5:Line5
2157 Xqftestfile1:6:Line6
2158 Xqftestfile2:10:Line10
2159 Xqftestfile2:11:Line11
2160 Xqftestfile3:15:Line15
2161 Xqftestfile3:16:Line16
2162 END
2163 cgetexpr lines
Bram Moolenaar049cba92016-06-26 14:38:04 +02002164
2165 new
2166 let winid = win_getid()
2167 cfirst | cnext
2168 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002169 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002170 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002171 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002172 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002173
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002174 " Test for 'switchbuf' set to search for files in windows in the current
2175 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002176 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002177 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02002178 cfirst | cnext
2179 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002180 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002181 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002182 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002183 call assert_equal(file2_winid, win_getid())
2184
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002185 " Test for 'switchbuf' set to search for files in tabpages and jump to an
2186 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002187 enew | only
2188 set switchbuf=usetab
2189 tabedit Xqftestfile1
2190 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01002191 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02002192 tabfirst
2193 cfirst | cnext
2194 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002195 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002196 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002197 6cnext
2198 call assert_equal(4, tabpagenr())
2199 2cpfile
2200 call assert_equal(2, tabpagenr())
2201 2cnfile
2202 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002203 tabfirst | tabonly | enew
2204
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002205 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002206 set switchbuf=split
2207 cfirst | cnext
2208 call assert_equal(1, winnr('$'))
2209 cnext | cnext
2210 call assert_equal(2, winnr('$'))
2211 cnext | cnext
2212 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002213
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002214 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002215 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002216 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002217 cfirst | cnext
2218 call assert_equal(1, tabpagenr('$'))
2219 cnext | cnext
2220 call assert_equal(2, tabpagenr('$'))
2221 cnext | cnext
2222 call assert_equal(3, tabpagenr('$'))
2223 tabfirst | enew | tabonly | only
2224
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002225 set switchbuf=uselast
2226 split
2227 let last_winid = win_getid()
2228 copen
2229 exe "normal 1G\<CR>"
2230 call assert_equal(last_winid, win_getid())
2231 enew | only
2232
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002233 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2234 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002235 set switchbuf=
2236 edit Xqftestfile1
2237 let file1_winid = win_getid()
2238 new Xqftestfile2
2239 let file2_winid = win_getid()
2240 copen
2241 exe "normal 1G\<CR>"
2242 call assert_equal(file1_winid, win_getid())
2243 copen
2244 exe "normal 3G\<CR>"
2245 call assert_equal(file2_winid, win_getid())
2246 copen | only
2247 exe "normal 5G\<CR>"
2248 call assert_equal(2, winnr('$'))
2249 call assert_equal(1, bufwinnr('Xqftestfile3'))
2250
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002251 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002252 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002253 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002254 set switchbuf=usetab
2255 tabedit Xqftestfile1
2256 tabedit Xqftestfile2
2257 tabedit Xqftestfile3
2258 tabfirst
2259 copen | only
2260 clast
2261 call assert_equal(4, tabpagenr())
2262 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002263
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002264 " Jumping to a file that is not present in any of the tabpages and the
2265 " current tabpage doesn't have any usable windows, should open it in a new
2266 " window in the current tabpage.
2267 copen | only
2268 cfirst
2269 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002270 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002271
2272 " If opening a file changes 'switchbuf', then the new value should be
2273 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002274 set modeline&vim
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002275 call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002276 enew | only
2277 set switchbuf&vim
2278 cexpr "Xqftestfile1:1:10"
2279 call assert_equal('split', &switchbuf)
2280 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2281 enew | only
2282 set switchbuf=useopen
2283 cexpr "Xqftestfile1:1:10"
2284 call assert_equal('usetab', &switchbuf)
2285 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2286 enew | only
2287 set switchbuf=useopen
2288 cexpr "Xqftestfile1:1:10"
2289 call assert_equal('', &switchbuf)
2290
Bram Moolenaar049cba92016-06-26 14:38:04 +02002291 call delete('Xqftestfile2')
2292 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002293 set switchbuf&vim
2294
2295 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002296endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002297
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002298func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002299 call s:setup_commands(a:cchar)
2300
2301 enew | only
2302
Bram Moolenaarc1542742016-07-20 21:44:37 +02002303 let fname = 'Xqftestfile' . a:cchar
2304 call s:create_test_file(fname)
2305 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002306
Bram Moolenaarc1542742016-07-20 21:44:37 +02002307 Xgetexpr [fname . ':5:Line5',
2308 \ fname . ':10:Line10',
2309 \ fname . ':15:Line15',
2310 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002311
2312 6,14delete
2313 call append(6, ['Buffer', 'Window'])
2314
2315 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002316 call assert_equal(5, l[0].lnum)
2317 call assert_equal(6, l[2].lnum)
2318 call assert_equal(13, l[3].lnum)
2319
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002320 " If a file doesn't have any quickfix entries, then deleting lines in the
2321 " file should not update the quickfix list
2322 call g:Xsetlist([], 'f')
2323 1,2delete
2324 call assert_equal([], g:Xgetlist())
2325
Bram Moolenaar049cba92016-06-26 14:38:04 +02002326 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002327 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002328endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002329
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002330func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002331 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002332 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002333 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002334 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002335endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002336
2337" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002338func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002339 call s:setup_commands(a:cchar)
2340
2341 " The following lines are used for the grep test. Don't remove.
2342 " Grep_Test_Text: Match 1
2343 " Grep_Test_Text: Match 2
2344 " GrepAdd_Test_Text: Match 1
2345 " GrepAdd_Test_Text: Match 2
2346 enew! | only
2347 set makeef&vim
2348 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002349 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002350 Xopen
2351 call assert_true(w:quickfix_title =~ '^:grep')
2352 Xclose
2353 enew
2354 set makeef=Temp_File_##
2355 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002356 call assert_true(len(g:Xgetlist()) == 9)
2357
2358 " Try with 'grepprg' set to 'internal'
2359 set grepprg=internal
2360 silent Xgrep Grep_Test_Text: test_quickfix.vim
2361 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2362 call assert_true(len(g:Xgetlist()) == 9)
2363 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002364
2365 call writefile(['Vim'], 'XtestTempFile')
2366 set makeef=XtestTempFile
2367 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002368 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002369 call assert_false(filereadable('XtestTempFile'))
2370 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002371endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002372
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002373func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002374 " The grepprg may not be set on non-Unix systems
2375 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002376
2377 call s:test_xgrep('c')
2378 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002379endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002380
glepnir7b9eb632025-05-16 19:49:23 +02002381func Test_local_grepformat()
2382 let save_grepformat = &grepformat
2383 set grepformat=%f:%l:%m
2384 " The following line are used for the local grep test. Don't remove.
2385 " UNIQUEPREFIX:2:3: Local grepformat test
2386 new
2387 setlocal grepformat=UNIQUEPREFIX:%c:%n:%m
2388 call assert_equal('UNIQUEPREFIX:%c:%n:%m', &l:grepformat)
2389 call assert_equal('%f:%l:%m', &g:grepformat)
2390
2391 set grepprg=internal
2392 silent grep "^[[:space:]]*\" UNIQUEPREFIX:" test_quickfix.vim
2393 call assert_equal(1, len(getqflist()))
2394 set grepprg&vim
2395
2396 bwipe!
2397 let &grepformat = save_grepformat
2398endfunc
2399
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002400func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002401 " Use one 'errorformat' for two windows. Add an expression to each of them,
2402 " make sure they each keep their own state.
2403 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002404 call mkdir('Xone/a', 'pR')
2405 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002406 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2407 call writefile(lines, 'Xone/a/one.txt')
2408 call writefile(lines, 'Xtwo/a/two.txt')
2409
2410 new one
2411 let one_id = win_getid()
2412 lexpr ""
2413 new two
2414 let two_id = win_getid()
2415 lexpr ""
2416
2417 laddexpr "Entering dir 'Xtwo/a'"
2418 call win_gotoid(one_id)
2419 laddexpr "Entering dir 'Xone/a'"
2420 call win_gotoid(two_id)
2421 laddexpr 'two.txt:5:two two two'
2422 call win_gotoid(one_id)
2423 laddexpr 'one.txt:3:one one one'
2424
2425 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002426 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2427 call assert_equal(3, loc_one[1].lnum)
2428
2429 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002430 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2431 call assert_equal(5, loc_two[1].lnum)
2432
2433 call win_gotoid(one_id)
2434 bwipe!
2435 call win_gotoid(two_id)
2436 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002437endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002438
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002439func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002440 call s:setup_commands(a:cchar)
2441
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002442 " Calling lbottom without any errors should fail
2443 if a:cchar == 'l'
2444 call assert_fails('lbottom', 'E776:')
2445 endif
2446
Bram Moolenaar875feea2017-06-11 16:07:51 +02002447 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002448 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002449 let wid = win_getid()
2450 call assert_equal(1, line('.'))
2451 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002452 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002453 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002454 call win_gotoid(wid)
2455 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002456 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002457endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002458
2459" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002460func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002461 call XbottomTests('c')
2462 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002463endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002464
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002465func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002466 call s:setup_commands(a:cchar)
2467
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002468 " clear all lists after the first one, then replace the first one.
2469 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002470 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002471 let entry = {'filename': 'foo', 'lnum': 42}
2472 call g:Xsetlist([entry], 'r')
2473 call g:Xsetlist([entry, entry])
2474 call g:Xsetlist([entry, entry, entry])
2475 let res = split(execute(a:cchar . 'hist'), "\n")
2476 call assert_equal(3, len(res))
2477 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2478 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2479 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2480 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002481
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002482 " Test for changing the quickfix lists
2483 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2484 exe '1' . a:cchar . 'hist'
2485 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2486 exe '3' . a:cchar . 'hist'
2487 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2488 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2489 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2490
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002491 call g:Xsetlist([], 'f')
2492 let l = split(execute(a:cchar . 'hist'), "\n")
2493 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002494 if a:cchar == 'c'
2495 call assert_fails('4chist', 'E16:')
2496 else
2497 call assert_fails('4lhist', 'E776:')
2498 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002499
2500 " An empty list should still show the stack history
2501 call g:Xsetlist([])
2502 let res = split(execute(a:cchar . 'hist'), "\n")
2503 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2504
2505 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002506endfunc
2507
2508func Test_history()
2509 call HistoryTest('c')
2510 call HistoryTest('l')
2511endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002512
2513func Test_duplicate_buf()
2514 " make sure we can get the highest buffer number
2515 edit DoesNotExist
2516 edit DoesNotExist2
2517 let last_buffer = bufnr("$")
2518
2519 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002520 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002521 vimgrep one Xgrepthis
2522 vimgrep one Xgrepthis
2523 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002524endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002525
2526" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002527func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002528 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002529
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002530 " Error cases
2531 call assert_fails('call g:Xgetlist(99)', 'E715:')
2532 call assert_fails('call g:Xsetlist(99)', 'E714:')
2533 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002534
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002535 " Set and get the title
2536 call g:Xsetlist([])
2537 Xopen
2538 wincmd p
2539 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2540 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2541 call assert_equal(0, s)
2542 let d = g:Xgetlist({"title":1})
2543 call assert_equal('Sample', d.title)
2544 " Try setting title to a non-string value
2545 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2546 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2547
2548 Xopen
2549 call assert_equal('Sample', w:quickfix_title)
2550 Xclose
2551
2552 " Tests for action argument
2553 silent! Xolder 999
2554 let qfnr = g:Xgetlist({'all':1}).nr
2555 call g:Xsetlist([], 'r', {'title' : 'N1'})
2556 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2557 call g:Xsetlist([], ' ', {'title' : 'N2'})
2558 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2559
2560 let res = g:Xgetlist({'nr': 0})
2561 call assert_equal(qfnr + 1, res.nr)
2562 call assert_equal(['nr'], keys(res))
2563
2564 call g:Xsetlist([], ' ', {'title' : 'N3'})
2565 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2566
2567 " Changing the title of an earlier quickfix list
2568 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2569 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2570
2571 " Changing the title of an invalid quickfix list
2572 call assert_equal(-1, g:Xsetlist([], ' ',
2573 \ {'title' : 'SomeTitle', 'nr' : 99}))
2574 call assert_equal(-1, g:Xsetlist([], ' ',
2575 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2576
2577 if a:cchar == 'c'
2578 copen
2579 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2580 cclose
2581 endif
2582
2583 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002584 call assert_fails('call g:Xgetlist([])', 'E715:')
2585 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002586 let s = g:Xsetlist([], 'a', {'abc':1})
2587 call assert_equal(-1, s)
2588
2589 call assert_equal({}, g:Xgetlist({'abc':1}))
2590 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2591 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2592
2593 if a:cchar == 'l'
2594 call assert_equal({}, getloclist(99, {'title': 1}))
2595 endif
2596
2597 " Context related tests
2598 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2599 call assert_equal(0, s)
2600 call test_garbagecollect_now()
2601 let d = g:Xgetlist({'context':1})
2602 call assert_equal([1,2,3], d.context)
2603 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2604 let d = g:Xgetlist({'context':1})
2605 call assert_equal({'color':'green'}, d.context)
2606 call g:Xsetlist([], 'a', {'context':"Context info"})
2607 let d = g:Xgetlist({'context':1})
2608 call assert_equal("Context info", d.context)
2609 call g:Xsetlist([], 'a', {'context':246})
2610 let d = g:Xgetlist({'context':1})
2611 call assert_equal(246, d.context)
2612 " set other Vim data types as context
2613 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2614 if has('channel')
2615 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2616 endif
2617 if has('job')
2618 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2619 endif
2620 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2621 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2622 call g:Xsetlist([], 'a', {'context' : ''})
2623 call test_garbagecollect_now()
2624 if a:cchar == 'l'
2625 " Test for copying context across two different location lists
2626 new | only
2627 let w1_id = win_getid()
2628 let l = [1]
2629 call setloclist(0, [], 'a', {'context':l})
2630 new
2631 let w2_id = win_getid()
2632 call add(l, 2)
2633 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2634 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2635 unlet! l
2636 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2637 only
2638 call setloclist(0, [], 'f')
2639 call assert_equal('', getloclist(0, {'context':1}).context)
2640 endif
2641
2642 " Test for changing the context of previous quickfix lists
2643 call g:Xsetlist([], 'f')
2644 Xexpr "One"
2645 Xexpr "Two"
2646 Xexpr "Three"
2647 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2648 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2649 " Also, check for setting the context using quickfix list number zero.
2650 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2651 call test_garbagecollect_now()
2652 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2653 call assert_equal([1], l.context)
2654 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2655 call assert_equal([2], l.context)
2656 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2657 call assert_equal([3], l.context)
2658
2659 " Test for changing the context through reference and for garbage
2660 " collection of quickfix context
2661 let l = ["red"]
2662 call g:Xsetlist([], ' ', {'context' : l})
2663 call add(l, "blue")
2664 let x = g:Xgetlist({'context' : 1})
2665 call add(x.context, "green")
2666 call assert_equal(["red", "blue", "green"], l)
2667 call assert_equal(["red", "blue", "green"], x.context)
2668 unlet l
2669 call test_garbagecollect_now()
2670 let m = g:Xgetlist({'context' : 1})
2671 call assert_equal(["red", "blue", "green"], m.context)
2672
2673 " Test for setting/getting items
2674 Xexpr ""
2675 let qfprev = g:Xgetlist({'nr':0})
2676 let s = g:Xsetlist([], ' ', {'title':'Green',
2677 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2678 call assert_equal(0, s)
2679 let qfcur = g:Xgetlist({'nr':0})
2680 call assert_true(qfcur.nr == qfprev.nr + 1)
2681 let l = g:Xgetlist({'items':1})
2682 call assert_equal('F1', bufname(l.items[0].bufnr))
2683 call assert_equal(10, l.items[0].lnum)
2684 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2685 \ {'filename':'F2', 'lnum':30}]})
2686 let l = g:Xgetlist({'items':1})
2687 call assert_equal('F2', bufname(l.items[2].bufnr))
2688 call assert_equal(30, l.items[2].lnum)
2689 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2690 let l = g:Xgetlist({'items':1})
2691 call assert_equal('F3', bufname(l.items[0].bufnr))
2692 call assert_equal(40, l.items[0].lnum)
2693 call g:Xsetlist([], 'r', {'items' : []})
2694 let l = g:Xgetlist({'items':1})
2695 call assert_equal(0, len(l.items))
2696
2697 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2698 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2699 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2700 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2701
2702 " Test for getting id of window associated with a location list window
2703 if a:cchar == 'l'
2704 only
2705 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2706 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002707 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002708 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2709 wincmd w
2710 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2711 only
2712 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002713
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002714 " The following used to crash Vim with address sanitizer
2715 call g:Xsetlist([], 'f')
2716 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2717 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002718
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002719 " Try setting the items using a string
2720 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002721
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002722 " Save and restore the quickfix stack
2723 call g:Xsetlist([], 'f')
2724 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2725 Xexpr "File1:10:Line1"
2726 Xexpr "File2:20:Line2"
2727 Xexpr "File3:30:Line3"
2728 let last_qf = g:Xgetlist({'nr':'$'}).nr
2729 call assert_equal(3, last_qf)
2730 let qstack = []
2731 for i in range(1, last_qf)
2732 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2733 endfor
2734 call g:Xsetlist([], 'f')
2735 for i in range(len(qstack))
2736 call g:Xsetlist([], ' ', qstack[i])
2737 endfor
2738 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2739 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2740 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2741 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2742 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002743
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002744 " Swap two quickfix lists
2745 Xexpr "File1:10:Line10"
2746 Xexpr "File2:20:Line20"
2747 Xexpr "File3:30:Line30"
2748 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2749 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2750 let l1=g:Xgetlist({'nr':1,'all':1})
2751 let l2=g:Xgetlist({'nr':2,'all':1})
2752 let save_id = l1.id
2753 let l1.id=l2.id
2754 let l2.id=save_id
2755 call g:Xsetlist([], 'r', l1)
2756 call g:Xsetlist([], 'r', l2)
2757 let newl1=g:Xgetlist({'nr':1,'all':1})
2758 let newl2=g:Xgetlist({'nr':2,'all':1})
2759 call assert_equal('Fruits', newl1.title)
2760 call assert_equal(['Fruits'], newl1.context)
2761 call assert_equal('Line20', newl1.items[0].text)
2762 call assert_equal('Colors', newl2.title)
2763 call assert_equal(['Colors'], newl2.context)
2764 call assert_equal('Line10', newl2.items[0].text)
2765 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002766
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002767 " Cannot specify both a non-empty list argument and a dict argument
2768 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002769endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002770
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002771func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002772 call Xproperty_tests('c')
2773 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002774endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002775
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002776" Test for setting the current index in the location/quickfix list
2777func Xtest_setqfidx(cchar)
2778 call s:setup_commands(a:cchar)
2779
2780 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2781 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2782 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2783
2784 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2785 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2786 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2787 Xolder 2
2788 Xopen
2789 call assert_equal(3, line('.'))
2790 Xnewer
2791 call assert_equal(2, line('.'))
2792 Xnewer
2793 call assert_equal(2, line('.'))
2794 " Update the current index with the quickfix window open
2795 wincmd w
2796 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2797 Xopen
2798 call assert_equal(3, line('.'))
2799 Xclose
2800
2801 " Set the current index to the last entry
2802 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2803 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2804 " A large value should set the index to the last index
2805 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2806 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2807 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2808 " Invalid index values
2809 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2810 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2811 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2812 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2813 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2814 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2815 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2816
2817 call g:Xsetlist([], 'f')
2818 new | only
2819endfunc
2820
2821func Test_setqfidx()
2822 call Xtest_setqfidx('c')
2823 call Xtest_setqfidx('l')
2824endfunc
2825
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002826" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002827func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002828 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002829endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002830
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002831func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002832 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2833 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2834
2835 let g:acmds = []
2836 cexpr "F1:10:Line 10"
2837 caddexpr "F1:20:Line 20"
2838 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002839 cexpr ""
2840 caddexpr ""
2841 cgetexpr ""
2842 silent! cexpr non_existing_func()
2843 silent! caddexpr non_existing_func()
2844 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002845 let l =<< trim END
2846 precexpr
2847 postcexpr
2848 precaddexpr
2849 postcaddexpr
2850 precgetexpr
2851 postcgetexpr
2852 precexpr
2853 postcexpr
2854 precaddexpr
2855 postcaddexpr
2856 precgetexpr
2857 postcgetexpr
2858 precexpr
2859 precaddexpr
2860 precgetexpr
2861 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002862 call assert_equal(l, g:acmds)
2863
2864 let g:acmds = []
2865 enew! | call append(0, "F2:10:Line 10")
2866 cbuffer!
2867 enew! | call append(0, "F2:20:Line 20")
2868 cgetbuffer
2869 enew! | call append(0, "F2:30:Line 30")
2870 caddbuffer
2871 new
2872 let bnum = bufnr('%')
2873 bunload
2874 exe 'silent! cbuffer! ' . bnum
2875 exe 'silent! cgetbuffer ' . bnum
2876 exe 'silent! caddbuffer ' . bnum
2877 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002878 let l =<< trim END
2879 precbuffer
2880 postcbuffer
2881 precgetbuffer
2882 postcgetbuffer
2883 precaddbuffer
2884 postcaddbuffer
2885 precbuffer
2886 precgetbuffer
2887 precaddbuffer
2888 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002889 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002890
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002891 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2892 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002893 let g:acmds = []
2894 cfile Xtest
2895 caddfile Xtest
2896 cgetfile Xtest
2897 cfile Xempty
2898 caddfile Xempty
2899 cgetfile Xempty
2900 silent! cfile do_not_exist
2901 silent! caddfile do_not_exist
2902 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002903 let l =<< trim END
2904 precfile
2905 postcfile
2906 precaddfile
2907 postcaddfile
2908 precgetfile
2909 postcgetfile
2910 precfile
2911 postcfile
2912 precaddfile
2913 postcaddfile
2914 precgetfile
2915 postcgetfile
2916 precfile
2917 postcfile
2918 precaddfile
2919 postcaddfile
2920 precgetfile
2921 postcgetfile
2922 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002923 call assert_equal(l, g:acmds)
2924
2925 let g:acmds = []
2926 helpgrep quickfix
2927 silent! helpgrep non_existing_help_topic
2928 vimgrep test Xtest
2929 vimgrepadd test Xtest
2930 silent! vimgrep non_existing_test Xtest
2931 silent! vimgrepadd non_existing_test Xtest
2932 set makeprg=
2933 silent! make
2934 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002935 let l =<< trim END
2936 prehelpgrep
2937 posthelpgrep
2938 prehelpgrep
2939 posthelpgrep
2940 previmgrep
2941 postvimgrep
2942 previmgrepadd
2943 postvimgrepadd
2944 previmgrep
2945 postvimgrep
2946 previmgrepadd
2947 postvimgrepadd
2948 premake
2949 postmake
2950 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002951 call assert_equal(l, g:acmds)
2952
2953 if has('unix')
2954 " Run this test only on Unix-like systems. The grepprg may not be set on
2955 " non-Unix systems.
2956 " The following lines are used for the grep test. Don't remove.
2957 " Grep_Autocmd_Text: Match 1
2958 " GrepAdd_Autocmd_Text: Match 2
2959 let g:acmds = []
2960 silent grep Grep_Autocmd_Text test_quickfix.vim
2961 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2962 silent grep abc123def Xtest
2963 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002964 set grepprg=internal
2965 silent grep Grep_Autocmd_Text test_quickfix.vim
2966 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2967 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2968 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2969 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002970 let l =<< trim END
2971 pregrep
2972 postgrep
2973 pregrepadd
2974 postgrepadd
2975 pregrep
2976 postgrep
2977 pregrepadd
2978 postgrepadd
2979 pregrep
2980 postgrep
2981 pregrepadd
2982 postgrepadd
2983 prelgrep
2984 postlgrep
2985 prelgrepadd
2986 postlgrepadd
2987 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002988 call assert_equal(l, g:acmds)
2989 endif
2990
Bram Moolenaarb254af32017-12-18 19:48:58 +01002991 au! QuickFixCmdPre
2992 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002993endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002994
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002995func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002996 set efm=%m
2997 lgetexpr '?'
2998
2999 try
3000 call DoesNotExit()
3001 catch
3002 lgetexpr '1'
3003 finally
3004 lgetexpr '1'
3005 endtry
3006
3007 call assert_equal('1', getloclist(0)[0].text)
3008
3009 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003010endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003011
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003012func Test_caddbuffer_wrong()
3013 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003014 let save_efm = &efm
3015 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
3016 cgetexpr ['WWWW', 'EEEE', 'CCCC']
3017 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003018 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003019 bwipe!
3020endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003021
3022func Test_caddexpr_wrong()
3023 " This used to cause a memory access in freed memory.
3024 cbuffer
3025 cbuffer
3026 copen
3027 let save_efm = &efm
3028 set efm=%
3029 call assert_fails('caddexpr ""', 'E376:')
3030 let &efm = save_efm
3031endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01003032
3033func Test_dirstack_cleanup()
3034 " This used to cause a memory access in freed memory.
3035 let save_efm = &efm
3036 lexpr '0'
3037 lopen
3038 fun X(c)
3039 let save_efm=&efm
3040 set efm=%D%f
3041 if a:c == 'c'
3042 caddexpr '::'
3043 else
3044 laddexpr ':0:0'
3045 endif
3046 let &efm=save_efm
3047 endfun
3048 call X('c')
3049 call X('l')
3050 call setqflist([], 'r')
3051 caddbuffer
3052 let &efm = save_efm
3053endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003054
3055" Tests for jumping to entries from the location list window and quickfix
3056" window
3057func Test_cwindow_jump()
3058 set efm=%f%%%l%%%m
3059 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3060 lopen | only
3061 lfirst
3062 call assert_true(winnr('$') == 2)
3063 call assert_true(winnr() == 1)
3064 " Location list for the new window should be set
3065 call assert_true(getloclist(0)[2].text == 'Line 30')
3066
3067 " Open a scratch buffer
3068 " Open a new window and create a location list
3069 " Open the location list window and close the other window
3070 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003071 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003072 " should not be used.
3073 enew | only
3074 set buftype=nofile
3075 below new
3076 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3077 lopen
3078 2wincmd c
3079 lnext
3080 call assert_true(winnr('$') == 3)
3081 call assert_true(winnr() == 2)
3082
3083 " Open two windows with two different location lists
3084 " Open the location list window and close the previous window
3085 " Jump to an entry in the location list window
3086 " Should open the file in the first window and not set the location list.
3087 enew | only
3088 lgetexpr ["F1%5%Line 5"]
3089 below new
3090 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3091 lopen
3092 2wincmd c
3093 lnext
3094 call assert_true(winnr() == 1)
3095 call assert_true(getloclist(0)[0].text == 'Line 5')
3096
3097 enew | only
3098 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3099 copen
3100 cnext
3101 call assert_true(winnr('$') == 2)
3102 call assert_true(winnr() == 1)
3103
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003104 " open the quickfix buffer in two windows and jump to an entry. Should open
3105 " the file in the first quickfix window.
3106 enew | only
3107 copen
3108 let bnum = bufnr('')
3109 exe 'sbuffer ' . bnum
3110 wincmd b
3111 cfirst
3112 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003113 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003114 enew | only
3115 exe 'sb' bnum
3116 exe 'botright sb' bnum
3117 wincmd t
3118 clast
3119 call assert_equal(2, winnr())
3120 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3121 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3122
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003123 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003124 " window by wrapping around the window list.
3125 enew | only
3126 call setloclist(0, [], 'f')
3127 new | new
3128 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3129 lopen
3130 1close
3131 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3132 lnext
3133 call assert_equal(3, winnr())
3134 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3135
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003136 enew | only
3137 set efm&vim
3138endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003139
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003140func Test_cwindow_highlight()
3141 CheckScreendump
3142
3143 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003144 call setline(1, ['some', 'text', 'with', 'matches'])
3145 write XCwindow
3146 vimgrep e XCwindow
3147 redraw
3148 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003149 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003150 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003151 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3152 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3153
3154 call term_sendkeys(buf, ":cnext\<CR>")
3155 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3156
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003157 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003158 call term_sendkeys(buf, ":\<CR>")
3159 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3160
3161 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3162 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003163 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3164
3165 call term_sendkeys(buf, "j")
3166 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3167
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003168 " clean up
3169 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003170 call delete('XCwindow')
3171endfunc
3172
Bram Moolenaaree85df32017-03-19 14:19:50 +01003173func XvimgrepTests(cchar)
3174 call s:setup_commands(a:cchar)
3175
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003176 let lines =<< trim END
3177 Editor:VIM vim
3178 Editor:Emacs EmAcS
3179 Editor:Notepad NOTEPAD
3180 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003181 call writefile(lines, 'Xtestfile1', 'D')
3182 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003183
3184 " Error cases
3185 call assert_fails('Xvimgrep /abc *', 'E682:')
3186
3187 let @/=''
3188 call assert_fails('Xvimgrep // *', 'E35:')
3189
3190 call assert_fails('Xvimgrep abc', 'E683:')
3191 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3192 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3193
3194 Xexpr ""
3195 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003196 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003197 let l = g:Xgetlist()
3198 call assert_equal(2, len(l))
3199 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3200
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003201 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003202 let l = g:Xgetlist()
3203 call assert_equal(2, len(l))
3204 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003205 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003206 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003207 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003208
3209 1Xvimgrep ?Editor? Xtestfile*
3210 let l = g:Xgetlist()
3211 call assert_equal(1, len(l))
3212 call assert_equal('Editor:VIM vim', l[0].text)
3213
3214 edit +3 Xtestfile2
3215 Xvimgrep +\cemacs+j Xtestfile1
3216 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003217 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003218 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3219
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003220 " Test for unloading a buffer after vimgrep searched the buffer
3221 %bwipe
3222 Xvimgrep /Editor/j Xtestfile*
3223 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3224 call assert_equal([], getbufinfo('Xtestfile2'))
3225
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003226 " Test for opening the dummy buffer used by vimgrep in a window. The new
3227 " window should be closed
3228 %bw!
3229 augroup QF_Test
3230 au!
3231 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3232 augroup END
3233 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3234 call assert_equal(1, winnr('$'))
3235 augroup QF_Test
3236 au!
3237 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003238endfunc
3239
3240" Tests for the :vimgrep command
3241func Test_vimgrep()
3242 call XvimgrepTests('c')
3243 call XvimgrepTests('l')
3244endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003245
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003246func Test_vimgrep_wildcards_expanded_once()
3247 new X[id-01] file.txt
3248 call setline(1, 'some text to search for')
3249 vimgrep text %
3250 bwipe!
3251endfunc
3252
Bram Moolenaar1c299432018-10-28 14:36:09 +01003253" Test for incsearch highlighting of the :vimgrep pattern
3254" This test used to cause "E315: ml_get: invalid lnum" errors.
3255func Test_vimgrep_incsearch()
3256 enew
3257 set incsearch
3258 call test_override("char_avail", 1)
3259
3260 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3261 let l = getqflist()
3262 call assert_equal(2, len(l))
3263
3264 call test_override("ALL", 0)
3265 set noincsearch
3266endfunc
3267
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003268" Test vimgrep with the last search pattern not set
3269func Test_vimgrep_with_no_last_search_pat()
3270 let lines =<< trim [SCRIPT]
3271 call assert_fails('vimgrep // *', 'E35:')
3272 call writefile(v:errors, 'Xresult')
3273 qall!
3274 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003275 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003276 if RunVim([], [], '--clean -S Xscript')
3277 call assert_equal([], readfile('Xresult'))
3278 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003279 call delete('Xresult')
3280endfunc
3281
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003282" Test vimgrep without swap file
3283func Test_vimgrep_without_swap_file()
3284 let lines =<< trim [SCRIPT]
3285 vimgrep grep test_c*
3286 call writefile(['done'], 'Xresult')
3287 qall!
3288 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003289 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003290 if RunVim([], [], '--clean -n -S Xscript Xscript')
3291 call assert_equal(['done'], readfile('Xresult'))
3292 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003293 call delete('Xresult')
3294endfunc
3295
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003296func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003297 call writefile(['match apple with apple'], 'Xapple', 'D')
3298 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003299 let g:foundSwap = 0
3300 let g:ignoreSwapExists = 1
3301 augroup grep
3302 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3303 augroup END
3304 vimgrep apple Xapple
3305 call assert_equal(1, g:foundSwap)
3306 call assert_match('.Xapple.swo', swapname(''))
3307
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003308 augroup grep
3309 au! SwapExists
3310 augroup END
3311 unlet g:ignoreSwapExists
3312endfunc
3313
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003314func XfreeTests(cchar)
3315 call s:setup_commands(a:cchar)
3316
3317 enew | only
3318
3319 " Deleting the quickfix stack should work even When the current list is
3320 " somewhere in the middle of the stack
3321 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3322 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3323 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3324 Xolder
3325 call g:Xsetlist([], 'f')
3326 call assert_equal(0, len(g:Xgetlist()))
3327
3328 " After deleting the stack, adding a new list should create a stack with a
3329 " single list.
3330 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3331 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3332
3333 " Deleting the stack from a quickfix window should update/clear the
3334 " quickfix/location list window.
3335 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3336 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3337 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3338 Xolder
3339 Xwindow
3340 call g:Xsetlist([], 'f')
3341 call assert_equal(2, winnr('$'))
3342 call assert_equal(1, line('$'))
3343 Xclose
3344
3345 " Deleting the stack from a non-quickfix window should update/clear the
3346 " quickfix/location list window.
3347 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3348 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3349 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3350 Xolder
3351 Xwindow
3352 wincmd p
3353 call g:Xsetlist([], 'f')
3354 call assert_equal(0, len(g:Xgetlist()))
3355 wincmd p
3356 call assert_equal(2, winnr('$'))
3357 call assert_equal(1, line('$'))
3358
3359 " After deleting the location list stack, if the location list window is
3360 " opened, then a new location list should be created. So opening the
3361 " location list window again should not create a new window.
3362 if a:cchar == 'l'
3363 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3364 wincmd p
3365 lopen
3366 call assert_equal(2, winnr('$'))
3367 endif
3368 Xclose
3369endfunc
3370
Bram Moolenaar74240d32017-12-10 15:26:15 +01003371" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003372func Test_qf_free()
3373 call XfreeTests('c')
3374 call XfreeTests('l')
3375endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003376
3377" Test for buffer overflow when parsing lines and adding new entries to
3378" the quickfix list.
3379func Test_bufoverflow()
3380 set efm=%f:%l:%m
3381 cgetexpr ['File1:100:' . repeat('x', 1025)]
3382
3383 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3384 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3385
3386 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003387 let lines =<< trim eval END
3388 Entering directory $"{repeat('a', 1006)}"
3389 File1:10:Hello World
3390 END
3391 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003392 set efm&vim
3393endfunc
3394
Bram Moolenaar875feea2017-06-11 16:07:51 +02003395" Tests for getting the quickfix stack size
3396func XsizeTests(cchar)
3397 call s:setup_commands(a:cchar)
3398
3399 call g:Xsetlist([], 'f')
3400 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003401 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3402 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003403
3404 Xexpr "File1:10:Line1"
3405 Xexpr "File2:20:Line2"
3406 Xexpr "File3:30:Line3"
3407 Xolder | Xolder
3408 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3409 call g:Xsetlist([], 'f')
3410
3411 Xexpr "File1:10:Line1"
3412 Xexpr "File2:20:Line2"
3413 Xexpr "File3:30:Line3"
3414 Xolder | Xolder
3415 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3416 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3417endfunc
3418
3419func Test_Qf_Size()
3420 call XsizeTests('c')
3421 call XsizeTests('l')
3422endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003423
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003424func Test_cclose_from_copen()
3425 augroup QF_Test
3426 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003427 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003428 augroup END
3429 copen
3430 augroup QF_Test
3431 au!
3432 augroup END
3433 augroup! QF_Test
3434endfunc
3435
Bram Moolenaar18141832017-06-25 21:17:25 +02003436func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003437 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003438 " event will be triggered.
3439 call test_override('starting', 1)
3440 augroup QF_Test
3441 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003442 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003443 augroup END
3444 copen
3445 augroup QF_Test
3446 au!
3447 augroup END
3448 augroup! QF_Test
3449 call test_override('starting', 0)
3450endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003451
Bram Moolenaar379fb762018-08-30 15:58:28 +02003452" Check that ":file" without an argument is possible even when "curbuf_lock"
3453" is set.
3454func Test_file_from_copen()
3455 " Works without argument.
3456 augroup QF_Test
3457 au!
3458 au FileType qf file
3459 augroup END
3460 copen
3461
3462 augroup QF_Test
3463 au!
3464 augroup END
3465 cclose
3466
3467 " Fails with argument.
3468 augroup QF_Test
3469 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003470 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003471 augroup END
3472 copen
3473 augroup QF_Test
3474 au!
3475 augroup END
3476 cclose
3477
3478 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003479endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003480
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003481func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003482 augroup QF_Test
3483 au!
3484 au FileType qf resize 5
3485 augroup END
3486 try
3487 " This should succeed without any exception. No other buffers are
3488 " involved in the autocmd.
3489 copen
3490 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003491 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003492 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003493 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003494 augroup! QF_Test
3495 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003496endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003497
Bram Moolenaard0fab102022-10-20 16:03:33 +01003498func Test_filetype_autocmd()
3499 " this changes the location list while it is in use to fill a buffer
3500 lexpr ''
3501 lopen
3502 augroup FT_loclist
3503 au FileType * call setloclist(0, [], 'f')
3504 augroup END
3505 silent! lolder
3506 lexpr ''
3507
3508 augroup FT_loclist
3509 au! FileType
3510 augroup END
3511endfunc
3512
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003513func Test_vimgrep_with_textlock()
3514 new
3515
zeertzjqcfe45652022-05-27 17:26:55 +01003516 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003517 " Check that vimgrep without jumping can be executed.
3518 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3519 normal ax
3520 let qflist = getqflist()
3521 call assert_true(len(qflist) > 0)
3522 call assert_match('RunTheTest', qflist[0].text)
3523 call setqflist([], 'r')
3524 au! InsertCharPre
3525
3526 " Check that vimgrepadd without jumping can be executed.
3527 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3528 normal ax
3529 let qflist = getqflist()
3530 call assert_true(len(qflist) > 0)
3531 call assert_match('RunTheTest', qflist[0].text)
3532 call setqflist([], 'r')
3533 au! InsertCharPre
3534
3535 " Check that lvimgrep without jumping can be executed.
3536 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3537 normal ax
3538 let qflist = getloclist(0)
3539 call assert_true(len(qflist) > 0)
3540 call assert_match('RunTheTest', qflist[0].text)
3541 call setloclist(0, [], 'r')
3542 au! InsertCharPre
3543
3544 " Check that lvimgrepadd without jumping can be executed.
3545 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3546 normal ax
3547 let qflist = getloclist(0)
3548 call assert_true(len(qflist) > 0)
3549 call assert_match('RunTheTest', qflist[0].text)
3550 call setloclist(0, [], 'r')
3551 au! InsertCharPre
3552
3553 " trying to jump will give an error
3554 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3555 call assert_fails('normal ax', 'E565:')
3556 au! InsertCharPre
3557
3558 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3559 call assert_fails('normal ax', 'E565:')
3560 au! InsertCharPre
3561
3562 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3563 call assert_fails('normal ax', 'E565:')
3564 au! InsertCharPre
3565
3566 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3567 call assert_fails('normal ax', 'E565:')
3568 au! InsertCharPre
3569
3570 bwipe!
3571endfunc
3572
Bram Moolenaara8788f42017-07-19 17:06:20 +02003573" Tests for the quickfix buffer b:changedtick variable
3574func Xchangedtick_tests(cchar)
3575 call s:setup_commands(a:cchar)
3576
3577 new | only
3578
3579 Xexpr "" | Xexpr "" | Xexpr ""
3580
3581 Xopen
3582 Xolder
3583 Xolder
3584 Xaddexpr "F1:10:Line10"
3585 Xaddexpr "F2:20:Line20"
3586 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3587 call g:Xsetlist([], 'f')
3588 call assert_equal(8, getbufvar('%', 'changedtick'))
3589 Xclose
3590endfunc
3591
3592func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003593 call Xchangedtick_tests('c')
3594 call Xchangedtick_tests('l')
3595endfunc
3596
3597" Tests for parsing an expression using setqflist()
3598func Xsetexpr_tests(cchar)
3599 call s:setup_commands(a:cchar)
3600
3601 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003602 call g:Xsetlist([], ' ', {'lines' : t})
3603 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003604
3605 let l = g:Xgetlist()
3606 call assert_equal(3, len(l))
3607 call assert_equal(20, l[1].lnum)
3608 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003609 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003610 let l = g:Xgetlist()
3611 call assert_equal(1, len(l))
3612 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003613 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3614 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003615
3616 call g:Xsetlist([], 'f')
3617 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003618 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3619 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3620 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3621 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003622 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3623 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003624
3625 " Adding entries using a custom efm
3626 set efm&
3627 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3628 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3629 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3630 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3631 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3632 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3633 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3634 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003635endfunc
3636
3637func Test_setexpr()
3638 call Xsetexpr_tests('c')
3639 call Xsetexpr_tests('l')
3640endfunc
3641
3642" Tests for per quickfix/location list directory stack
3643func Xmultidirstack_tests(cchar)
3644 call s:setup_commands(a:cchar)
3645
3646 call g:Xsetlist([], 'f')
3647 Xexpr "" | Xexpr ""
3648
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003649 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3650 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3651 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3652 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003653
3654 let l1 = g:Xgetlist({'nr':1, 'items':1})
3655 let l2 = g:Xgetlist({'nr':2, 'items':1})
3656 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3657 call assert_equal(3, l1.items[1].lnum)
3658 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3659 call assert_equal(5, l2.items[1].lnum)
3660endfunc
3661
3662func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003663 call mkdir('Xone/a', 'pR')
3664 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003665 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3666 call writefile(lines, 'Xone/a/one.txt')
3667 call writefile(lines, 'Xtwo/a/two.txt')
3668 let save_efm = &efm
3669 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3670
3671 call Xmultidirstack_tests('c')
3672 call Xmultidirstack_tests('l')
3673
3674 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003675endfunc
3676
3677" Tests for per quickfix/location list file stack
3678func Xmultifilestack_tests(cchar)
3679 call s:setup_commands(a:cchar)
3680
3681 call g:Xsetlist([], 'f')
3682 Xexpr "" | Xexpr ""
3683
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003684 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3685 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3686 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3687 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003688
3689 let l1 = g:Xgetlist({'nr':1, 'items':1})
3690 let l2 = g:Xgetlist({'nr':2, 'items':1})
3691 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3692 call assert_equal(3, l1.items[1].lnum)
3693 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3694 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003695
3696 " Test for start of a new error line in the same line where a previous
3697 " error line ends with a file stack.
3698 let efm_val = 'Error\ l%l\ in\ %f,'
3699 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003700 let lines =<< trim END
3701 (one.txt
3702 Error l4 in one.txt
3703 ) (two.txt
3704 Error l6 in two.txt
3705 )
3706 Error l8 in one.txt
3707 END
3708 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003709 call assert_equal(3, len(l.items))
3710 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3711 call assert_equal(4, l.items[0].lnum)
3712 call assert_equal('one.txt', l.items[0].text)
3713 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3714 call assert_equal(6, l.items[1].lnum)
3715 call assert_equal('two.txt', l.items[1].text)
3716 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3717 call assert_equal(8, l.items[2].lnum)
3718 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003719endfunc
3720
3721func Test_multifilestack()
3722 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003723 call writefile(lines, 'one.txt', 'D')
3724 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003725 let save_efm = &efm
3726 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3727
3728 call Xmultifilestack_tests('c')
3729 call Xmultifilestack_tests('l')
3730
3731 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003732endfunc
3733
3734" Tests for per buffer 'efm' setting
3735func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003736 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3737 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003738 set efm=%f#%l#%m
3739 new | only
3740 new
3741 setlocal efm=%f-%l-%m
3742 cfile one.txt
3743 wincmd w
3744 caddfile two.txt
3745
3746 let l = getqflist()
3747 call assert_equal(10, l[0].lnum)
3748 call assert_equal('Line20', l[1].text)
3749
3750 set efm&
3751 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003752endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003753
3754" Open multiple help windows using ":lhelpgrep
3755" This test used to crash Vim
3756func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003757 new | only
3758 lhelpgrep window
3759 lopen
3760 e#
3761 lhelpgrep buffer
3762 call assert_equal(3, winnr('$'))
3763 call assert_true(len(getloclist(1)) != 0)
3764 call assert_true(len(getloclist(2)) != 0)
3765 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003766endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003767
3768" Tests for adding new quickfix lists using setqflist()
3769func XaddQf_tests(cchar)
3770 call s:setup_commands(a:cchar)
3771
3772 " Create a new list using ' ' for action
3773 call g:Xsetlist([], 'f')
3774 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3775 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3776 call assert_equal(1, l.nr)
3777 call assert_equal('Test1', l.title)
3778
3779 " Create a new list using ' ' for action and '$' for 'nr'
3780 call g:Xsetlist([], 'f')
3781 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3782 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3783 call assert_equal(1, l.nr)
3784 call assert_equal('Test2', l.title)
3785
3786 " Create a new list using 'a' for action
3787 call g:Xsetlist([], 'f')
3788 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3789 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3790 call assert_equal(1, l.nr)
3791 call assert_equal('Test3', l.title)
3792
3793 " Create a new list using 'a' for action and '$' for 'nr'
3794 call g:Xsetlist([], 'f')
3795 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3796 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3797 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3798 call assert_equal(1, l.nr)
3799 call assert_equal('Test4', l.title)
3800
3801 " Adding a quickfix list should remove all the lists following the current
3802 " list.
3803 Xexpr "" | Xexpr "" | Xexpr ""
3804 silent! 10Xolder
3805 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3806 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3807 call assert_equal(2, l.nr)
3808 call assert_equal('Test5', l.title)
3809
3810 " Add a quickfix list using '$' as the list number.
3811 let lastqf = g:Xgetlist({'nr':'$'}).nr
3812 silent! 99Xolder
3813 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3814 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3815 call assert_equal(lastqf + 1, l.nr)
3816 call assert_equal('Test6', l.title)
3817
3818 " Add a quickfix list using 'nr' set to one more than the quickfix
3819 " list size.
3820 let lastqf = g:Xgetlist({'nr':'$'}).nr
3821 silent! 99Xolder
3822 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3823 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3824 call assert_equal(lastqf + 1, l.nr)
3825 call assert_equal('Test7', l.title)
3826
3827 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3828 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3829 silent! 99Xolder
3830 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3831 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3832 call assert_equal(10, l.nr)
3833 call assert_equal('Test8', l.title)
3834
3835 " Add a quickfix list using 'nr' set to a value greater than 10
3836 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3837
3838 " Try adding a quickfix list with 'nr' set to a value greater than the
3839 " quickfix list size but less than 10.
3840 call g:Xsetlist([], 'f')
3841 Xexpr "" | Xexpr "" | Xexpr ""
3842 silent! 99Xolder
3843 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3844
3845 " Add a quickfix list using 'nr' set to a some string or list
3846 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3847endfunc
3848
3849func Test_add_qf()
3850 call XaddQf_tests('c')
3851 call XaddQf_tests('l')
3852endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003853
3854" Test for getting the quickfix list items from some text without modifying
3855" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003856func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003857 call s:setup_commands(a:cchar)
3858 call g:Xsetlist([], 'f')
3859
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003860 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003861 call assert_equal(2, len(l))
3862 call assert_equal(30, l[1].lnum)
3863
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003864 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3865 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3866 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3867 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003868
Bram Moolenaar36538222017-09-02 19:51:44 +02003869 " Parse text using a custom efm
3870 set efm&
3871 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3872 call assert_equal('Line30', l[0].text)
3873 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3874 call assert_equal('File3:30:Line30', l[0].text)
3875 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3876 call assert_equal({}, l)
3877 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3878 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3879
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003880 " Make sure that the quickfix stack is not modified
3881 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3882endfunc
3883
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003884func Test_get_list_from_lines()
3885 call XgetListFromLines('c')
3886 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003887endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003888
3889" Tests for the quickfix list id
3890func Xqfid_tests(cchar)
3891 call s:setup_commands(a:cchar)
3892
3893 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003894 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003895 Xexpr ''
3896 let start_id = g:Xgetlist({'id' : 0}).id
3897 Xexpr '' | Xexpr ''
3898 Xolder
3899 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3900 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3901 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003902 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003903 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003904 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3905 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003906
3907 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3908 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003909 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003910 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3911 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3912 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3913
3914 let qfid = g:Xgetlist({'id':0, 'nr':0})
3915 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003916 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003917endfunc
3918
3919func Test_qf_id()
3920 call Xqfid_tests('c')
3921 call Xqfid_tests('l')
3922endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003923
3924func Xqfjump_tests(cchar)
3925 call s:setup_commands(a:cchar)
3926
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003927 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3928 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3929 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003930
3931 call g:Xsetlist([], 'f')
3932
3933 " Tests for
3934 " Jumping to a line using a pattern
3935 " Jumping to a column greater than the last column in a line
3936 " Jumping to a line greater than the last line in the file
3937 let l = []
3938 for i in range(1, 7)
3939 call add(l, {})
3940 endfor
3941 let l[0].filename='F1'
3942 let l[0].pattern='Line1'
3943 let l[1].filename='F2'
3944 let l[1].pattern='Line1'
3945 let l[2].filename='F3'
3946 let l[2].pattern='Line1'
3947 let l[3].filename='F3'
3948 let l[3].lnum=1
3949 let l[3].col=9
3950 let l[3].vcol=1
3951 let l[4].filename='F3'
3952 let l[4].lnum=99
3953 let l[5].filename='F3'
3954 let l[5].lnum=1
3955 let l[5].col=99
3956 let l[5].vcol=1
3957 let l[6].filename='F3'
3958 let l[6].pattern='abcxyz'
3959
3960 call g:Xsetlist([], ' ', {'items' : l})
3961 Xopen | only
3962 2Xnext
3963 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003964 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003965 Xnext
3966 call assert_equal(7, col('.'))
3967 Xnext
3968 call assert_equal(2, line('.'))
3969 Xnext
3970 call assert_equal(9, col('.'))
3971 2
3972 Xnext
3973 call assert_equal(2, line('.'))
3974
3975 if a:cchar == 'l'
3976 " When jumping to a location list entry in the location list window and
3977 " no usable windows are available, then a new window should be opened.
3978 enew! | new | only
3979 call g:Xsetlist([], 'f')
3980 setlocal buftype=nofile
3981 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003982 let lines =<< trim END
3983 F1:1:1:Line1
3984 F1:2:2:Line2
3985 F2:1:1:Line1
3986 F2:2:2:Line2
3987 F3:1:1:Line1
3988 F3:2:2:Line2
3989 END
3990 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003991 Xopen
3992 let winid = win_getid()
3993 wincmd p
3994 close
3995 call win_gotoid(winid)
3996 Xnext
3997 call assert_equal(3, winnr('$'))
3998 call assert_equal(1, winnr())
3999 call assert_equal(2, line('.'))
4000
4001 " When jumping to an entry in the location list window and the window
4002 " associated with the location list is not present and a window containing
4003 " the file is already present, then that window should be used.
4004 close
4005 belowright new
4006 call g:Xsetlist([], 'f')
4007 edit F3
4008 call win_gotoid(winid)
4009 Xlast
4010 call assert_equal(3, winnr())
4011 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
4012 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
4013 endif
4014
4015 " Cleanup
4016 enew!
4017 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01004018endfunc
4019
4020func Test_qfjump()
4021 call Xqfjump_tests('c')
4022 call Xqfjump_tests('l')
4023endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01004024
4025" Tests for the getqflist() and getloclist() functions when the list is not
4026" present or is empty
4027func Xgetlist_empty_tests(cchar)
4028 call s:setup_commands(a:cchar)
4029
4030 " Empty quickfix stack
4031 call g:Xsetlist([], 'f')
4032 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4033 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
4034 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4035 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4036 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4037 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4038 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4039 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004040 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004041 if a:cchar == 'c'
4042 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004043 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004044 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4045 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004046 else
4047 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4048 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004049 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004050 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004051 \ g:Xgetlist({'all' : 0}))
4052 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004053
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004054 " Quickfix window with empty stack
4055 silent! Xopen
4056 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004057 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004058 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4059 Xclose
4060
Bram Moolenaara6d48492017-12-12 22:45:31 +01004061 " Empty quickfix list
4062 Xexpr ""
4063 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4064 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4065 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4066 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4067 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4068 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4069 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4070 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004071 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004072
4073 let qfid = g:Xgetlist({'id' : 0}).id
4074 call g:Xsetlist([], 'f')
4075
4076 " Non-existing quickfix identifier
4077 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4078 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4079 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4080 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4081 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4082 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4083 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4084 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004085 call assert_equal(0, g:Xgetlist({'id' : qfid, '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 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004090 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4091 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' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004096 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4097 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004098
4099 " Non-existing quickfix list number
4100 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4101 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4102 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4103 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4104 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4105 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4106 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4107 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004108 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004109 if a:cchar == 'c'
4110 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4111 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004112 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4113 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004114 else
4115 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4116 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004117 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4118 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004119 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004120endfunc
4121
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004122func Test_empty_list_quickfixtextfunc()
4123 " This was crashing. Can only reproduce by running it in a separate Vim
4124 " instance.
4125 let lines =<< trim END
4126 func s:Func(o)
4127 cgetexpr '0'
4128 endfunc
4129 cope
4130 let &quickfixtextfunc = 's:Func'
4131 cgetfile [ex
4132 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004133 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004134 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004135endfunc
4136
Bram Moolenaara6d48492017-12-12 22:45:31 +01004137func Test_getqflist()
4138 call Xgetlist_empty_tests('c')
4139 call Xgetlist_empty_tests('l')
4140endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004141
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004142func Test_getqflist_invalid_nr()
4143 " The following commands used to crash Vim
4144 cexpr ""
4145 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4146
4147 " Cleanup
4148 call setqflist([], 'r')
4149endfunc
4150
Bram Moolenaarb254af32017-12-18 19:48:58 +01004151" Tests for the quickfix/location list changedtick
4152func Xqftick_tests(cchar)
4153 call s:setup_commands(a:cchar)
4154
4155 call g:Xsetlist([], 'f')
4156
4157 Xexpr "F1:10:Line10"
4158 let qfid = g:Xgetlist({'id' : 0}).id
4159 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4160 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4161 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4162 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4163 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4164 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4165 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4166 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4167 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4168
4169 enew!
4170 call append(0, ["F5:50:L50", "F6:60:L60"])
4171 Xaddbuffer
4172 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4173 enew!
4174
4175 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4176 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4177 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4178 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4179 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4180 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4181 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4182 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4183 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4184 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4185 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4186
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004187 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004188 Xfile Xone
4189 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4190 Xaddfile Xone
4191 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4192
4193 " Test case for updating a non-current quickfix list
4194 call g:Xsetlist([], 'f')
4195 Xexpr "F1:1:L1"
4196 Xexpr "F2:2:L2"
4197 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4198 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4199 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004200endfunc
4201
4202func Test_qf_tick()
4203 call Xqftick_tests('c')
4204 call Xqftick_tests('l')
4205endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004206
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004207" Test helpgrep with lang specifier
4208func Xtest_helpgrep_with_lang_specifier(cchar)
4209 call s:setup_commands(a:cchar)
4210 Xhelpgrep Vim@en
4211 call assert_equal('help', &filetype)
4212 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4213 new | only
4214endfunc
4215
4216func Test_helpgrep_with_lang_specifier()
4217 call Xtest_helpgrep_with_lang_specifier('c')
4218 call Xtest_helpgrep_with_lang_specifier('l')
4219endfunc
4220
Bram Moolenaar12237442017-12-19 12:38:52 +01004221" The following test used to crash Vim.
4222" Open the location list window and close the regular window associated with
4223" the location list. When the garbage collection runs now, it incorrectly
4224" marks the location list context as not in use and frees the context.
4225func Test_ll_window_ctx()
4226 call setloclist(0, [], 'f')
4227 call setloclist(0, [], 'a', {'context' : []})
4228 lopen | only
4229 call test_garbagecollect_now()
4230 echo getloclist(0, {'context' : 1}).context
4231 enew | only
4232endfunc
4233
zeertzjqbe4bd182024-09-14 10:32:31 +02004234" Similar to the problem above, but for user data.
4235func Test_ll_window_user_data()
4236 call setloclist(0, [#{bufnr: bufnr(), user_data: {}}])
4237 lopen
4238 wincmd t
4239 close
4240 call test_garbagecollect_now()
4241 call feedkeys("\<CR>", 'tx')
4242 call test_garbagecollect_now()
4243 %bwipe!
4244endfunc
4245
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004246" The following test used to crash vim
4247func Test_lfile_crash()
4248 sp Xtest
4249 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004250 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004251 au! QuickFixCmdPre
4252endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004253
4254" The following test used to crash vim
4255func Test_lbuffer_crash()
4256 sv Xtest
4257 augroup QF_Test
4258 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004259 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004260 augroup END
4261 lbuffer
4262 augroup QF_Test
4263 au!
4264 augroup END
4265endfunc
4266
4267" The following test used to crash vim
4268func Test_lexpr_crash()
4269 augroup QF_Test
4270 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004271 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004272 augroup END
4273 lexpr ""
4274 augroup QF_Test
4275 au!
4276 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004277
Bram Moolenaar3c097222017-12-21 20:54:49 +01004278 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004279 augroup QF_Test
4280 au!
4281 au BufNew * call setloclist(0, [], 'f')
4282 augroup END
4283 lexpr 'x:1:x'
4284 augroup QF_Test
4285 au!
4286 augroup END
4287
4288 enew | only
4289 lexpr ''
4290 lopen
4291 augroup QF_Test
4292 au!
4293 au FileType * call setloclist(0, [], 'f')
4294 augroup END
4295 lexpr ''
4296 augroup QF_Test
4297 au!
4298 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004299endfunc
4300
4301" The following test used to crash Vim
4302func Test_lvimgrep_crash()
Austin Chang29822992024-10-03 10:50:05 +02004303 " this leaves a swapfile .test_quickfix.vim.swp around, why?
Bram Moolenaar3c097222017-12-21 20:54:49 +01004304 sv Xtest
4305 augroup QF_Test
4306 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004307 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004308 augroup END
4309 lvimgrep quickfix test_quickfix.vim
4310 augroup QF_Test
4311 au!
4312 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004313
4314 new | only
4315 augroup QF_Test
4316 au!
4317 au BufEnter * call setloclist(0, [], 'r')
4318 augroup END
4319 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4320 augroup QF_Test
4321 au!
4322 augroup END
4323
Bram Moolenaar3c097222017-12-21 20:54:49 +01004324 enew | only
4325endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004326
Bram Moolenaar2573af32020-03-14 17:21:34 +01004327func Test_lvimgrep_crash2()
4328 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004329 call assert_fails('lvimgrep x x', 'E471:')
4330 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004331
4332 au! BufNewFile
4333endfunc
4334
Bram Moolenaarde046542017-12-26 13:53:11 +01004335" Test for the position of the quickfix and location list window
4336func Test_qfwin_pos()
4337 " Open two windows
4338 new | only
4339 new
4340 cexpr ['F1:10:L10']
4341 copen
4342 " Quickfix window should be the bottom most window
4343 call assert_equal(3, winnr())
4344 close
4345 " Open at the very top
4346 wincmd t
4347 topleft copen
4348 call assert_equal(1, winnr())
4349 close
4350 " open left of the current window
4351 wincmd t
4352 below new
4353 leftabove copen
4354 call assert_equal(2, winnr())
4355 close
4356 " open right of the current window
4357 rightbelow copen
4358 call assert_equal(3, winnr())
4359 close
4360endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004361
4362" Tests for quickfix/location lists changed by autocommands when
4363" :vimgrep/:lvimgrep commands are running.
4364func Test_vimgrep_autocmd()
4365 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004366 call writefile(['stars'], 'Xtest1.txt', 'D')
4367 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004368
4369 " Test 1:
4370 " When searching for a pattern using :vimgrep, if the quickfix list is
4371 " changed by an autocmd, the results should be added to the correct quickfix
4372 " list.
4373 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4374 silent vimgrep stars Xtest*.txt
4375 call assert_equal(1, getqflist({'nr' : 0}).nr)
4376 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4377 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4378 au! BufRead Xtest2.txt
4379
4380 " Test 2:
4381 " When searching for a pattern using :vimgrep, if the quickfix list is
4382 " freed, then a error should be given.
4383 silent! %bwipe!
4384 call setqflist([], 'f')
4385 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4386 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4387 au! BufRead Xtest2.txt
4388
4389 " Test 3:
4390 " When searching for a pattern using :lvimgrep, if the location list is
4391 " freed, then the command should error out.
4392 silent! %bwipe!
4393 let g:save_winid = win_getid()
4394 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4395 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4396 au! BufRead Xtest2.txt
Austin Chang29822992024-10-03 10:50:05 +02004397 " cleanup the swap files
4398 bw! Xtest2.txt Xtest1.txt
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004399
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004400 call setqflist([], 'f')
4401endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004402
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004403" Test for an autocmd changing the current directory when running vimgrep
4404func Xvimgrep_autocmd_cd(cchar)
4405 call s:setup_commands(a:cchar)
4406
4407 %bwipe
4408 let save_cwd = getcwd()
4409
4410 augroup QF_Test
4411 au!
4412 autocmd BufRead * silent cd %:p:h
4413 augroup END
4414
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004415 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004416 let l = g:Xgetlist()
4417 call assert_equal('f1.txt', bufname(l[0].bufnr))
4418 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4419
4420 augroup QF_Test
4421 au!
4422 augroup END
4423
4424 exe 'cd ' . save_cwd
4425endfunc
4426
4427func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004428 call mkdir('Xgrepdir/a', 'pR')
4429 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004430 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4431 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004432 call Xvimgrep_autocmd_cd('c')
4433 call Xvimgrep_autocmd_cd('l')
4434 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004435endfunc
4436
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004437" The following test used to crash Vim
4438func Test_lhelpgrep_autocmd()
4439 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004440 augroup QF_Test
4441 au!
4442 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4443 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004444 lhelpgrep buffer
4445 call assert_equal('help', &filetype)
4446 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4447 lhelpgrep tabpage
4448 call assert_equal('help', &filetype)
4449 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004450 augroup QF_Test
4451 au!
4452 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004453
4454 new | only
4455 augroup QF_Test
4456 au!
4457 au BufEnter * call setqflist([], 'f')
4458 augroup END
4459 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004460 " run the test with a help window already open
4461 help
4462 wincmd w
4463 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004464 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004465 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004466 augroup END
4467
4468 new | only
4469 augroup QF_Test
4470 au!
4471 au BufEnter * call setqflist([], 'r')
4472 augroup END
4473 call assert_fails('helpgrep quickfix', 'E925:')
4474 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004475 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004476 augroup END
4477
4478 new | only
4479 augroup QF_Test
4480 au!
4481 au BufEnter * call setloclist(0, [], 'r')
4482 augroup END
4483 call assert_fails('lhelpgrep quickfix', 'E926:')
4484 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004485 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004486 augroup END
4487
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004488 " Replace the contents of a help window location list when it is still in
4489 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004490 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004491 lhelpgrep quickfix
4492 wincmd w
4493 augroup QF_Test
4494 au!
4495 autocmd WinEnter * call setloclist(0, [], 'r')
4496 augroup END
4497 call assert_fails('lhelpgrep win_getid', 'E926:')
4498 augroup QF_Test
4499 au!
4500 augroup END
4501
4502 %bw!
4503endfunc
4504
4505" The following test used to crash Vim
4506func Test_lhelpgrep_autocmd_free_loclist()
4507 %bw!
4508 lhelpgrep quickfix
4509 wincmd w
4510 augroup QF_Test
4511 au!
4512 autocmd WinEnter * call setloclist(0, [], 'f')
4513 augroup END
4514 lhelpgrep win_getid
4515 wincmd w
4516 wincmd w
4517 wincmd w
4518 augroup QF_Test
4519 au!
4520 augroup END
4521 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004522endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004523
4524" Test for shortening/simplifying the file name when opening the
4525" quickfix window or when displaying the quickfix list
4526func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004527 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004528 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004529 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004530 let fname = getcwd() . '/test_quickfix.vim'
4531 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4532 call assert_equal(fname, bufname('test_quickfix.vim'))
4533 " Opening the quickfix window should simplify the file path
4534 cwindow
4535 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4536 cclose
4537 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004538 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004539 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4540 call assert_equal(fname, bufname('test_quickfix.vim'))
4541 " Displaying the quickfix list should simplify the file path
4542 silent! clist
4543 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004544 " Add a few entries for the same file with different paths and check whether
4545 " the buffer name is shortened
4546 %bwipe
4547 call setqflist([], 'f')
4548 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4549 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4550 \ {'filename' : fname, 'lnum' : 30}], ' ')
4551 copen
4552 call assert_equal(['test_quickfix.vim|10| ',
4553 \ 'test_quickfix.vim|20| ',
4554 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4555 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004556endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004557
4558" Quickfix title tests
4559" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4560" Otherwise due to indentation, the title is set with spaces at the beginning
4561" of the command.
4562func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004563 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004564
4565 " :cexpr
4566 exe "cexpr readfile('Xerr')"
4567 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4568
4569 " :cgetexpr
4570 exe "cgetexpr readfile('Xerr')"
4571 call assert_equal(":cgetexpr readfile('Xerr')",
4572 \ getqflist({'title' : 1}).title)
4573
4574 " :caddexpr
4575 call setqflist([], 'f')
4576 exe "caddexpr readfile('Xerr')"
4577 call assert_equal(":caddexpr readfile('Xerr')",
4578 \ getqflist({'title' : 1}).title)
4579
4580 " :cbuffer
4581 new Xerr
4582 exe "cbuffer"
4583 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4584
4585 " :cgetbuffer
4586 edit Xerr
4587 exe "cgetbuffer"
4588 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4589
4590 " :caddbuffer
4591 call setqflist([], 'f')
4592 edit Xerr
4593 exe "caddbuffer"
4594 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4595
4596 " :cfile
4597 exe "cfile Xerr"
4598 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4599
4600 " :cgetfile
4601 exe "cgetfile Xerr"
4602 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4603
4604 " :caddfile
4605 call setqflist([], 'f')
4606 exe "caddfile Xerr"
4607 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4608
4609 " :grep
4610 set grepprg=internal
4611 exe "grep F1 Xerr"
4612 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4613
4614 " :grepadd
4615 call setqflist([], 'f')
4616 exe "grepadd F1 Xerr"
4617 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4618 set grepprg&vim
4619
4620 " :vimgrep
4621 exe "vimgrep F1 Xerr"
4622 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4623
4624 " :vimgrepadd
4625 call setqflist([], 'f')
4626 exe "vimgrepadd F1 Xerr"
4627 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4628
4629 call setqflist(['F1:10:L10'], ' ')
4630 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4631
4632 call setqflist([], 'f')
4633 call setqflist(['F1:10:L10'], 'a')
4634 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4635
4636 call setqflist([], 'f')
4637 call setqflist(['F1:10:L10'], 'r')
4638 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4639
4640 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004641
4642 call setqflist([], ' ', {'title' : 'Errors'})
4643 copen
4644 call assert_equal('Errors', w:quickfix_title)
4645 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4646 call assert_equal('Errors', w:quickfix_title)
4647 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004648
4649 " Switching to another quickfix list in one tab page should update the
4650 " quickfix window title and statusline in all the other tab pages also
4651 call setqflist([], 'f')
4652 %bw!
4653 cgetexpr ['file_one:1:1: error in the first quickfix list']
4654 call setqflist([], 'a', {'title': 'first quickfix list'})
4655 cgetexpr ['file_two:2:1: error in the second quickfix list']
4656 call setqflist([], 'a', {'title': 'second quickfix list'})
4657 copen
4658 wincmd t
4659 tabnew two
4660 copen
4661 wincmd t
4662 colder
4663 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4664 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4665 call assert_equal(1, tabpagewinnr(1))
4666 call assert_equal(1, tabpagewinnr(2))
4667 tabnew
4668 call setqflist([], 'a', {'title': 'new quickfix title'})
4669 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4670 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4671 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004672endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004673
4674func Test_lbuffer_with_bwipe()
4675 new
4676 new
4677 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004678 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004679 augroup END
4680 lbuffer
4681 augroup nasty
4682 au!
4683 augroup END
4684endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004685
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004686" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4687" running
4688func Xexpr_acmd_freelist(cchar)
4689 call s:setup_commands(a:cchar)
4690
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004691 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004692 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004693 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004694 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004695 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004696 augroup nasty
4697 au!
4698 augroup END
4699endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004700
4701func Test_cexpr_acmd_freelist()
4702 call Xexpr_acmd_freelist('c')
4703 call Xexpr_acmd_freelist('l')
4704endfunc
4705
4706" Test for commands that create a new quickfix/location list and jump to the
4707" first error automatically.
4708func Xjumpto_first_error_test(cchar)
4709 call s:setup_commands(a:cchar)
4710
4711 call s:create_test_file('Xtestfile1')
4712 call s:create_test_file('Xtestfile2')
4713 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4714
4715 " Test for cexpr/lexpr
4716 enew
4717 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004718 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004719 call assert_equal(2, line('.'))
4720
4721 " Test for cfile/lfile
4722 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004723 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004724 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004725 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004726 call assert_equal(2, line('.'))
4727
4728 " Test for cbuffer/lbuffer
4729 edit Xerr
4730 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004731 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004732 call assert_equal(2, line('.'))
4733
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004734 call delete('Xtestfile1')
4735 call delete('Xtestfile2')
4736endfunc
4737
4738func Test_jumpto_first_error()
4739 call Xjumpto_first_error_test('c')
4740 call Xjumpto_first_error_test('l')
4741endfunc
4742
4743" Test for a quickfix autocmd changing the quickfix/location list before
4744" jumping to the first error in the new list.
4745func Xautocmd_changelist(cchar)
4746 call s:setup_commands(a:cchar)
4747
4748 " Test for cfile/lfile
4749 call s:create_test_file('Xtestfile1')
4750 call s:create_test_file('Xtestfile2')
4751 Xexpr 'Xtestfile1:2:Line2'
4752 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004753 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004754 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004755 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004756 call assert_equal(4, line('.'))
4757 autocmd! QuickFixCmdPost
4758
4759 " Test for cbuffer/lbuffer
4760 call g:Xsetlist([], 'f')
4761 Xexpr 'Xtestfile1:2:Line2'
4762 autocmd QuickFixCmdPost * Xolder
4763 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4764 edit Xerr
4765 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004766 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004767 call assert_equal(4, line('.'))
4768 autocmd! QuickFixCmdPost
4769
4770 " Test for cexpr/lexpr
4771 call g:Xsetlist([], 'f')
4772 Xexpr 'Xtestfile1:2:Line2'
4773 autocmd QuickFixCmdPost * Xolder
4774 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004775 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004776 call assert_equal(4, line('.'))
4777 autocmd! QuickFixCmdPost
4778
Bram Moolenaar851332e2018-07-03 19:16:00 +02004779 " The grepprg may not be set on non-Unix systems
4780 if has('unix')
4781 " Test for grep/lgrep
4782 call g:Xsetlist([], 'f')
4783 Xexpr 'Xtestfile1:2:Line2'
4784 autocmd QuickFixCmdPost * Xolder
4785 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004786 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004787 call assert_equal(5, line('.'))
4788 autocmd! QuickFixCmdPost
4789 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004790
4791 " Test for vimgrep/lvimgrep
4792 call g:Xsetlist([], 'f')
4793 Xexpr 'Xtestfile1:2:Line2'
4794 autocmd QuickFixCmdPost * Xolder
4795 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004796 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004797 call assert_equal(5, line('.'))
4798 autocmd! QuickFixCmdPost
4799
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004800 " Test for autocommands clearing the quickfix list before jumping to the
4801 " first error. This should not result in an error
4802 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4803 let v:errmsg = ''
4804 " Test for cfile/lfile
4805 Xfile Xerr
4806 call assert_true(v:errmsg !~# 'E42:')
4807 " Test for cbuffer/lbuffer
4808 edit Xerr
4809 Xbuffer
4810 call assert_true(v:errmsg !~# 'E42:')
4811 " Test for cexpr/lexpr
4812 Xexpr 'Xtestfile2:4:Line4'
4813 call assert_true(v:errmsg !~# 'E42:')
4814 " Test for grep/lgrep
4815 " The grepprg may not be set on non-Unix systems
4816 if has('unix')
4817 silent Xgrep Line5 Xtestfile2
4818 call assert_true(v:errmsg !~# 'E42:')
4819 endif
4820 " Test for vimgrep/lvimgrep
4821 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4822 autocmd! QuickFixCmdPost
4823
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004824 call delete('Xtestfile1')
4825 call delete('Xtestfile2')
4826endfunc
4827
4828func Test_autocmd_changelist()
4829 call Xautocmd_changelist('c')
4830 call Xautocmd_changelist('l')
4831endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004832
4833" Tests for the ':filter /pat/ clist' command
4834func Test_filter_clist()
4835 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4836 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4837 \ split(execute('filter /Line 15/ clist'), "\n"))
4838 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4839 \ split(execute('filter /Xfile1/ clist'), "\n"))
4840 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4841
4842 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4843 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4844 call assert_equal([' 2 pqr:pat2: '],
4845 \ split(execute('filter /pqr/ clist'), "\n"))
4846 call assert_equal([' 1 abc:pat1: '],
4847 \ split(execute('filter /pat1/ clist'), "\n"))
4848endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004849
4850" Tests for the "CTRL-W <CR>" command.
4851func Xview_result_split_tests(cchar)
4852 call s:setup_commands(a:cchar)
4853
4854 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4855 call g:Xsetlist([])
4856 Xopen
4857 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004858 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004859 call assert_equal(l:win_count, winnr('$'))
4860 Xclose
4861endfunc
4862
4863func Test_view_result_split()
4864 call Xview_result_split_tests('c')
4865 call Xview_result_split_tests('l')
4866endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004867
4868" Test that :cc sets curswant
4869func Test_curswant()
4870 helpgrep quickfix
4871 normal! llll
4872 1cc
4873 call assert_equal(getcurpos()[4], virtcol('.'))
4874 cclose | helpclose
4875endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004876
4877" Test for opening a file from the quickfix window using CTRL-W <Enter>
4878" doesn't leave an empty buffer around.
4879func Test_splitview()
4880 call s:create_test_file('Xtestfile1')
4881 call s:create_test_file('Xtestfile2')
4882 new | only
4883 let last_bufnr = bufnr('Test_sv_1', 1)
4884 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4885 cgetexpr l
4886 copen
4887 let numbufs = len(getbufinfo())
4888 exe "normal \<C-W>\<CR>"
4889 copen
4890 exe "normal j\<C-W>\<CR>"
4891 " Make sure new empty buffers are not created
4892 call assert_equal(numbufs, len(getbufinfo()))
4893 " Creating a new buffer should use the next available buffer number
4894 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4895 bwipe Test_sv_1
4896 bwipe Test_sv_2
4897 new | only
4898
4899 " When split opening files from location list window, make sure that two
4900 " windows doesn't refer to the same location list
4901 lgetexpr l
4902 let locid = getloclist(0, {'id' : 0}).id
4903 lopen
4904 exe "normal \<C-W>\<CR>"
4905 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4906 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4907 new | only
4908
4909 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004910 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004911 lhelpgrep window
4912 let locid = getloclist(0, {'id' : 0}).id
4913 lwindow
4914 exe "normal j\<C-W>\<CR>"
4915 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4916 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4917 new | only
4918
Bram Moolenaar406cd902020-02-18 21:54:41 +01004919 " Using :split or :vsplit from a quickfix window should behave like a :new
4920 " or a :vnew command
4921 copen
4922 split
4923 call assert_equal(3, winnr('$'))
4924 let l = getwininfo()
4925 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4926 close
4927 copen
4928 vsplit
4929 let l = getwininfo()
4930 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4931 new | only
4932
Bram Moolenaarb2443732018-11-11 22:50:27 +01004933 call delete('Xtestfile1')
4934 call delete('Xtestfile2')
4935endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004936
4937" Test for parsing entries using visual screen column
4938func Test_viscol()
4939 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004940 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004941 edit Xfile1
4942
4943 " Use byte offset for column number
4944 set efm&
4945 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4946 call assert_equal([5, 8], [col('.'), virtcol('.')])
4947 cnext
4948 call assert_equal([9, 12], [col('.'), virtcol('.')])
4949 cnext
4950 call assert_equal([14, 20], [col('.'), virtcol('.')])
4951
4952 " Use screen column offset for column number
4953 set efm=%f:%l:%v:%m
4954 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4955 call assert_equal([5, 8], [col('.'), virtcol('.')])
4956 cnext
4957 call assert_equal([9, 12], [col('.'), virtcol('.')])
4958 cnext
4959 call assert_equal([14, 20], [col('.'), virtcol('.')])
4960 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4961 call assert_equal([5, 8], [col('.'), virtcol('.')])
4962 cnext
4963 call assert_equal([10, 16], [col('.'), virtcol('.')])
4964 cnext
4965 call assert_equal([14, 20], [col('.'), virtcol('.')])
4966
4967 enew
4968 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4969
4970 " Use byte offset for column number
4971 set efm&
4972 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4973 call assert_equal([8, 10], [col('.'), virtcol('.')])
4974 cnext
4975 call assert_equal([11, 17], [col('.'), virtcol('.')])
4976 cnext
4977 call assert_equal([16, 25], [col('.'), virtcol('.')])
4978
4979 " Use screen column offset for column number
4980 set efm=%f:%l:%v:%m
4981 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4982 call assert_equal([8, 10], [col('.'), virtcol('.')])
4983 cnext
4984 call assert_equal([11, 17], [col('.'), virtcol('.')])
4985 cnext
4986 call assert_equal([16, 25], [col('.'), virtcol('.')])
4987
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004988 " Use screen column number with a multi-line error message
4989 enew
4990 call writefile(["à test"], 'Xfile1')
4991 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4992 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4993 call assert_equal('Xfile1', @%)
4994 call assert_equal([0, 1, 4, 0], getpos('.'))
4995
4996 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4997 " does not break this
4998 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4999 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
5000 call assert_equal('Xfile1', @%)
5001 call assert_equal([0, 1, 3, 0], getpos('.'))
5002
Bram Moolenaarc45eb772019-01-31 14:27:04 +01005003 enew | only
5004 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01005005endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005006
5007" Test for the quickfix window buffer
5008func Xqfbuf_test(cchar)
5009 call s:setup_commands(a:cchar)
5010
5011 " Quickfix buffer should be reused across closing and opening a quickfix
5012 " window
5013 Xexpr "F1:10:Line10"
5014 Xopen
5015 let qfbnum = bufnr('')
5016 Xclose
5017 " Even after the quickfix window is closed, the buffer should be loaded
5018 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005019 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005020 Xopen
5021 " Buffer should be reused when opening the window again
5022 call assert_equal(qfbnum, bufnr(''))
5023 Xclose
5024
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00005025 " When quickfix buffer is wiped out, getqflist() should return 0
5026 %bw!
5027 Xexpr ""
5028 Xopen
5029 bw!
5030 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
5031
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005032 if a:cchar == 'l'
5033 %bwipe
5034 " For a location list, when both the file window and the location list
5035 " window for the list are closed, then the buffer should be freed.
5036 new | only
5037 lexpr "F1:10:Line10"
5038 let wid = win_getid()
5039 lopen
5040 let qfbnum = bufnr('')
5041 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
5042 close
5043 " When the location list window is closed, the buffer name should not
5044 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005045 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005046 call assert_true(bufloaded(qfbnum))
5047
Bram Moolenaard82a81c2019-03-02 07:57:18 +01005048 " After deleting a location list buffer using ":bdelete", opening the
5049 " location list window should mark the buffer as a location list buffer.
5050 exe "bdelete " . qfbnum
5051 lopen
5052 call assert_equal("quickfix", &buftype)
5053 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5054 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5055 call assert_false(&swapfile)
5056 lclose
5057
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005058 " When the location list is cleared for the window, the buffer should be
5059 " removed
5060 call setloclist(0, [], 'f')
5061 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005062 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005063
5064 " When the location list is freed with the location list window open, the
5065 " location list buffer should not be lost. It should be reused when the
5066 " location list is again populated.
5067 lexpr "F1:10:Line10"
5068 lopen
5069 let wid = win_getid()
5070 let qfbnum = bufnr('')
5071 wincmd p
5072 call setloclist(0, [], 'f')
5073 lexpr "F1:10:Line10"
5074 lopen
5075 call assert_equal(wid, win_getid())
5076 call assert_equal(qfbnum, bufnr(''))
5077 lclose
5078
5079 " When the window with the location list is closed, the buffer should be
5080 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005081 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005082 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005083 endif
5084endfunc
5085
5086func Test_qfbuf()
5087 call Xqfbuf_test('c')
5088 call Xqfbuf_test('l')
5089endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005090
5091" If there is an autocmd to use only one window, then opening the location
5092" list window used to crash Vim.
5093func Test_winonly_autocmd()
5094 call s:create_test_file('Xtest1')
5095 " Autocmd to show only one Vim window at a time
5096 autocmd WinEnter * only
5097 new
5098 " Load the location list
5099 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5100 let loclistid = getloclist(0, {'id' : 0}).id
5101 " Open the location list window. Only this window will be shown and the file
5102 " window is closed.
5103 lopen
5104 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5105 " Jump to an entry in the location list and make sure that the cursor is
5106 " positioned correctly.
5107 ll 3
5108 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005109 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005110 call assert_equal(15, line('.'))
5111 " Cleanup
5112 autocmd! WinEnter
5113 new | only
5114 call delete('Xtest1')
5115endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005116
5117" Test to make sure that an empty quickfix buffer is not reused for loading
5118" a normal buffer.
5119func Test_empty_qfbuf()
5120 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005121 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005122 call setqflist([], 'f')
5123 copen | only
5124 let qfbuf = bufnr('')
5125 edit Xfile1
5126 call assert_notequal(qfbuf, bufnr(''))
5127 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005128endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005129
5130" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005131" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005132func Xtest_below(cchar)
5133 call s:setup_commands(a:cchar)
5134
5135 " No quickfix/location list
5136 call assert_fails('Xbelow', 'E42:')
5137 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005138 call assert_fails('Xbefore', 'E42:')
5139 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005140
5141 " Empty quickfix/location list
5142 call g:Xsetlist([])
5143 call assert_fails('Xbelow', 'E42:')
5144 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005145 call assert_fails('Xbefore', 'E42:')
5146 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005147
5148 call s:create_test_file('X1')
5149 call s:create_test_file('X2')
5150 call s:create_test_file('X3')
5151 call s:create_test_file('X4')
5152
5153 " Invalid entries
5154 edit X1
5155 call g:Xsetlist(["E1", "E2"])
5156 call assert_fails('Xbelow', 'E42:')
5157 call assert_fails('Xabove', 'E42:')
5158 call assert_fails('3Xbelow', 'E42:')
5159 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005160 call assert_fails('Xbefore', 'E42:')
5161 call assert_fails('Xafter', 'E42:')
5162 call assert_fails('3Xbefore', 'E42:')
5163 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005164
5165 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005166 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 +02005167 edit +7 X2
5168 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005169 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005170 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005171 normal 7G
5172 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005173 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005174 call assert_fails('Xbefore', 'E553:')
5175
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005176 normal 2j
5177 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005178 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005179 normal 7G
5180 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005181 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005182
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005183 " Last error in this file
5184 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005185 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005186 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005187 normal gg
5188 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005189 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005190 call assert_fails('Xafter', 'E553:')
5191
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005192 " First error in this file
5193 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005194 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005195 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005196 normal G
5197 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005198 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005199 call assert_fails('Xbefore', 'E553:')
5200
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005201 normal gg
5202 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005203 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005204 normal gg
5205 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005206 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005207
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005208 normal G
5209 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005210 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005211 normal G
5212 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005213 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005214
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005215 edit X4
5216 call assert_fails('Xabove', 'E42:')
5217 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005218 call assert_fails('Xbefore', 'E42:')
5219 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005220 if a:cchar == 'l'
5221 " If a buffer has location list entries from some other window but not
5222 " from the current window, then the commands should fail.
5223 edit X1 | split | call setloclist(0, [], 'f')
5224 call assert_fails('Xabove', 'E776:')
5225 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005226 call assert_fails('Xbefore', 'E776:')
5227 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005228 close
5229 endif
5230
5231 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005232 let lines =<< trim END
5233 X1:5:L5
5234 X2:5:1:L5_1
5235 X2:5:2:L5_2
5236 X2:5:3:L5_3
5237 X2:10:1:L10_1
5238 X2:10:2:L10_2
5239 X2:10:3:L10_3
5240 X2:15:1:L15_1
5241 X2:15:2:L15_2
5242 X2:15:3:L15_3
5243 X3:3:L3
5244 END
5245 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005246 edit +1 X2
5247 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005248 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005249 normal 1G
5250 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005251 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005252
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005253 normal gg
5254 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005255 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005256 normal gg
5257 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005258 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005259
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005260 normal G
5261 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005262 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005263 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005264 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005265 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005266
5267 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005268 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005269 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005270 normal G
5271 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005272 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005273
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005274 normal 10G
5275 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005276 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005277 normal 10G$
5278 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005279 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005280
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005281 normal 10G
5282 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005283 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005284 normal 9G
5285 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005286 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005287
5288 " Invalid range
5289 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005290 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005291 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005292 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005293 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005294 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005295 endif
5296
5297 call delete('X1')
5298 call delete('X2')
5299 call delete('X3')
5300 call delete('X4')
5301endfunc
5302
5303func Test_cbelow()
5304 call Xtest_below('c')
5305 call Xtest_below('l')
5306endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005307
5308func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005309 let commands =<< trim END
5310 cNext
5311 cNfile
5312 cabove
5313 cbelow
5314 cfirst
5315 clast
5316 cnewer
5317 cnext
5318 cnfile
5319 colder
5320 cprevious
5321 crewind
5322 lNext
5323 lNfile
5324 labove
5325 lbelow
5326 lfirst
5327 llast
5328 lnewer
5329 lnext
5330 lnfile
5331 lolder
5332 lprevious
5333 lrewind
5334 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005335 for cmd in commands
5336 call assert_fails('-1' .. cmd, 'E16:')
5337 call assert_fails('.' .. cmd, 'E16:')
5338 call assert_fails('%' .. cmd, 'E16:')
5339 call assert_fails('$' .. cmd, 'E16:')
5340 endfor
5341endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005342
5343" Test for aborting quickfix commands using QuickFixCmdPre
5344func Xtest_qfcmd_abort(cchar)
5345 call s:setup_commands(a:cchar)
5346
5347 call g:Xsetlist([], 'f')
5348
5349 " cexpr/lexpr
5350 let e = ''
5351 try
5352 Xexpr ["F1:10:Line10", "F2:20:Line20"]
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
5359 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005360 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005361 let e = ''
5362 try
5363 Xfile Xfile1
5364 catch /.*/
5365 let e = v:exception
5366 endtry
5367 call assert_equal('AbortCmd', e)
5368 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005369
5370 " cgetbuffer/lgetbuffer
5371 enew!
5372 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5373 let e = ''
5374 try
5375 Xgetbuffer
5376 catch /.*/
5377 let e = v:exception
5378 endtry
5379 call assert_equal('AbortCmd', e)
5380 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5381 enew!
5382
5383 " vimgrep/lvimgrep
5384 let e = ''
5385 try
5386 Xvimgrep /func/ test_quickfix.vim
5387 catch /.*/
5388 let e = v:exception
5389 endtry
5390 call assert_equal('AbortCmd', e)
5391 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5392
5393 " helpgrep/lhelpgrep
5394 let e = ''
5395 try
5396 Xhelpgrep quickfix
5397 catch /.*/
5398 let e = v:exception
5399 endtry
5400 call assert_equal('AbortCmd', e)
5401 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5402
5403 " grep/lgrep
5404 if has('unix')
5405 let e = ''
5406 try
5407 silent Xgrep func test_quickfix.vim
5408 catch /.*/
5409 let e = v:exception
5410 endtry
5411 call assert_equal('AbortCmd', e)
5412 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5413 endif
5414endfunc
5415
5416func Test_qfcmd_abort()
5417 augroup QF_Test
5418 au!
5419 autocmd QuickFixCmdPre * throw "AbortCmd"
5420 augroup END
5421
5422 call Xtest_qfcmd_abort('c')
5423 call Xtest_qfcmd_abort('l')
5424
5425 augroup QF_Test
5426 au!
5427 augroup END
5428endfunc
5429
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005430" Test for using a file in one of the parent directories.
5431func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005432 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005433 let save_cwd = getcwd()
5434 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5435 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5436 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5437 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5438
5439 let lines = "Entering dir Xtestdir\n" .
5440 \ "Entering dir a\n" .
5441 \ "Entering dir b\n" .
5442 \ "Xfile2:2:X2_L2\n" .
5443 \ "Leaving dir a\n" .
5444 \ "Xfile1:2:X1_L2\n" .
5445 \ "Xfile3:1:X3_L1\n" .
5446 \ "Entering dir c\n" .
5447 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005448 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005449 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005450 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005451 call assert_equal(11, getqflist({'size' : 0}).size)
5452 call assert_equal(4, getqflist({'idx' : 0}).idx)
5453 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005454 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005455 cnext
5456 call assert_equal(6, getqflist({'idx' : 0}).idx)
5457 call assert_equal('X1_L2', getline('.'))
5458 cnext
5459 call assert_equal(7, getqflist({'idx' : 0}).idx)
5460 call assert_equal(1, line('$'))
5461 call assert_equal('', getline(1))
5462 cnext
5463 call assert_equal(9, getqflist({'idx' : 0}).idx)
5464 call assert_equal(1, line('$'))
5465 call assert_equal('', getline(1))
5466
5467 set efm&
5468 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005469endfunc
5470
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005471" Test for :cquit
5472func Test_cquit()
5473 " Exit Vim with a non-zero value
5474 if RunVim([], ["cquit 7"], '')
5475 call assert_equal(7, v:shell_error)
5476 endif
5477
5478 if RunVim([], ["50cquit"], '')
5479 call assert_equal(50, v:shell_error)
5480 endif
5481
5482 " Exit Vim with default value
5483 if RunVim([], ["cquit"], '')
5484 call assert_equal(1, v:shell_error)
5485 endif
5486
5487 " Exit Vim with zero value
5488 if RunVim([], ["cquit 0"], '')
5489 call assert_equal(0, v:shell_error)
5490 endif
5491
5492 " Exit Vim with negative value
5493 call assert_fails('-3cquit', 'E16:')
5494endfunc
5495
Bram Moolenaar858ba062020-05-31 23:11:59 +02005496" Test for getting a specific item from a quickfix list
5497func Xtest_getqflist_by_idx(cchar)
5498 call s:setup_commands(a:cchar)
5499 " Empty list
5500 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5501 Xexpr ['F1:10:L10', 'F1:20:L20']
5502 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5503 call assert_equal(bufnr('F1'), l[0].bufnr)
5504 call assert_equal(20, l[0].lnum)
5505 call assert_equal('L20', l[0].text)
5506 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5507 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005508 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005509 %bwipe!
5510endfunc
5511
5512func Test_getqflist_by_idx()
5513 call Xtest_getqflist_by_idx('c')
5514 call Xtest_getqflist_by_idx('l')
5515endfunc
5516
5517" Test for the 'quickfixtextfunc' setting
5518func Tqfexpr(info)
5519 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005520 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005521 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005522 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005523 endif
5524
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005525 let l = []
5526 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5527 let e = qfl[idx]
5528 let s = ''
5529 if e.bufnr != 0
5530 let bname = bufname(e.bufnr)
5531 let s ..= fnamemodify(bname, ':.')
5532 endif
5533 let s ..= '-'
5534 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5535 let s ..= e.text
5536 call add(l, s)
5537 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005538
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005539 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005540endfunc
5541
5542func Xtest_qftextfunc(cchar)
5543 call s:setup_commands(a:cchar)
5544
5545 set efm=%f:%l:%c:%m
5546 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005547 call assert_equal('Tqfexpr', &quickfixtextfunc)
5548 call assert_equal('',
5549 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005550 call g:Xsetlist([
5551 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5552 \ 'end_col': 7, 'text': 'green'},
5553 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5554 \ 'end_col': 8, 'text': 'blue'},
5555 \ ])
5556
Bram Moolenaar858ba062020-05-31 23:11:59 +02005557 Xwindow
5558 call assert_equal('F1-L10C2-green', getline(1))
5559 call assert_equal('F1-L20C4-blue', getline(2))
5560 Xclose
5561 set quickfixtextfunc&vim
5562 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005563 call assert_equal('F1|10 col 2-7| green', getline(1))
5564 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005565 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005566
5567 set efm=%f:%l:%c:%m
5568 set quickfixtextfunc=Tqfexpr
5569 " Update the list with only the cwindow
5570 Xwindow
5571 only
5572 call g:Xsetlist([
5573 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5574 \ 'end_col': 7, 'text': 'red'}
5575 \ ])
5576 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5577 new
5578 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005579 set efm&
5580 set quickfixtextfunc&
5581
5582 " Test for per list 'quickfixtextfunc' setting
5583 func PerQfText(info)
5584 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005585 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005586 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005587 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005588 endif
5589 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005590 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005591 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005592 let l = []
5593 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5594 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5595 endfor
5596 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005597 endfunc
5598 set quickfixtextfunc=Tqfexpr
5599 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5600 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5601 Xwindow
5602 call assert_equal('Line 10, Col 2', getline(1))
5603 call assert_equal('Line 20, Col 4', getline(2))
5604 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005605 call assert_equal(function('PerQfText'),
5606 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005607 " Add entries to the list when the quickfix buffer is hidden
5608 Xaddexpr ['F1:30:6:red']
5609 Xwindow
5610 call assert_equal('Line 30, Col 6', getline(3))
5611 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005612 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005613 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005614 set quickfixtextfunc&
5615 delfunc PerQfText
5616
5617 " Non-existing function
5618 set quickfixtextfunc=Tabc
5619 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5620 call assert_fails("Xwindow", 'E117:')
5621 Xclose
5622 set quickfixtextfunc&
5623
5624 " set option to a non-function
5625 set quickfixtextfunc=[10,\ 20]
5626 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5627 call assert_fails("Xwindow", 'E117:')
5628 Xclose
5629 set quickfixtextfunc&
5630
5631 " set option to a function with different set of arguments
5632 func Xqftext(a, b, c)
5633 return a:a .. a:b .. a:c
5634 endfunc
5635 set quickfixtextfunc=Xqftext
5636 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5637 call assert_fails("Xwindow", 'E119:')
5638 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005639
5640 " set option to a function that returns a list with non-strings
5641 func Xqftext2(d)
5642 return ['one', [], 'two']
5643 endfunc
5644 set quickfixtextfunc=Xqftext2
5645 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5646 \ 'E730:')
5647 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005648 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5649 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005650 Xclose
5651
Bram Moolenaar858ba062020-05-31 23:11:59 +02005652 set quickfixtextfunc&
5653 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005654 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005655
5656 " set the global option to a lambda function
5657 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5658 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5659 Xwindow
5660 call assert_equal(['green', 'blue'], getline(1, '$'))
5661 Xclose
5662 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)
5663 set quickfixtextfunc&
5664
5665 " use a lambda function that returns an empty list
5666 set quickfixtextfunc={d\ ->\ []}
5667 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5668 Xwindow
5669 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5670 \ getline(1, '$'))
5671 Xclose
5672 set quickfixtextfunc&
5673
5674 " use a lambda function that returns a list with empty strings
5675 set quickfixtextfunc={d\ ->\ ['',\ '']}
5676 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5677 Xwindow
5678 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5679 \ getline(1, '$'))
5680 Xclose
5681 set quickfixtextfunc&
5682
5683 " set the per-quickfix list text function to a lambda function
5684 call g:Xsetlist([], ' ',
5685 \ {'quickfixtextfunc' :
5686 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5687 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5688 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5689 Xwindow
5690 call assert_equal('Line 10, Col 2', getline(1))
5691 call assert_equal('Line 20, Col 4', getline(2))
5692 Xclose
5693 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5694 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005695endfunc
5696
5697func Test_qftextfunc()
5698 call Xtest_qftextfunc('c')
5699 call Xtest_qftextfunc('l')
5700endfunc
5701
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005702func Test_qftextfunc_callback()
5703 let lines =<< trim END
5704 set efm=%f:%l:%c:%m
5705
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005706 #" Test for using a function name
5707 LET &qftf = 'g:Tqfexpr'
5708 cexpr "F0:0:0:L0"
5709 copen
5710 call assert_equal('F0-L0C0-L0', getline(1))
5711 cclose
5712
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005713 #" Test for using a function()
5714 set qftf=function('g:Tqfexpr')
5715 cexpr "F1:1:1:L1"
5716 copen
5717 call assert_equal('F1-L1C1-L1', getline(1))
5718 cclose
5719
5720 #" Using a funcref variable to set 'quickfixtextfunc'
5721 VAR Fn = function('g:Tqfexpr')
5722 LET &qftf = Fn
5723 cexpr "F2:2:2:L2"
5724 copen
5725 call assert_equal('F2-L2C2-L2', getline(1))
5726 cclose
5727
5728 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5729 LET Fn = function('g:Tqfexpr')
5730 LET &qftf = string(Fn)
5731 cexpr "F3:3:3:L3"
5732 copen
5733 call assert_equal('F3-L3C3-L3', getline(1))
5734 cclose
5735
5736 #" Test for using a funcref()
5737 set qftf=funcref('g:Tqfexpr')
5738 cexpr "F4:4:4:L4"
5739 copen
5740 call assert_equal('F4-L4C4-L4', getline(1))
5741 cclose
5742
5743 #" Using a funcref variable to set 'quickfixtextfunc'
5744 LET Fn = funcref('g:Tqfexpr')
5745 LET &qftf = Fn
5746 cexpr "F5:5:5:L5"
5747 copen
5748 call assert_equal('F5-L5C5-L5', getline(1))
5749 cclose
5750
5751 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5752 LET Fn = funcref('g:Tqfexpr')
5753 LET &qftf = string(Fn)
5754 cexpr "F5:5:5:L5"
5755 copen
5756 call assert_equal('F5-L5C5-L5', getline(1))
5757 cclose
5758
5759 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005760 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005761 LET optval = substitute(optval, ' ', '\\ ', 'g')
5762 exe "set qftf=" .. optval
5763 cexpr "F6:6:6:L6"
5764 copen
5765 call assert_equal('F6-L6C6-L6', getline(1))
5766 cclose
5767
5768 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005769 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005770 cexpr "F7:7:7:L7"
5771 copen
5772 call assert_equal('F7-L7C7-L7', getline(1))
5773 cclose
5774
5775 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005776 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005777 cexpr "F8:8:8:L8"
5778 copen
5779 call assert_equal('F8-L8C8-L8', getline(1))
5780 cclose
5781
5782 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005783 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005784 LET &qftf = Lambda
5785 cexpr "F9:9:9:L9"
5786 copen
5787 call assert_equal('F9-L9C9-L9', getline(1))
5788 cclose
5789
5790 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005791 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005792 LET &qftf = string(Lambda)
5793 cexpr "F9:9:9:L9"
5794 copen
5795 call assert_equal('F9-L9C9-L9', getline(1))
5796 cclose
5797 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005798 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005799
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005800 " Test for using a script-local function name
5801 func s:TqfFunc2(info)
5802 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5803 return ''
5804 endfunc
5805 let g:TqfFunc2Args = []
5806 set quickfixtextfunc=s:TqfFunc2
5807 cexpr "F10:10:10:L10"
5808 cclose
5809 call assert_equal([1, 1], g:TqfFunc2Args)
5810
5811 let &quickfixtextfunc = 's:TqfFunc2'
5812 cexpr "F11:11:11:L11"
5813 cclose
5814 call assert_equal([1, 1], g:TqfFunc2Args)
5815 delfunc s:TqfFunc2
5816
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005817 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5818 func SetQftfFunc()
5819 let params = {'qftf': function('g:DictQftfFunc')}
5820 let &quickfixtextfunc = params.qftf
5821 endfunc
5822 func g:DictQftfFunc(_) dict
5823 endfunc
5824 call SetQftfFunc()
5825 new
5826 call SetQftfFunc()
5827 bw
5828 call test_garbagecollect_now()
5829 new
5830 set qftf=
5831 wincmd w
5832 set qftf=
5833 :%bw!
5834
5835 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5836 " to cause a crash.
5837 let &qftf = ''
5838 func SetLocalQftfFunc()
5839 let params = {'qftf': function('g:DictQftfFunc')}
5840 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5841 endfunc
5842 call SetLocalQftfFunc()
5843 call test_garbagecollect_now()
5844 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5845 delfunc g:DictQftfFunc
5846 delfunc SetQftfFunc
5847 delfunc SetLocalQftfFunc
5848 set efm&
5849endfunc
5850
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005851" Test for updating a location list for some other window and check that
5852" 'qftextfunc' uses the correct location list.
5853func Test_qftextfunc_other_loclist()
5854 %bw!
5855 call setloclist(0, [], 'f')
5856
5857 " create a window and a location list for it and open the location list
5858 " window
5859 lexpr ['F1:10:12:one', 'F1:20:14:two']
5860 let w1_id = win_getid()
5861 call setloclist(0, [], ' ',
5862 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5863 \ 'quickfixtextfunc':
5864 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5865 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5866 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5867 lwindow
5868 let w2_id = win_getid()
5869
5870 " create another window and a location list for it and open the location
5871 " list window
5872 topleft new
5873 let w3_id = win_getid()
5874 call setloclist(0, [], ' ',
5875 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5876 \ 'quickfixtextfunc':
5877 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5878 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5879 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5880 lwindow
5881 let w4_id = win_getid()
5882
5883 topleft new
5884 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5885 let w5_id = win_getid()
5886
5887 " change the location list for some other window
5888 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5889 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5890 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5891 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5892 \ getbufline(winbufnr(w2_id), 1, '$'))
5893 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5894 \ getbufline(winbufnr(w4_id), 1, '$'))
5895 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5896 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5897 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5898 \ getbufline(winbufnr(w2_id), 1, '$'))
5899 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5900 \ getbufline(winbufnr(w4_id), 1, '$'))
5901
5902 call win_gotoid(w5_id)
5903 lwindow
5904 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5905 \ getline(1, '$'))
5906 %bw!
5907endfunc
5908
Bram Moolenaarec98e932020-06-08 19:35:59 +02005909" Running :lhelpgrep command more than once in a help window, doesn't jump to
5910" the help topic
5911func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005912 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005913 call writefile(['window'], 'Xtestdir/doc/a.txt')
5914 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5915 let save_rtp = &rtp
5916 let &rtp = 'Xtestdir'
5917 lhelpgrep window
5918 lhelpgrep buffer
5919 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5920 lhelpgrep window
5921 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5922 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005923 new | only!
5924endfunc
5925
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005926" Test for the crash fixed by 7.3.715
5927func Test_setloclist_crash()
5928 %bw!
5929 let g:BufNum = bufnr()
5930 augroup QF_Test
5931 au!
5932 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5933 augroup END
5934
5935 try
5936 lvimgrep /.*/ *.mak
5937 catch /E926:/
5938 endtry
5939 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5940 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5941
5942 augroup QF_Test
5943 au!
5944 augroup END
5945 unlet g:BufNum
5946 %bw!
5947endfunc
5948
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005949" Test for adding an invalid entry with the quickfix window open and making
5950" sure that the window contents are not changed
5951func Test_add_invalid_entry_with_qf_window()
5952 call setqflist([], 'f')
5953 cexpr "Xfile1:10:aa"
5954 copen
5955 call setqflist(['bb'], 'a')
5956 call assert_equal(1, line('$'))
5957 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005958 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())
5959
5960 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5961 call assert_equal(1 , line('$'))
5962 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5963 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())
5964
5965 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')
5966 call assert_equal(1 , line('$'))
5967 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5968 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())
5969
5970 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')
5971 call assert_equal(1 , line('$'))
5972 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5973 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())
5974
5975 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')
5976 call assert_equal(1 , line('$'))
5977 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5978 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())
5979
5980 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')
5981 call assert_equal(1 , line('$'))
5982 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5983 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())
5984
5985 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')
5986 call assert_equal(1 , line('$'))
5987 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5988 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())
5989
5990 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')
5991 call assert_equal(1 , line('$'))
5992 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5993 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 +01005994 cclose
5995endfunc
5996
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005997" Test for very weird problem: autocommand causes a failure, resulting opening
5998" the quickfix window to fail. This still splits the window, but otherwise
5999" should not mess up buffers.
6000func Test_quickfix_window_fails_to_open()
6001 CheckScreendump
6002
6003 let lines =<< trim END
6004 anything
6005 try
6006 anything
6007 endtry
6008 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006009 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006010
6011 let lines =<< trim END
6012 split XquickfixFails
6013 silent vimgrep anything %
6014 normal o
6015 au BufLeave * ++once source XquickfixFails
6016 " This will trigger the autocommand, which causes an error, what follows
6017 " is aborted but the window was already split.
6018 silent! cwindow
6019 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006020 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006021 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
6022 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
6023
6024 " clean up
6025 call term_sendkeys(buf, ":bwipe!\<CR>")
6026 call term_wait(buf)
6027 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006028endfunc
6029
Bram Moolenaar2d870f82020-12-05 13:41:01 +01006030" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01006031" is changed.
6032func Xqfbuf_update(cchar)
6033 call s:setup_commands(a:cchar)
6034
6035 Xexpr "F1:1:line1"
6036 Xopen
6037 call assert_equal(['F1|1| line1'], getline(1, '$'))
6038 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6039
6040 " Test setqflist() using the 'lines' key in 'what'
6041 " add a new entry
6042 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
6043 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
6044 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6045 " replace all the entries with a single entry
6046 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
6047 call assert_equal(['F3|3| line3'], getline(1, '$'))
6048 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6049 " remove all the entries
6050 call g:Xsetlist([], 'r', {'lines' : []})
6051 call assert_equal([''], getline(1, '$'))
6052 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6053 " add a new list
6054 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6055 call assert_equal(['F4|4| line4'], getline(1, '$'))
6056 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6057
6058 " Test setqflist() using the 'items' key in 'what'
6059 " add a new entry
6060 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6061 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6062 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6063 " replace all the entries with a single entry
6064 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6065 call assert_equal(['F6|6| line6'], getline(1, '$'))
6066 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6067 " remove all the entries
6068 call g:Xsetlist([], 'r', {'items' : []})
6069 call assert_equal([''], getline(1, '$'))
6070 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6071 " add a new list
6072 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6073 call assert_equal(['F7|7| line7'], getline(1, '$'))
6074 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6075
6076 call g:Xsetlist([], ' ', {})
6077 call assert_equal([''], getline(1, '$'))
6078 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6079
6080 Xclose
6081endfunc
6082
6083func Test_qfbuf_update()
6084 call Xqfbuf_update('c')
6085 call Xqfbuf_update('l')
6086endfunc
6087
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006088func Test_vimgrep_noswapfile()
6089 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006090 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006091 vimgrep two Xgreppie
6092 call assert_equal('two', getline('.'))
6093
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006094 set swapfile
6095endfunc
6096
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006097" Test for the :vimgrep 'f' flag (fuzzy match)
6098func Xvimgrep_fuzzy_match(cchar)
6099 call s:setup_commands(a:cchar)
6100
6101 Xvimgrep /three one/f Xfile*
6102 let l = g:Xgetlist()
6103 call assert_equal(2, len(l))
6104 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6105 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6106 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6107 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6108
6109 Xvimgrep /the/f Xfile*
6110 let l = g:Xgetlist()
6111 call assert_equal(3, len(l))
6112 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6113 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6114 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6115 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6116 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6117 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6118
6119 Xvimgrep /aaa/fg Xfile*
6120 let l = g:Xgetlist()
6121 call assert_equal(4, len(l))
6122 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6123 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6124 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6125 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6126 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6127 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6128 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6129 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6130
6131 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6132endfunc
6133
6134func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006135 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6136 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006137 call Xvimgrep_fuzzy_match('c')
6138 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006139endfunc
6140
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006141func Test_locationlist_open_in_newtab()
6142 call s:create_test_file('Xqftestfile1')
6143 call s:create_test_file('Xqftestfile2')
6144 call s:create_test_file('Xqftestfile3')
6145
6146 %bwipe!
6147
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006148 let lines =<< trim END
6149 Xqftestfile1:5:Line5
6150 Xqftestfile2:10:Line10
6151 Xqftestfile3:16:Line16
6152 END
6153 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006154
6155 silent! llast
6156 call assert_equal(1, tabpagenr('$'))
6157 call assert_equal('Xqftestfile3', bufname())
6158
6159 set switchbuf=newtab
6160
6161 silent! lfirst
6162 call assert_equal(2, tabpagenr('$'))
6163 call assert_equal('Xqftestfile1', bufname())
6164
6165 silent! lnext
6166 call assert_equal(3, tabpagenr('$'))
6167 call assert_equal('Xqftestfile2', bufname())
6168
6169 call delete('Xqftestfile1')
6170 call delete('Xqftestfile2')
6171 call delete('Xqftestfile3')
6172 set switchbuf&vim
6173
6174 %bwipe!
6175endfunc
6176
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006177" Test for win_gettype() in quickfix and location list windows
6178func Test_win_gettype()
6179 copen
6180 call assert_equal("quickfix", win_gettype())
6181 let wid = win_getid()
6182 wincmd p
6183 call assert_equal("quickfix", win_gettype(wid))
6184 cclose
6185 lexpr ''
6186 lopen
6187 call assert_equal("loclist", win_gettype())
6188 let wid = win_getid()
6189 wincmd p
6190 call assert_equal("loclist", win_gettype(wid))
6191 lclose
6192endfunc
6193
Christian Brabandt0b226f62021-12-01 10:54:24 +00006194fun Test_vimgrep_nomatch()
6195 call XexprTests('c')
6196 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6197 copen
6198 if has("win32")
6199 call assert_fails('vimgrep foo *.zzz', 'E479:')
6200 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'}]
6201 else
6202 call assert_fails('vimgrep foo *.zzz', 'E480:')
6203 let expected = []
6204 endif
6205 call assert_equal(expected, getqflist())
6206 cclose
6207endfunc
6208
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006209" Test for opening the quickfix window in two tab pages and then closing one
6210" of the quickfix windows. This should not make the quickfix buffer unlisted.
6211" (github issue #9300).
6212func Test_two_qf_windows()
6213 cexpr "F1:1:line1"
6214 copen
6215 tabnew
6216 copen
6217 call assert_true(&buflisted)
6218 cclose
6219 tabfirst
6220 call assert_true(&buflisted)
6221 let bnum = bufnr()
6222 cclose
6223 " if all the quickfix windows are closed, then buffer should be unlisted.
6224 call assert_false(buflisted(bnum))
6225 %bw!
6226
6227 " Repeat the test for a location list
6228 lexpr "F2:2:line2"
6229 lopen
6230 let bnum = bufnr()
6231 tabnew
6232 exe "buffer" bnum
6233 tabfirst
6234 lclose
6235 tablast
6236 call assert_true(buflisted(bnum))
6237 tabclose
6238 lopen
6239 call assert_true(buflisted(bnum))
6240 lclose
6241 call assert_false(buflisted(bnum))
6242 %bw!
6243endfunc
6244
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006245" Weird sequence of commands that caused entering a wiped-out buffer
6246func Test_lopen_bwipe()
6247 func R()
6248 silent! tab lopen
6249 e x
6250 silent! lfile
6251 endfunc
6252
6253 cal R()
6254 cal R()
6255 cal R()
6256 bw!
6257 delfunc R
6258endfunc
6259
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006260" Another sequence of commands that caused all buffers to be wiped out
6261func Test_lopen_bwipe_all()
6262 let lines =<< trim END
6263 func R()
6264 silent! tab lopen
6265 e foo
6266 silent! lfile
6267 endfunc
6268 cal R()
6269 exe "norm \<C-W>\<C-V>0"
6270 cal R()
6271 bwipe
6272
6273 call writefile(['done'], 'Xresult')
6274 qall!
6275 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006276 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006277 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6278 call assert_equal(['done'], readfile('Xresult'))
6279 endif
6280
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006281 call delete('Xresult')
6282endfunc
6283
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006284" Test for calling setqflist() function recursively
6285func Test_recursive_setqflist()
6286 augroup QF_Test
6287 au!
6288 autocmd BufWinEnter quickfix call setqflist([], 'r')
6289 augroup END
6290
6291 copen
6292 call assert_fails("call setqflist([], 'a')", 'E952:')
6293
6294 augroup QF_Test
6295 au!
6296 augroup END
6297 %bw!
6298endfunc
6299
6300" Test for failure to create a new window when selecting a file from the
6301" quickfix window
6302func Test_cwindow_newwin_fails()
6303 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6304 cwindow
6305 only
6306 let qf_wid = win_getid()
6307 " create the maximum number of scratch windows
6308 let hor_win_count = (&lines - 1)/2
6309 let hor_split_count = hor_win_count - 1
6310 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6311 call win_gotoid(qf_wid)
6312 call assert_fails('exe "normal \<CR>"', 'E36:')
6313 %bw!
6314endfunc
6315
6316" Test for updating the location list when only the location list window is
6317" present and the corresponding file window is closed.
6318func Test_loclist_update_with_llwin_only()
6319 %bw!
6320 new
6321 wincmd w
6322 lexpr ["Xfile1:1:Line1"]
6323 lopen
6324 wincmd p
6325 close
6326 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6327 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6328 %bw!
6329endfunc
6330
6331" Test for getting the quickfix list after a buffer with an error is wiped out
6332func Test_getqflist_wiped_out_buffer()
6333 %bw!
6334 cexpr ["Xtest1:34:Wiped out"]
6335 let bnum = bufnr('Xtest1')
6336 call assert_equal(bnum, getqflist()[0].bufnr)
6337 bw Xtest1
6338 call assert_equal(0, getqflist()[0].bufnr)
6339 %bw!
6340endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006341
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006342" Test for the status message that is displayed when opening a new quickfix
6343" list
6344func Test_qflist_statusmsg()
6345 cexpr "1\n2"
6346 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6347 call assert_equal('(4 of 4): msg', v:statusmsg)
6348 call setqflist([], 'f')
6349 %bw!
6350
6351 " When creating a new quickfix list, if an autocmd changes the quickfix list
6352 " in the stack, then an error message should be displayed.
6353 augroup QF_Test
6354 au!
6355 au BufEnter test_quickfix.vim colder
6356 augroup END
6357 cexpr "1\n2"
6358 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6359 call setqflist([], 'f')
6360 augroup QF_Test
6361 au!
6362 augroup END
6363 %bw!
6364
6365 augroup QF_Test
6366 au!
6367 au BufEnter test_quickfix.vim caddexpr "4"
6368 augroup END
6369 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6370 call setqflist([], 'f')
6371 augroup QF_Test
6372 au!
6373 augroup END
6374 %bw!
6375endfunc
6376
Bram Moolenaard6c67622022-08-24 20:07:22 +01006377func Test_quickfixtextfunc_recursive()
6378 func s:QFTfunc(o)
6379 cgete '0'
6380 endfunc
6381 copen
6382 let &quickfixtextfunc = 's:QFTfunc'
6383 cex ""
6384
6385 let &quickfixtextfunc = ''
6386 cclose
6387endfunc
6388
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006389" Test for replacing the location list from an autocmd. This used to cause a
6390" read from freed memory.
6391func Test_loclist_replace_autocmd()
6392 %bw!
6393 call setloclist(0, [], 'f')
6394 let s:bufnr = bufnr()
6395 cal setloclist(0, [{'0': 0, '': ''}])
6396 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6397 lopen
6398 try
6399 exe "norm j\<CR>"
6400 catch
6401 endtry
6402 lnext
6403 %bw!
6404 call setloclist(0, [], 'f')
6405endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006406
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006407" Test for a very long error line and a very long information line
6408func Test_very_long_error_line()
6409 let msg = repeat('abcdefghijklmn', 146)
6410 let emsg = 'Xlonglines.c:1:' . msg
6411 call writefile([msg, emsg], 'Xerror', 'D')
6412 cfile Xerror
6413 cwindow
6414 call assert_equal($'|| {msg}', getline(1))
6415 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6416 cclose
6417
6418 let l = execute('clist!')->split("\n")
6419 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6420
6421 let l = execute('cc')->split("\n")
6422 call assert_equal([$'(2 of 2): {msg}'], l)
6423
6424 call setqflist([], 'f')
6425endfunc
6426
6427" In the quickfix window, spaces at the beginning of an informational line
6428" should not be removed but should be removed from an error line.
6429func Test_info_line_with_space()
6430 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6431 \ ' 20 | Afunc():', '', ' | ^']
6432 copen
6433 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6434 \ '|| 20 | Afunc():', '|| ',
6435 \ '|| | ^'], getline(1, '$'))
6436 cclose
6437
6438 let l = execute('clist!')->split("\n")
6439 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6440 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6441
6442 call setqflist([], 'f')
6443endfunc
6444
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006445func s:QfTf(_)
6446endfunc
6447
6448func Test_setqflist_cb_arg()
6449 " This was changing the callback name in the dictionary.
6450 let d = #{quickfixtextfunc: 's:QfTf'}
6451 call setqflist([], 'a', d)
6452 call assert_equal('s:QfTf', d.quickfixtextfunc)
6453
6454 call setqflist([], 'f')
6455endfunc
6456
zeertzjqa40c0bc2023-05-27 14:10:08 +01006457" Test that setqflist() should not prevent :stopinsert from working
6458func Test_setqflist_stopinsert()
6459 new
6460 call setqflist([], 'f')
6461 copen
6462 cclose
6463 func StopInsert()
6464 stopinsert
6465 call setqflist([{'text': 'foo'}])
6466 return ''
6467 endfunc
6468
6469 call setline(1, 'abc')
6470 call cursor(1, 1)
6471 call feedkeys("i\<C-R>=StopInsert()\<CR>$", 'tnix')
6472 call assert_equal('foo', getqflist()[0].text)
6473 call assert_equal([0, 1, 3, 0, v:maxcol], getcurpos())
6474 call assert_equal(['abc'], getline(1, '$'))
6475
6476 delfunc StopInsert
6477 call setqflist([], 'f')
6478 bwipe!
6479endfunc
Bram Moolenaard0fab102022-10-20 16:03:33 +01006480
Shane Harper5bf04282023-06-07 19:09:57 +01006481func Test_quickfix_buffer_contents()
6482 call setqflist([{'filename':'filename', 'pattern':'pattern', 'text':'text'}])
6483 copen
6484 call assert_equal(['filename|pattern| text'], getline(1, '$')) " The assert failed with Vim v9.0.0736; '| text' did not appear after the pattern.
6485 call setqflist([], 'f')
6486endfunc
6487
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006488func XquickfixUpdateTests(cchar)
6489 call s:setup_commands(a:cchar)
6490
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006491 " Setup: populate a couple buffers
6492 new
6493 call setline(1, range(1, 5))
6494 let b1 = bufnr()
6495 new
6496 call setline(1, range(1, 3))
6497 let b2 = bufnr()
6498 " Setup: set a quickfix list.
6499 let items = [{'bufnr': b1, 'lnum': 1}, {'bufnr': b1, 'lnum': 2}, {'bufnr': b2, 'lnum': 1}, {'bufnr': b2, 'lnum': 2}]
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006500 call g:Xsetlist(items)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006501
6502 " Open the quickfix list, select the third entry.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006503 Xopen
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006504 exe "normal jj\<CR>"
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006505 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006506
6507 " Update the quickfix list. Make sure the third entry is still selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006508 call g:Xsetlist([], 'u', { 'items': items })
6509 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006510
6511 " Update the quickfix list again, but this time with missing line number
6512 " information. Confirm that we keep the current buffer selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006513 call g:Xsetlist([{'bufnr': b1}, {'bufnr': b2}], 'u')
6514 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
6515
6516 Xclose
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006517
6518 " Cleanup the buffers we allocated during this test.
6519 %bwipe!
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006520endfunc
6521
6522" Test for updating a quickfix list using the "u" flag in setqflist()
6523func Test_quickfix_update()
6524 call XquickfixUpdateTests('c')
6525 call XquickfixUpdateTests('l')
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006526endfunc
6527
6528func Test_quickfix_update_with_missing_coordinate_info()
6529 new
6530 call setline(1, range(1, 5))
6531 let b1 = bufnr()
6532
6533 new
6534 call setline(1, range(1, 3))
6535 let b2 = bufnr()
6536
6537 new
6538 call setline(1, range(1, 2))
6539 let b3 = bufnr()
6540
6541 " Setup: set a quickfix list with no coordinate information at all.
6542 call setqflist([{}, {}])
6543
6544 " Open the quickfix list, select the second entry.
6545 copen
6546 exe "normal j\<CR>"
6547 call assert_equal(2, getqflist({'idx' : 0}).idx)
6548
6549 " Update the quickfix list. As the previously selected entry has no
6550 " coordinate information, we expect the first entry to now be selected.
6551 call setqflist([{'bufnr': b1}, {'bufnr': b2}, {'bufnr': b3}], 'u')
6552 call assert_equal(1, getqflist({'idx' : 0}).idx)
6553
6554 " Select the second entry in the quickfix list.
6555 copen
6556 exe "normal j\<CR>"
6557 call assert_equal(2, getqflist({'idx' : 0}).idx)
6558
6559 " Update the quickfix list again. The currently selected entry does not have
6560 " a line number, but we should keep the file selected.
6561 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 3}, {'bufnr': b3}], 'u')
6562 call assert_equal(2, getqflist({'idx' : 0}).idx)
6563
6564 " Update the quickfix list again. The currently selected entry (bufnr=b2, lnum=3)
6565 " is no longer present. We should pick the nearest entry.
6566 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 1}, {'bufnr': b2, 'lnum': 4}], 'u')
6567 call assert_equal(3, getqflist({'idx' : 0}).idx)
6568
6569 " Set the quickfix list again, with a specific column number. The currently selected entry doesn't have a
6570 " column number, but they share a line number.
6571 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 5}, {'bufnr': b2, 'lnum': 4, 'col': 6}], 'u')
6572 call assert_equal(2, getqflist({'idx' : 0}).idx)
6573
6574 " Set the quickfix list again. The currently selected column number (6) is
6575 " no longer present. We should select the nearest column number.
6576 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 2}, {'bufnr': b2, 'lnum': 4, 'col': 4}], 'u')
6577 call assert_equal(3, getqflist({'idx' : 0}).idx)
6578
6579 " Now set the quickfix list, but without columns. We should still pick the
6580 " same line.
6581 call setqflist([{'bufnr': b2, 'lnum': 3}, {'bufnr': b2, 'lnum': 4}, {'bufnr': b2, 'lnum': 4}], 'u')
6582 call assert_equal(2, getqflist({'idx' : 0}).idx)
6583
6584 " Cleanup the buffers we allocated during this test.
6585 %bwipe!
6586endfunc
6587
Yegappan Lakshmananb7318002023-10-25 20:50:28 +02006588" Test for "%b" in "errorformat"
6589func Test_efm_format_b()
6590 call setqflist([], 'f')
6591 new
6592 call setline(1, ['1: abc', '1: def', '1: ghi'])
6593 let b1 = bufnr()
6594 new
6595 call setline(1, ['2: abc', '2: def', '2: ghi'])
6596 let b2 = bufnr()
6597 new
6598 call setline(1, ['3: abc', '3: def', '3: ghi'])
6599 let b3 = bufnr()
6600 new
6601 let lines =<< trim eval END
6602 {b1}:1:1
6603 {b2}:2:2
6604 {b3}:3:3
6605 END
6606 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c'})
6607 cfirst
6608 call assert_equal([b1, 1, 1], [bufnr(), line('.'), col('.')])
6609 cnext
6610 call assert_equal([b2, 2, 2], [bufnr(), line('.'), col('.')])
6611 cnext
6612 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6613 enew!
6614
6615 " Use a non-existing buffer
6616 let lines =<< trim eval END
6617 9991:1:1:m1
6618 9992:2:2:m2
6619 {b3}:3:3:m3
6620 END
6621 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c:%m'})
6622 cfirst | cnext
6623 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6624 " Lines with non-existing buffer numbers should be used as non-error lines
6625 call assert_equal([
6626 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6627 \ module: '', type: '', end_col: 0, col: 0, text: '9991:1:1:m1'},
6628 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6629 \ module: '', type: '', end_col: 0, col: 0, text: '9992:2:2:m2'},
6630 \ #{lnum: 3, bufnr: b3, end_lnum: 0, pattern: '', valid: 1, vcol: 0,
6631 \ nr: -1, module: '', type: '', end_col: 0, col: 3, text: 'm3'}],
6632 \ getqflist())
6633 %bw!
6634 call setqflist([], 'f')
6635endfunc
6636
Christian Brabandt652c8212024-04-29 20:36:49 +02006637func XbufferTests_range(cchar)
6638 call s:setup_commands(a:cchar)
6639
6640 enew!
6641 let lines =<< trim END
6642 Xtestfile7:700:10:Line 700
6643 Xtestfile8:800:15:Line 800
6644 END
6645 silent! call setline(1, lines)
6646 norm! Vy
6647 " Note: We cannot use :Xbuffer here,
6648 " it doesn't properly fail, so we need to
6649 " test using the raw c/l commands.
6650 " (also further down)
6651 if (a:cchar == 'c')
6652 exe "'<,'>cbuffer!"
6653 else
6654 exe "'<,'>lbuffer!"
6655 endif
6656 let l = g:Xgetlist()
6657 call assert_true(len(l) == 1 &&
6658 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700')
6659
6660 enew!
6661 let lines =<< trim END
6662 Xtestfile9:900:55:Line 900
6663 Xtestfile10:950:66:Line 950
6664 END
6665 silent! call setline(1, lines)
6666 if (a:cchar == 'c')
6667 1cgetbuffer
6668 else
6669 1lgetbuffer
6670 endif
6671 let l = g:Xgetlist()
6672 call assert_true(len(l) == 1 &&
6673 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900')
6674
6675 enew!
6676 let lines =<< trim END
6677 Xtestfile11:700:20:Line 700
6678 Xtestfile12:750:25:Line 750
6679 END
6680 silent! call setline(1, lines)
6681 if (a:cchar == 'c')
6682 1,1caddbuffer
6683 else
6684 1,1laddbuffer
6685 endif
6686 let l = g:Xgetlist()
6687 call assert_true(len(l) == 2 &&
6688 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
6689 \ l[1].lnum == 700 && l[1].col == 20 && l[1].text ==# 'Line 700')
6690 enew!
6691
6692 " Check for invalid range
6693 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
6694 " commands. So directly call the commands.
6695 if (a:cchar == 'c')
6696 call assert_fails('900,999caddbuffer', 'E16:')
6697 else
6698 call assert_fails('900,999laddbuffer', 'E16:')
6699 endif
6700endfunc
6701
6702func Test_cbuffer_range()
6703 call XbufferTests_range('c')
6704 call XbufferTests_range('l')
6705endfunc
6706
zeertzjq5df3cb22024-10-07 21:05:06 +02006707" Test for displaying fname passed from setqflist() when the names include
6708" hard links to prevent seemingly duplicate entries.
Austin Chang29822992024-10-03 10:50:05 +02006709func Xtest_hardlink_fname(cchar)
6710 call s:setup_commands(a:cchar)
6711 %bwipe
6712 " Create a sample source file
6713 let lines =<< trim END
6714 void sample() {}
6715 int main() { sample(); return 0; }
6716 END
6717 call writefile(lines, 'test_qf_hardlink1.c', 'D')
6718 defer delete('test_qf_hardlink1.c')
6719 defer delete('test_qf_hardlink2.c')
6720 call system('ln test_qf_hardlink1.c test_qf_hardlink2.c')
6721 if v:shell_error
6722 throw 'Skipped: ln throws error on this platform'
6723 endif
6724 call g:Xsetlist([], 'f')
6725 " Make a qflist that contains the file and it's hard link
6726 " like how LSP plugins set response into qflist
6727 call g:Xsetlist([{'filename' : 'test_qf_hardlink1.c', 'lnum' : 1},
6728 \ {'filename' : 'test_qf_hardlink2.c', 'lnum' : 1}], ' ')
6729 Xopen
6730 " Ensure that two entries are displayed with different name
6731 " so that they aren't seen as duplication.
6732 call assert_equal(['test_qf_hardlink1.c|1| ',
6733 \ 'test_qf_hardlink2.c|1| '], getline(1, '$'))
6734 Xclose
6735endfunc
6736
6737func Test_hardlink_fname()
6738 CheckUnix
6739 CheckExecutable ln
6740 call Xtest_hardlink_fname('c')
6741 call Xtest_hardlink_fname('l')
6742endfunc
6743
64-bitman88d41ab2025-04-06 17:20:39 +02006744" Test for checking if correct number of tests are deleted
6745" and current list stays the same after setting Xhistory
6746" to a smaller number. Do roughly the same for growing the stack.
6747func Xtest_resize_list_stack(cchar)
6748 call s:setup_commands(a:cchar)
6749 Xsethist 100
6750
6751 for i in range(1, 100)
6752 Xexpr string(i)
6753 endfor
6754 Xopen
6755 call assert_equal(g:Xgetlist({'nr': '$'}).nr, 100)
6756 call assert_equal("|| 100", getline(1))
6757 Xsethist 8
6758 call assert_equal("|| 100", getline(1))
6759 Xolder 5
6760 call assert_equal("|| 95", getline(1))
6761 Xsethist 6
6762 call assert_equal("|| 95", getline(1))
6763 Xsethist 1
6764 call assert_equal("|| 100", getline(1))
6765
6766 " grow array again
6767 Xsethist 100
6768 for i in range(1, 99)
6769 Xexpr string(i)
6770 endfor
6771 call assert_equal("|| 99", getline(1))
6772 Xolder 99
6773 call assert_equal("|| 100", getline(1))
6774
6775 Xsethistdefault
6776endfunc
6777
6778func Test_resize_list_stack()
6779 call Xtest_resize_list_stack('c')
6780 call Xtest_resize_list_stack('l')
6781endfunc
6782
6783" Test to check if order of lists is from
6784" oldest at the bottom to newest at the top
6785func Xtest_Xhistory_check_order(cchar)
6786
6787 Xsethist 100
6788
6789 for i in range(1, 100)
6790 Xexpr string(i)
6791 endfor
6792
6793 Xopen
6794 for i in range(100, 1, -1)
6795 let l:ret = assert_equal("|| " .. i, getline(1))
6796
6797 if ret == 1 || i == 1
6798 break
6799 endif
6800 Xolder
6801 endfor
6802
6803 for i in range(1, 50)
6804 Xexpr string(i)
6805 endfor
6806
6807 for i in range(50, 1, -1)
6808 let l:ret = assert_equal("|| " .. i, getline(1))
6809
6810 if ret == 1 || i == 50
6811 break
6812 endif
6813 Xolder
6814 endfor
6815
6816 for i in range(50, 1, -1)
6817 let l:ret = assert_equal("|| " .. i, getline(1))
6818
6819 if ret == 1 || i == 50
6820 break
6821 endif
6822 Xolder
6823 endfor
6824
6825 Xsethistdefault
6826endfunc
6827
6828func Test_set_history_to_check_order()
6829 call Xtest_Xhistory_check_order('c')
6830 call Xtest_Xhistory_check_order('l')
6831endfunc
6832
6833" Check if 'lhistory' is the same between the location list window
6834" and associated normal window
6835func Test_win_and_loc_synced()
6836 new
6837 set lhistory=2
6838 lexpr "Text"
6839 lopen
6840
6841 " check if lhistory is synced when modified inside the
6842 " location list window
6843 setlocal lhistory=1
6844 wincmd k
6845 call assert_equal(&lhistory, 1)
6846
6847 " check if lhistory is synced when modified inside the
6848 " normal window
6849 setlocal lhistory=10
6850 lopen
6851 call assert_equal(&lhistory, 10)
6852
6853 wincmd k
6854 lclose
6855 wincmd q
6856
6857 set lhistory&
6858endfunc
6859
6860" Test if setting the lhistory of one window doesn't affect the other
6861func Test_two_win_are_independent_of_history()
6862 setlocal lhistory=10
6863 new
6864 setlocal lhistory=20
6865 wincmd w
6866 call assert_equal(&lhistory, 10)
6867 wincmd w
6868 wincmd q
6869
6870 set lhistory&
6871endfunc
6872
6873" Test if lhistory is copied over to a new window
6874func Test_lhistory_copied_over()
6875 setlocal lhistory=3
6876 split
6877 call assert_equal(&lhistory, 3)
6878 wincmd q
6879
6880 set lhistory&
6881endfunc
6882
6883" Test if error occurs when given invalid history number
6884func Xtest_invalid_history_num(cchar)
6885 call s:setup_commands(a:cchar)
6886
6887 call assert_fails('Xsethist -10000', "E1542:")
6888 call assert_fails('Xsethist 10000', "E1543:")
6889 Xsethistdefault
6890endfunc
6891
6892func Test_invalid_history_num()
6893 call Xtest_invalid_history_num('c')
6894 call Xtest_invalid_history_num('l')
6895endfunc
6896
6897" Test if chistory and lhistory don't affect each other
6898func Test_chi_and_lhi_are_independent()
6899 set chistory=100
6900 set lhistory=100
6901
6902 set chistory=10
6903 call assert_equal(&lhistory, 100)
6904
6905 set lhistory=1
6906 call assert_equal(&chistory, 10)
6907
6908 set chistory&
6909 set lhistory&
6910endfunc
6911
Christian Brabandtce80c592025-03-28 19:13:32 +01006912func Test_quickfix_close_buffer_crash()
6913 new
6914 lexpr 'test' | lopen
6915 wincmd k
6916 lclose
6917 wincmd q
6918endfunc
6919
Sean Dewarb4074ea2025-05-10 14:30:36 +02006920func Test_vimgrep_dummy_buffer_crash()
6921 augroup DummyCrash
6922 autocmd!
6923 " Make the dummy buffer non-current, but still open in a window.
6924 autocmd BufReadCmd * ++once let s:dummy_buf = bufnr()
6925 \| split | wincmd p | enew
6926
6927 " Autocmds from cleaning up the dummy buffer in this case should be blocked.
6928 autocmd BufWipeout *
6929 \ call assert_notequal(s:dummy_buf, str2nr(expand('<abuf>')))
6930 augroup END
6931
6932 silent! vimgrep /./ .
6933 redraw! " Window to freed dummy buffer used to remain; heap UAF.
6934 call assert_equal([], win_findbuf(s:dummy_buf))
6935 call assert_equal(0, bufexists(s:dummy_buf))
6936
6937 unlet! s:dummy_buf
6938 autocmd! DummyCrash
6939 %bw!
6940endfunc
6941
Sean Dewar270124f2025-05-10 14:33:28 +02006942func Test_vimgrep_dummy_buffer_keep()
6943 augroup DummyKeep
6944 autocmd!
6945 " Trigger a wipe of the dummy buffer by aborting script processing. Prevent
6946 " wiping it by splitting it from the autocmd window into an only window.
6947 autocmd BufReadCmd * ++once let s:dummy_buf = bufnr()
6948 \| tab split | call interrupt()
6949 augroup END
6950
6951 call assert_fails('vimgrep /./ .')
6952 call assert_equal(1, bufexists(s:dummy_buf))
6953 " Ensure it's no longer considered a dummy; should be able to switch to it.
6954 execute s:dummy_buf 'sbuffer'
6955
6956 unlet! s:dummy_buf
6957 autocmd! DummyKeep
6958 %bw!
6959endfunc
6960
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006961" vim: shiftwidth=2 sts=2 expandtab