blob: dc2a2a4c5ce34e6b43eb1a8848b3845b3cf53834 [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00004import './vim9.vim' as v9
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
64-bitman88d41ab2025-04-06 17:20:39 +020046 command! -nargs=1 Xsethist <mods>set chistory=<args>
47 command! -nargs=0 Xsethistdefault <mods>set chistory&
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020048 let g:Xgetlist = function('getqflist')
49 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020050 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020051 else
52 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
53 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020054 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020055 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010057 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020059 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020060 command! -nargs=* Xclose <mods>lclose <args>
61 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
62 command! -nargs=* Xgetfile <mods>lgetfile <args>
63 command! -nargs=* Xaddfile <mods>laddfile <args>
64 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
65 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
66 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
67 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020068 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
69 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020070 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
71 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020072 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020073 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020074 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020075 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010076 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020077 command! -nargs=* Xgrep <mods> lgrep <args>
78 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
79 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010080 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020081 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
82 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020083 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
84 command! -count=1 -nargs=0 Xafter <mods><count>lafter
64-bitman88d41ab2025-04-06 17:20:39 +020085 command! -nargs=1 Xsethist <mods>set lhistory=<args>
86 command! -nargs=1 Xsetlocalhist <mods>setlocal lhistory=<args>
87 command! -nargs=0 Xsethistdefault <mods>set lhistory&
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088 let g:Xgetlist = function('getloclist', [0])
89 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020090 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020091 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010092endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020093
Bram Moolenaara5d78d12021-12-15 12:28:22 +000094" This must be run before any error lists are created.
95func Test_AA_cc_no_errors()
96 call assert_fails('cc', 'E42:')
97 call assert_fails('ll', 'E42:')
98endfunc
99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100100" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100101func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200102 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100103
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200104 if a:cchar == 'l'
105 call assert_fails('llist', 'E776:')
106 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100107 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200108 Xgetexpr []
109 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100110 call assert_true(v:errmsg ==# 'E42: No Errors')
111
112 " Populate the list and then try
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100113 let lines =<< trim END
114 non-error 1
115 Xtestfile1:1:3:Line1
116 non-error 2
117 Xtestfile2:2:2:Line2
118 non-error| 3
119 Xtestfile3:3:1:Line3
120 END
121 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100122
123 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100124 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100125 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
126 \ ' 4 Xtestfile2:2 col 2: Line2',
127 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
128
129 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100130 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100131 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
132 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100133 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100134
135 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100136 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100137 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
138 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
139
Bram Moolenaaree85df32017-03-19 14:19:50 +0100140 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100141 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
142
Bram Moolenaaree85df32017-03-19 14:19:50 +0100143 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100144 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
145
Bram Moolenaaree85df32017-03-19 14:19:50 +0100146 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100147 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
148 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100149
150 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100151 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100152 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
153 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100154
thinca6864efa2021-06-19 20:45:20 +0200155 " Ranged entries
156 call g:Xsetlist([{'lnum':10,'text':'Line1'},
157 \ {'lnum':20,'col':10,'text':'Line2'},
158 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
159 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
160 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
161 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
162 let l = split(execute('Xlist', ""), "\n")
163 call assert_equal([' 1:10: Line1',
164 \ ' 2:20 col 10: Line2',
165 \ ' 3:30 col 15-20: Line3',
166 \ ' 4:40-45: Line4',
167 \ ' 5:50-55 col 15: Line5',
168 \ ' 6:60-65 col 25-35: Line6'], l)
169
Bram Moolenaaree85df32017-03-19 14:19:50 +0100170 " Different types of errors
171 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
172 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
173 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
174 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
Shane Harper5bf04282023-06-07 19:09:57 +0100175 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55},
176 \ {'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 +0100177 let l = split(execute('Xlist', ""), "\n")
178 call assert_equal([' 1:10 col 5 warning 11: Warning',
179 \ ' 2:20 col 10 error 22: Error',
180 \ ' 3:30 col 15 info 33: Info',
181 \ ' 4:40 col 20 x 44: Other',
Shane Harper5bf04282023-06-07 19:09:57 +0100182 \ ' 5:50 col 25 55: one',
183 \ ' 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 +0100184
Bram Moolenaard76ce852018-05-01 15:02:04 +0200185 " Test for module names, one needs to explicitly set `'valid':v:true` so
186 call g:Xsetlist([
187 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
188 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
189 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
190 let l = split(execute('Xlist', ""), "\n")
191 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
192 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
193 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
194
Bram Moolenaar5f30e262022-07-28 11:56:01 +0100195 " Very long line should be displayed.
196 let text = 'Line' .. repeat('1234567890', 130)
197 let lines = ['Xtestfile9:2:9:' .. text]
198 Xgetexpr lines
199
200 let l = split(execute('Xlist', ''), "\n")
201 call assert_equal([' 1 Xtestfile9:2 col 9: ' .. text] , l)
202
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100203 " For help entries in the quickfix list, only the filename without directory
204 " should be displayed
205 Xhelpgrep setqflist()
206 let l = split(execute('Xlist 1', ''), "\n")
207 call assert_match('^ 1 [^\\/]\{-}:', l[0])
208
Bram Moolenaaree85df32017-03-19 14:19:50 +0100209 " Error cases
210 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100211endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100212
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100213func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100214 call XlistTests('c')
215 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100216endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100217
218" Tests for the :colder, :cnewer, :lolder and :lnewer commands
219" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100220" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100221func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200222 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200224 if a:cchar == 'l'
225 " No location list for the current window
226 call assert_fails('lolder', 'E776:')
227 call assert_fails('lnewer', 'E776:')
228 endif
229
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200230 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200231 call g:Xsetlist(list)
232
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100233 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200234 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100235 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
236
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200237 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100238 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
239
240 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200241 Xgetexpr ['Xtestfile1:1:3:Line1']
242 Xgetexpr ['Xtestfile2:2:2:Line2']
243 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100244
245 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200246 Xolder
247 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100248 call assert_equal('Line2', l[0].text)
249
250 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200251 Xnewer
252 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253 call assert_equal('Line3', l[0].text)
254
255 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200256 Xolder 2
257 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100258 call assert_equal('Line1', l[0].text)
259
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200260 Xnewer 2
261 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100262 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100263endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100264
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100265func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100266 call XageTests('c')
267 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100268endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
270" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
271" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100272func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200273 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100274
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200275 " Opening the location list window without any errors should fail
276 if a:cchar == 'l'
277 call assert_fails('lopen', 'E776:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000278 call assert_fails('lwindow', 'E776:')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200279 endif
280
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100281 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200282 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100283
284 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200285 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100286 call assert_true(winnr('$') == 1)
287
288 " Create a list with valid entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100289 let lines =<< trim END
290 Xtestfile1:1:3:Line1
291 Xtestfile2:2:2:Line2
292 Xtestfile3:3:1:Line3
293 END
294 Xgetexpr lines
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100295
296 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200297 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100298 call assert_true(winnr('$') == 2 && winnr() == 2 &&
299 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200300 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100301
302 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200303 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100304 call assert_true(winnr('$') == 1)
305
306 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200307 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100308
309 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200310 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100311 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200312 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100313
314 " Opening the window again, should move the cursor to that window
315 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200316 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100317 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200318 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100319 \ getline('.') ==# '|| non-error 1')
320
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100321 " :cnext in quickfix window should move to the next entry
322 Xnext
323 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100324
325 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200326 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100327 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200328
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100329 " Specifying the width should adjust the width for a vertically split
330 " quickfix window.
331 vert Xopen
332 call assert_equal(10, winwidth(0))
333 vert Xopen 12
334 call assert_equal(12, winwidth(0))
335 Xclose
336
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200337 " Horizontally or vertically splitting the quickfix window should create a
338 " normal window/buffer
339 Xopen
340 wincmd s
341 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
342 call assert_equal(0, getwininfo(win_getid())[0].loclist)
343 call assert_notequal('quickfix', &buftype)
344 close
345 Xopen
346 wincmd v
347 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
348 call assert_equal(0, getwininfo(win_getid())[0].loclist)
349 call assert_notequal('quickfix', &buftype)
350 close
351 Xopen
352 Xclose
353
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200354 if a:cchar == 'c'
355 " Opening the quickfix window in multiple tab pages should reuse the
356 " quickfix buffer
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100357 let lines =<< trim END
358 Xtestfile1:1:3:Line1
359 Xtestfile2:2:2:Line2
360 Xtestfile3:3:1:Line3
361 END
362 Xgetexpr lines
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200363 Xopen
364 let qfbufnum = bufnr('%')
365 tabnew
366 Xopen
367 call assert_equal(qfbufnum, bufnr('%'))
368 new | only | tabonly
369 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100370endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100371
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100372func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373 call XwindowTests('c')
374 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100375endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100376
Bram Moolenaar36d50222019-05-02 20:17:40 +0200377func Test_copenHeight()
378 copen
379 wincmd H
380 let height = winheight(0)
381 copen 10
382 call assert_equal(height, winheight(0))
383 quit
384endfunc
385
Bram Moolenaar1142a312019-10-16 14:51:39 +0200386func Test_copenHeight_tabline()
387 set tabline=foo showtabline=2
388 copen
389 wincmd H
390 let height = winheight(0)
391 copen 10
392 call assert_equal(height, winheight(0))
393 quit
394 set tabline& showtabline&
395endfunc
396
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100397" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
398" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100399func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200400 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100401
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100402 let lines =<< trim END
403 Xtestfile1:700:10:Line 700
404 Xtestfile2:800:15:Line 800
405 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100406 call writefile(lines, 'Xqftestfile1', 'D')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100407
408 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200409 Xfile Xqftestfile1
410 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411 call assert_true(len(l) == 2 &&
412 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
413 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
414
Bram Moolenaar049cba92016-06-26 14:38:04 +0200415 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200416 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200417
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100418 " Run cfile/lfile from a modified buffer
419 enew!
420 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200421 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100422 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
423
424 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200425 Xaddfile Xqftestfile1
426 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100427 call assert_true(len(l) == 3 &&
428 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
429
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100430 let lines =<< trim END
431 Xtestfile1:222:77:Line 222
432 Xtestfile2:333:88:Line 333
433 END
434 call writefile(lines, 'Xqftestfile1')
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100435
436 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200437 Xgetfile Xqftestfile1
438 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100439 call assert_true(len(l) == 2 &&
440 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
441 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
442
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100443 " Test for a file with a long line and without a newline at the end
444 let text = repeat('x', 1024)
445 let t = 'a.txt:18:' . text
446 call writefile([t], 'Xqftestfile1', 'b')
447 silent! Xfile Xqftestfile1
448 call assert_equal(text, g:Xgetlist()[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100449endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100450
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100451func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100452 call XfileTests('c')
453 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100454endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100455
456" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
457" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100458func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200459 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100460
461 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100462 let lines =<< trim END
463 Xtestfile7:700:10:Line 700
464 Xtestfile8:800:15:Line 800
465 END
466 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200467 Xbuffer!
468 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100469 call assert_true(len(l) == 2 &&
470 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
471 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
472
473 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100474 let lines =<< trim END
475 Xtestfile9:900:55:Line 900
476 Xtestfile10:950:66:Line 950
477 END
478 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200479 Xgetbuffer
480 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100481 call assert_true(len(l) == 2 &&
482 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
483 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
484
485 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100486 let lines =<< trim END
487 Xtestfile11:700:20:Line 700
488 Xtestfile12:750:25:Line 750
489 END
490 silent! call setline(1, lines)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200491 Xaddbuffer
492 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100493 call assert_true(len(l) == 4 &&
494 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
495 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
496 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200497 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100498
Bram Moolenaaree85df32017-03-19 14:19:50 +0100499 " Check for invalid buffer
500 call assert_fails('Xbuffer 199', 'E474:')
501
502 " Check for unloaded buffer
503 edit Xtestfile1
504 let bnr = bufnr('%')
505 enew!
506 call assert_fails('Xbuffer ' . bnr, 'E681:')
507
508 " Check for invalid range
509 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
510 " commands. So directly call the commands.
511 if (a:cchar == 'c')
512 call assert_fails('900,999cbuffer', 'E16:')
513 else
514 call assert_fails('900,999lbuffer', 'E16:')
515 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100516endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100517
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100518func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100519 call XbufferTests('c')
520 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100521endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100522
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100523func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200524 call s:setup_commands(a:cchar)
525
526 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100527endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100529func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200530 call XexprTests('c')
531 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100532endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200533
534" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100535func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200536 call s:setup_commands(a:cchar)
537
Bram Moolenaar74240d32017-12-10 15:26:15 +0100538 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200539 " Jumping to first or next location list entry without any error should
540 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100541 if a:cchar == 'c'
542 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100543 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100544 else
545 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100546 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200547 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100548 call assert_fails('Xnext', err)
549 call assert_fails('Xprev', err)
550 call assert_fails('Xnfile', err)
551 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100552 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200553
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100554 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100555 call assert_fails(cmd, 'E42:')
556
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200557 call s:create_test_file('Xqftestfile1')
558 call s:create_test_file('Xqftestfile2')
559
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100560 let lines =<< trim END
561 Xqftestfile1:5:Line5
562 Xqftestfile1:6:Line6
563 Xqftestfile2:10:Line10
564 Xqftestfile2:11:Line11
565 RegularLine1
566 RegularLine2
567 END
568 Xgetexpr lines
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200569
570 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100571 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200572 call assert_fails('Xprev', 'E553:')
573 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200574 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200575 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200576 call assert_equal(10, line('.'))
577 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200578 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200579 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100580 5Xcc
581 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
582 2Xcc
583 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100584 if a:cchar == 'c'
585 cc
586 else
587 ll
588 endif
589 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100590 10Xcc
591 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200592 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200593 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200594 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200595 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200596 call assert_fails('Xnext', 'E553:')
597 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100598 " To process the range using quickfix list entries, directly use the
599 " quickfix commands (don't use the user defined commands)
600 if a:cchar == 'c'
601 $cc
602 else
603 $ll
604 endif
605 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200606 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200607 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200608 call assert_equal(5, line('.'))
609
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200610 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200611 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200612 call assert_equal(11, line('.'))
613 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200614 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200615 call assert_equal(5, line('.'))
616
Bram Moolenaar74240d32017-12-10 15:26:15 +0100617 " Jumping to an error from the error window using cc command
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +0100618 let lines =<< trim END
619 Xqftestfile1:5:Line5
620 Xqftestfile1:6:Line6
621 Xqftestfile2:10:Line10
622 Xqftestfile2:11:Line11
623 END
624 Xgetexpr lines
Bram Moolenaar74240d32017-12-10 15:26:15 +0100625 Xopen
626 10Xcc
627 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200628 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100629 Xopen
630 call cursor(2, 1)
631 if a:cchar == 'c'
632 .cc
633 else
634 .ll
635 endif
636 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200637 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100638
639 " Jumping to an error from the error window (when only the error window is
640 " present)
641 Xopen | only
642 Xlast 1
643 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200644 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100645
Bram Moolenaaree85df32017-03-19 14:19:50 +0100646 Xexpr ""
647 call assert_fails('Xnext', 'E42:')
648
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200649 call delete('Xqftestfile1')
650 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200651
652 " Should be able to use next/prev with invalid entries
653 Xexpr ""
654 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
655 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100656 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200657 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
658 Xlast
659 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
660 Xfirst
661 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
662 2Xnext
663 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100664endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200665
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100666func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200667 call Xtest_browse('c')
668 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100669endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200670
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000671" Test for memory allocation failures
672func Xnomem_tests(cchar)
673 call s:setup_commands(a:cchar)
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100674
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000675 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
676 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
677
678 call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
679 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100680
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200681 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000682 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100683
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200684 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000685 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100686
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200687 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000688 call assert_fails('Xfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100689
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000690 call test_alloc_fail(GetAllocId('qf_efm_fmtstr'), 0, 0)
691 set efm=%f
692 call assert_fails('Xexpr ["Xfile1"]', 'E342:')
693 set efm&
694
695 call test_alloc_fail(GetAllocId('qf_efm_fmtpart'), 0, 0)
696 set efm=%f:%l:%m,%f-%l-%m
697 call assert_fails('Xaddexpr ["Xfile2", "Xfile3"]', 'E342:')
698 set efm&
699
700 call test_alloc_fail(GetAllocId('qf_title'), 0, 0)
701 call assert_fails('Xexpr ""', 'E342:')
702 call assert_equal('', g:Xgetlist({'all': 1}).title)
703
704 call test_alloc_fail(GetAllocId('qf_mef_name'), 0, 0)
705 set makeef=Xtmp##.err
706 call assert_fails('Xgrep needle haystack', 'E342:')
707 set makeef&
708
709 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
710 call assert_fails('Xexpr "Xfile1:10:Line10"', 'E342:')
711
712 if a:cchar == 'l'
713 for id in ['qf_qfline', 'qf_qfinfo']
714 lgetexpr ["Xfile1:10:L10", "Xfile2:20:L20"]
715 call test_alloc_fail(GetAllocId(id), 0, 0)
716 call assert_fails('new', 'E342:')
717 call assert_equal(2, winnr('$'))
718 call assert_equal([], getloclist(0))
719 %bw!
720 endfor
721 endif
722
723 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
724 try
725 call assert_fails('Xvimgrep vim runtest.vim', 'E342:')
726 catch /^Vim:Interrupt$/
727 endtry
728
729 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
730 try
731 call assert_fails('Xvimgrep /vim/f runtest.vim', 'E342:')
732 catch /^Vim:Interrupt$/
733 endtry
734
735 let l = getqflist({"lines": ["Xfile1:10:L10"]})
736 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
737 call assert_fails('call g:Xsetlist(l.items)', 'E342:')
738
739 call test_alloc_fail(GetAllocId('qf_qfline'), 0, 0)
740 try
741 call assert_fails('Xhelpgrep quickfix', 'E342:')
742 catch /^Vim:Interrupt$/
743 endtry
744
745 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
746 call assert_fails('let l = g:Xgetlist({"lines": ["Xfile1:10:L10"]})', 'E342:')
747 call assert_equal(#{items: []}, l)
748
749 if a:cchar == 'l'
750 call setqflist([], 'f')
751 call setloclist(0, [], 'f')
752 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
753 call assert_fails('lhelpgrep quickfix', 'E342:')
754 call assert_equal([], getloclist(0))
755
756 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
757 call assert_fails('lvimgrep vim runtest.vim', 'E342:')
758
759 let l = getqflist({"lines": ["Xfile1:10:L10"]})
760 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
761 call assert_fails('call setloclist(0, l.items)', 'E342:')
762
763 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
764 call assert_fails('lbuffer', 'E342:')
765
766 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
767 call assert_fails('lexpr ["Xfile1:10:L10", "Xfile2:20:L20"]', 'E342:')
768
769 call test_alloc_fail(GetAllocId('qf_qfinfo'), 0, 0)
770 call assert_fails('lfile runtest.vim', 'E342:')
771 endif
772
773 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
774 set efm=%DEntering\ dir\ %f,%f:%l:%m
775 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E342:')
776 set efm&
777
778 call test_alloc_fail(GetAllocId('qf_dirstack'), 0, 0)
779 set efm=%+P[%f],(%l)%m
780 call assert_fails('Xexpr ["[runtest.vim]", "(1)Hello"]', 'E342:')
781 set efm&
782
783 call test_alloc_fail(GetAllocId('qf_multiline_pfx'), 0, 0)
784 set efm=%EError,%Cline\ %l,%Z%m
785 call assert_fails('Xexpr ["Error", "line 1", "msg"]', 'E342:')
786 set efm&
787
788 call test_alloc_fail(GetAllocId('qf_makecmd'), 0, 0)
789 call assert_fails('Xgrep vim runtest.vim', 'E342:')
790
791 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
792 call assert_fails('Xexpr repeat("a", 8192)', 'E342:')
793
794 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
795 call assert_fails('Xexpr [repeat("a", 8192)]', 'E342:')
796
797 new
798 call setline(1, repeat('a', 8192))
799 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
800 call assert_fails('Xbuffer', 'E342:')
801 %bw!
802
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100803 call writefile([repeat('a', 8192)], 'Xtest', 'D')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000804 call test_alloc_fail(GetAllocId('qf_linebuf'), 0, 0)
805 call assert_fails('Xfile Xtest', 'E342:')
Yegappan Lakshmanan5a2d4a32022-02-26 10:31:32 +0000806endfunc
807
808func Test_nomem()
809 call Xnomem_tests('c')
810 call Xnomem_tests('l')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100811endfunc
812
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100813func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200814 call s:setup_commands(a:cchar)
815 Xhelpgrep quickfix
816 Xopen
817 if a:cchar == 'c'
818 let title_text = ':helpgrep quickfix'
819 else
820 let title_text = ':lhelpgrep quickfix'
821 endif
822 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200823
824 " Jumping to a help topic should open the help window
825 only
826 Xnext
827 call assert_true(&buftype == 'help')
828 call assert_true(winnr('$') == 2)
829 " Jumping to the next match should reuse the help window
830 Xnext
831 call assert_true(&buftype == 'help')
832 call assert_true(winnr() == 1)
833 call assert_true(winnr('$') == 2)
834 " Jumping to the next match from the quickfix window should reuse the help
835 " window
836 Xopen
837 Xnext
838 call assert_true(&buftype == 'help')
839 call assert_true(winnr() == 1)
840 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200841 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200842
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100843 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200844 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100845
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100846 " When the current window is vertically split, jumping to a help match
847 " should open the help window at the top.
848 only | enew
849 let w1 = win_getid()
850 vert new
851 let w2 = win_getid()
852 Xnext
853 let w3 = win_getid()
854 call assert_true(&buftype == 'help')
855 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100856 " See jump_to_help_window() for details
857 let w2_width = winwidth(w2)
858 if w2_width != &columns && w2_width < 80
859 call assert_equal(['col', [['leaf', w3],
860 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
861 else
862 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
863 \ ['leaf', w1]]] , winlayout())
864 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100865
866 new | only
867 set buftype=help
868 set modified
869 call assert_fails('Xnext', 'E37:')
870 set nomodified
871 new | only
872
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200873 if a:cchar == 'l'
874 " When a help window is present, running :lhelpgrep should reuse the
875 " help window and not the current window
876 new | only
877 call g:Xsetlist([], 'f')
878 help index.txt
879 wincmd w
880 lhelpgrep quickfix
881 call assert_equal(1, winnr())
882 call assert_notequal([], getloclist(1))
883 call assert_equal([], getloclist(2))
884 endif
885
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200886 new | only
887
Bram Moolenaaree85df32017-03-19 14:19:50 +0100888 " Search for non existing help string
889 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200890 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200891 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100892endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200893
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100894func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200895 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200896 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200897 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100898endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100899
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100900def Test_helpgrep_vim9_restore_cpo()
Christian Brabandt22105fd2024-07-15 20:51:11 +0200901 assert_equal('aABceFsz', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100902
903 var rtp_save = &rtp
904 var dir = 'Xruntime/after'
905 &rtp ..= ',' .. dir
Bram Moolenaardb77cb32022-10-05 21:45:30 +0100906 mkdir(dir .. '/ftplugin', 'pR')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100907 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100908 filetype plugin on
909 silent helpgrep grail
910 cwindow
911 silent helpgrep grail
912
Christian Brabandt22105fd2024-07-15 20:51:11 +0200913 assert_equal('aABceFsz', &cpo)
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100914 &rtp = rtp_save
915 cclose
916 helpclose
917enddef
918
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000919" When running the :helpgrep command, if an autocmd modifies the 'cpoptions'
920" value, then Vim crashes. (issue fixed by 7.2b-004 and 8.2.4453)
Bram Moolenaar4791fcd2022-02-23 12:06:00 +0000921func Test_helpgrep_restore_cpo_aucmd()
922 let save_cpo = &cpo
923 augroup QF_Test
924 au!
925 autocmd BufNew * set cpo=acd
926 augroup END
927
928 helpgrep quickfix
929 call assert_equal('acd', &cpo)
930 %bw!
931
932 set cpo&vim
933 augroup QF_Test
934 au!
935 autocmd BufReadPost * set cpo=
936 augroup END
937
938 helpgrep buffer
939 call assert_equal('', &cpo)
940
941 augroup QF_Test
942 au!
943 augroup END
944 %bw!
945 let &cpo = save_cpo
946endfunc
947
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200948def Test_vim9_cexpr()
949 var text = 'somefile:95:error'
950 cexpr text
951 var l = getqflist()
952 assert_equal(1, l->len())
953 assert_equal(95, l[0].lnum)
954 assert_equal('error', l[0].text)
955
956 text = 'somefile:77:warning'
957 caddexpr text
958 l = getqflist()
959 assert_equal(2, l->len())
960 assert_equal(77, l[1].lnum)
961 assert_equal('warning', l[1].text)
962enddef
963
Bram Moolenaar6920c722016-01-22 22:44:10 +0100964func Test_errortitle()
965 augroup QfBufWinEnter
966 au!
967 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
968 augroup END
969 copen
970 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'')'}]
971 call setqflist(a)
972 call assert_equal(':setqflist()', g:a)
973 augroup QfBufWinEnter
974 au!
975 augroup END
976 augroup! QfBufWinEnter
977endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100978
Bram Moolenaar5584df62016-03-18 21:00:51 +0100979func Test_vimgreptitle()
980 augroup QfBufWinEnter
981 au!
982 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
983 augroup END
984 try
985 vimgrep /pattern/j file
986 catch /E480/
987 endtry
988 copen
989 call assert_equal(': vimgrep /pattern/j file', g:a)
990 augroup QfBufWinEnter
991 au!
992 augroup END
993 augroup! QfBufWinEnter
994endfunc
995
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100996func Test_bufwinenter_once()
997 augroup QfBufWinEnter
998 au!
999 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
1000 augroup END
1001 let g:got_afile = ''
1002 copen
1003 call assert_equal('got quickfix', g:got_afile)
1004
1005 cclose
1006 unlet g:got_afile
1007 augroup QfBufWinEnter
1008 au!
1009 augroup END
1010 augroup! QfBufWinEnter
1011endfunc
1012
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001013func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001014 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +01001015
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001016 Xgetexpr ['file:1:1:message']
1017 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001018 if a:cchar == 'c'
1019 call setqflist(l, 'r')
1020 else
1021 call setloclist(0, l, 'r')
1022 endif
1023
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001024 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +01001025 if a:cchar == 'c'
1026 let title = ':setqflist()'
1027 else
1028 let title = ':setloclist()'
1029 endif
1030 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001031 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001032endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001033
1034" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001035func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001036 call XqfTitleTests('c')
1037 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001038endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +01001039
1040" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001041func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +01001042 let save_efm = &efm
1043 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
1044 cgetexpr ['WWWW', 'EEEE', 'CCCC']
1045 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1046 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1047 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
1048 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1049 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
1050 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
1051 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
1052 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
1053 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001054endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001055
1056" This will test for problems in quickfix:
1057" A. incorrectly copying location lists which caused the location list to show
1058" a different name than the file that was actually being displayed.
1059" B. not reusing the window for which the location list window is opened but
1060" instead creating new windows.
1061" C. make sure that the location list window is not reused instead of the
1062" window it belongs to.
1063"
1064" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001065func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001066 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
1067 let word = substitute(base, '\v(.*)\..*', '\1', '')
1068
1069 setl modifiable
1070 setl noreadonly
1071 setl noswapfile
1072 setl bufhidden=delete
1073 %del _
1074 " For problem 2:
1075 " 'buftype' has to be set to reproduce the constant opening of new windows
1076 setl buftype=nofile
1077
1078 call setline(1, word)
1079
1080 setl nomodified
1081 setl nomodifiable
1082 setl readonly
1083 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001084endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001085
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001086func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001087 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001088
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001089 augroup testgroup
1090 au!
1091 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
1092 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001093
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001094 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001095
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001096 let qflist = []
1097 for word in words
1098 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
1099 " NOTE: problem 1:
1100 " intentionally not setting 'lnum' so that the quickfix entries are not
1101 " valid
1102 eval qflist->setloclist(0, ' ')
1103 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001104
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001105 " Test A
1106 lrewind
1107 enew
1108 lopen
1109 4lnext
1110 vert split
1111 wincmd L
1112 lopen
1113 wincmd p
1114 lnext
1115 let fileName = expand("%")
1116 wincmd p
1117 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
1118 let fileName = substitute(fileName, '\\', '/', 'g')
1119 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
1120 call assert_equal("test://bar.txt", fileName)
1121 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001122
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001123 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001124
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001125 " Test B:
1126 lrewind
1127 lopen
1128 2
1129 exe "normal \<CR>"
1130 wincmd p
1131 3
1132 exe "normal \<CR>"
1133 wincmd p
1134 4
1135 exe "normal \<CR>"
1136 call assert_equal(2, winnr('$'))
1137 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001138
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001139 " Test C:
1140 lrewind
1141 lopen
1142 " Let's move the location list window to the top to check whether it (the
1143 " first window found) will be reused when we try to open new windows:
1144 wincmd K
1145 2
1146 exe "normal \<CR>"
1147 wincmd p
1148 3
1149 exe "normal \<CR>"
1150 wincmd p
1151 4
1152 exe "normal \<CR>"
1153 1wincmd w
1154 call assert_equal('quickfix', &buftype)
1155 2wincmd w
1156 let bufferName = expand("%")
1157 let bufferName = substitute(bufferName, '\\', '/', 'g')
1158 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001159
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001160 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +01001161
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001162 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +01001163endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001164
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001165func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001166 augroup testgroup
1167 au!
1168 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
1169 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +01001170
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001171 func! R(n)
1172 quit
1173 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001174
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001175 new
1176 let q = []
1177 call add(q, {'filename': 'test_curwin.txt' })
1178 call setloclist(0, q)
1179 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001180
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001181 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001182 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001183endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001184
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001185func Test_locationlist_cross_tab_jump()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001186 call writefile(['loclistfoo'], 'loclistfoo', 'D')
1187 call writefile(['loclistbar'], 'loclistbar', 'D')
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001188 set switchbuf=usetab
1189
1190 edit loclistfoo
1191 tabedit loclistbar
1192 silent lgrep loclistfoo loclist*
1193 call assert_equal(1, tabpagenr())
1194
1195 enew | only | tabonly
1196 set switchbuf&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001197endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001198
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001199" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001200func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001201 " The 'errorformat' setting is different on non-Unix systems.
1202 " This test works only on Unix-like systems.
1203 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001204
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001205 let l =<< trim [DATA]
1206 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1207 "Xtestfile", line 6 col 19; this is an error
1208 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1209 Xtestfile:9: parse error before `asd'
Gregory Andersd1911a82023-06-05 21:52:46 +01001210 make: *** [src/vim/testdir/Makefile:100: test_quickfix] Error 1
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001211 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001212
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001213 2 returned
1214 "Xtestfile", line 11 col 1; this is an error
1215 "Xtestfile", line 12 col 2; this is another error
1216 "Xtestfile", line 14:10; this is an error in column 10
1217 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1218 "Xtestfile", linenr 16: yet another problem
1219 Error in "Xtestfile" at line 17:
1220 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001221 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001222 ^
1223 Error in "Xtestfile" at line 18:
1224 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001225 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001226 .............^
1227 Error in "Xtestfile" at line 19:
1228 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001229 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001230 --------------^
1231 Error in "Xtestfile" at line 20:
1232 x should be a dot
Bram Moolenaar94722c52023-01-28 19:19:03 +00001233 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1234 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001235
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001236 Does anyone know what is the problem and how to correction it?
1237 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1238 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1239 [DATA]
1240
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001241 call writefile(l, 'Xerrorfile1', 'D')
1242 call delete('loclistbar')
1243 call writefile(l[:-2], 'Xerrorfile2', 'D')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001244
1245 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001246 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1247 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1248 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1249 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1250 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1251 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1252 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1253 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1254 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1255 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1256 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1257 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1258 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1259 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1260 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1261 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1262 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1263 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1264 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1265 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1266 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1267[DATA]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001268 call writefile(m, 'Xtestfile', 'D')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001269
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001270 let save_efm = &efm
1271 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1272 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001273
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001274 exe 'cf Xerrorfile2'
1275 clast
1276 copen
1277 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1278 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001279
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001280 exe 'cf Xerrorfile1'
1281 call assert_equal([4, 12], [line('.'), col('.')])
1282 cn
1283 call assert_equal([6, 19], [line('.'), col('.')])
1284 cn
1285 call assert_equal([9, 2], [line('.'), col('.')])
1286 cn
1287 call assert_equal([10, 2], [line('.'), col('.')])
1288 cn
1289 call assert_equal([11, 1], [line('.'), col('.')])
1290 cn
1291 call assert_equal([12, 2], [line('.'), col('.')])
1292 cn
1293 call assert_equal([14, 10], [line('.'), col('.')])
1294 cn
1295 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1296 cn
1297 call assert_equal([16, 2], [line('.'), col('.')])
1298 cn
1299 call assert_equal([17, 6], [line('.'), col('.')])
1300 cn
1301 call assert_equal([18, 7], [line('.'), col('.')])
1302 cn
1303 call assert_equal([19, 8], [line('.'), col('.')])
1304 cn
1305 call assert_equal([20, 9], [line('.'), col('.')])
1306 clast
1307 cprev
1308 cprev
1309 wincmd w
1310 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1311 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001312
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001313 let &efm = save_efm
Bram Moolenaaree85df32017-03-19 14:19:50 +01001314endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001315
Bram Moolenaarab47c612016-06-14 22:02:26 +02001316" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001317func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001318 call s:setup_commands(a:cchar)
1319
Bram Moolenaarab47c612016-06-14 22:02:26 +02001320 let save_efm=&efm
1321 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1322
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001323 let lines =<< trim END
1324 Entering dir 'dir1/a'
1325 habits2.txt:1:Nine Healthy Habits
1326 Entering dir 'b'
1327 habits3.txt:2:0 Hours of television
1328 habits2.txt:7:5 Small meals
1329 Entering dir 'dir1/c'
1330 habits4.txt:3:1 Hour of exercise
1331 Leaving dir 'dir1/c'
1332 Leaving dir 'dir1/a'
1333 habits1.txt:4:2 Liters of water
1334 Entering dir 'dir2'
1335 habits5.txt:5:3 Cups of hot green tea
1336 Leaving dir 'dir2'
1337 END
Bram Moolenaarab47c612016-06-14 22:02:26 +02001338
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001339 Xexpr ""
1340 for l in lines
1341 Xaddexpr l
1342 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001343
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001344 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001345
1346 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1347 call assert_equal(1, qf[1].lnum)
1348 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1349 call assert_equal(2, qf[3].lnum)
1350 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1351 call assert_equal(7, qf[4].lnum)
1352 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1353 call assert_equal(3, qf[6].lnum)
1354 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1355 call assert_equal(4, qf[9].lnum)
1356 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1357 call assert_equal(5, qf[11].lnum)
1358
1359 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001360endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001361
1362" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001363func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001364 " Create the directory stack and files
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001365 call mkdir('dir1', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001366 call mkdir('dir1/a')
1367 call mkdir('dir1/a/b')
1368 call mkdir('dir1/c')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001369 call mkdir('dir2', 'R')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001370
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001371 let lines =<< trim END
1372 Nine Healthy Habits
1373 0 Hours of television
1374 1 Hour of exercise
1375 2 Liters of water
1376 3 Cups of hot green tea
1377 4 Short mental breaks
1378 5 Small meals
1379 6 AM wake up time
1380 7 Minutes of laughter
1381 8 Hours of sleep (at least)
1382 9 PM end of the day and off to bed
1383 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001384 call writefile(lines, 'habits1.txt', 'D')
Bram Moolenaarab47c612016-06-14 22:02:26 +02001385 call writefile(lines, 'dir1/a/habits2.txt')
1386 call writefile(lines, 'dir1/a/b/habits3.txt')
1387 call writefile(lines, 'dir1/c/habits4.txt')
1388 call writefile(lines, 'dir2/habits5.txt')
1389
1390 call s:dir_stack_tests('c')
1391 call s:dir_stack_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001392endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001393
Bram Moolenaar9b457942016-10-09 16:10:05 +02001394" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001395func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001396 call s:setup_commands(a:cchar)
1397
1398 let save_efm = &efm
1399
1400 let &efm =
1401 \ '%Eerror %m %l,' .
1402 \ '%-Wignored %m %l,' .
1403 \ '%+Cmore ignored %m %l,' .
1404 \ '%Zignored end'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001405 let lines =<< trim END
1406 ignored warning 1
1407 more ignored continuation 2
1408 ignored end
1409 error resync 4
1410 END
1411 Xgetexpr lines
Bram Moolenaar9b457942016-10-09 16:10:05 +02001412 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1413 call assert_equal([['resync', 1, 4, 'E']], l)
1414
1415 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001416endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001417
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001418func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001419 call Xefm_ignore_continuations('c')
1420 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001421endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001422
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001423" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001424func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001425 call s:setup_commands(a:cchar)
1426
Bram Moolenaar049cba92016-06-26 14:38:04 +02001427 let save_efm = &efm
1428
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001429 set efm=%f:%l:%m,%f:%f:%l:%m
1430 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1431
1432 set efm=%f:%l:%m,%f:%l:%r:%m
1433 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1434
1435 set efm=%f:%l:%m,%O:%f:%l:%m
1436 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1437
1438 set efm=%f:%l:%m,%f:%l:%*[^a-z
1439 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1440
1441 set efm=%f:%l:%m,%f:%l:%*c
1442 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1443
1444 set efm=%f:%l:%m,%L%M%N
1445 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1446
1447 set efm=%f:%l:%m,%f:%l:%m:%R
1448 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1449
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001450 " Invalid regular expression
1451 set efm=%\\%%k
1452 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1453
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001454 set efm=
1455 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1456
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001457 " Empty directory name. When there is an error in parsing new entries, make
1458 " sure the previous quickfix list is made the current list.
1459 set efm&
1460 cexpr ["one", "two"]
1461 let qf_id = getqflist(#{id: 0}).id
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001462 set efm=%DEntering\ dir\ abc,%f:%l:%m
1463 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001464 call assert_equal(qf_id, getqflist(#{id: 0}).id)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001465
1466 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001467endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001468
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001469func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001470 call Xinvalid_efm_Tests('c')
1471 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001472endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001473
1474" TODO:
1475" Add tests for the following formats in 'errorformat'
1476" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001477func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001478 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001479
1480 " Test for %s format in efm
1481 set efm=%f:%s
1482 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001483 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001484 call assert_equal('^\VLine search text\$', l[0].pattern)
1485 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001486
Bram Moolenaaree85df32017-03-19 14:19:50 +01001487 let l = split(execute('clist', ''), "\n")
1488 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1489
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001490 " Test for a long line
1491 cexpr 'Xtestfile:' . repeat('a', 1026)
1492 let l = getqflist()
1493 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1494
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001495 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001496 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001497 [Xtestfile1]
1498 (1,17) error: ';' missing
1499 (21,2) warning: variable 'z' not defined
1500 (67,3) error: end of file found before string ended
1501 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001502
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001503 [Xtestfile2]
1504 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001505
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001506 [Xtestfile3]
1507 NEW compiler v1.1
1508 (2,2) warning: variable 'x' not defined
1509 (67,3) warning: 's' already defined
1510 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001511 [DATA]
1512
Bram Moolenaaree85df32017-03-19 14:19:50 +01001513 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001514 " To exercise the push/pop file functionality in quickfix, the test files
1515 " need to be created.
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001516 call writefile(['Line1'], 'Xtestfile1', 'D')
1517 call writefile(['Line2'], 'Xtestfile2', 'D')
1518 call writefile(['Line3'], 'Xtestfile3', 'D')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001519 cexpr ""
1520 for l in lines
1521 caddexpr l
1522 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001523 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001524 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001525 call assert_equal(21, l[2].lnum)
1526 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001527 call assert_equal('w', l[2].type)
1528 call assert_equal('e', l[3].type)
1529
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001530 " Test for %P, %Q with non-existing files
1531 cexpr lines
1532 let l = getqflist()
1533 call assert_equal(14, len(l))
1534 call assert_equal('[Xtestfile1]', l[0].text)
1535 call assert_equal('[Xtestfile2]', l[6].text)
1536 call assert_equal('[Xtestfile3]', l[9].text)
1537
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001538 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001539 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001540 Error 275
1541 line 42
1542 column 3
1543 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001544 [DATA]
1545
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001546 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1547 cgetexpr lines
1548 let l = getqflist()
1549 call assert_equal(275, l[0].nr)
1550 call assert_equal(42, l[0].lnum)
1551 call assert_equal(3, l[0].col)
1552 call assert_equal('E', l[0].type)
1553 call assert_equal("\n' ' expected after '--'", l[0].text)
1554
1555 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001556 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001557 Error in line 147 of foo.c:
1558 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001559 [DATA]
1560
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001561 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1562 cgetexpr lines
1563 let l = getqflist()
1564 call assert_equal(147, l[0].lnum)
1565 call assert_equal('E', l[0].type)
1566 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001567
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001568 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001569 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001570 ==============================================================
1571 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1572 --------------------------------------------------------------
1573 Traceback (most recent call last):
1574 File "unittests/dbfacadeTest.py", line 89, in testFoo
1575 self.assertEquals(34, dtid)
1576 File "/usr/lib/python2.2/unittest.py", line 286, in
1577 failUnlessEqual
1578 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001579 W:AssertionError: 34 != 33
Bram Moolenaar94722c52023-01-28 19:19:03 +00001580
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001581 --------------------------------------------------------------
1582 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001583 [DATA]
1584
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001585 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001586 cgetexpr lines
1587 let l = getqflist()
1588 call assert_equal(8, len(l))
1589 call assert_equal(89, l[4].lnum)
1590 call assert_equal(1, l[4].valid)
1591 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001592 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001593
Bram Moolenaard76ce852018-05-01 15:02:04 +02001594 " Test for %o
1595 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001596 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001597 call writefile(['Line1'], 'Xotestfile', 'D')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001598 let l = getqflist()
1599 call assert_equal(1, len(l), string(l))
1600 call assert_equal('Language.PureScript.Types', l[0].module)
1601 copen
1602 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1603 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001604 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001605 cclose
1606 bd
Bram Moolenaard76ce852018-05-01 15:02:04 +02001607
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001608 " Test for a long module name
1609 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1610 let l = getqflist()
1611 call assert_equal(repeat('m', 1024), l[0].module)
1612 call assert_equal(15, l[0].lnum)
1613 call assert_equal('message', l[0].text)
1614
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001615 " The following sequence of commands used to crash Vim
1616 set efm=%W%m
1617 cgetexpr ['msg1']
1618 let l = getqflist()
1619 call assert_equal(1, len(l), string(l))
1620 call assert_equal('msg1', l[0].text)
1621 set efm=%C%m
1622 lexpr 'msg2'
1623 let l = getloclist(0)
1624 call assert_equal(1, len(l), string(l))
1625 call assert_equal('msg2', l[0].text)
1626 lopen
1627 call setqflist([], 'r')
1628 caddbuf
1629 let l = getqflist()
1630 call assert_equal(1, len(l), string(l))
1631 call assert_equal('|| msg2', l[0].text)
1632
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001633 " When matching error lines, case should be ignored. Test for this.
1634 set noignorecase
1635 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1636 call assert_equal(10, l.items[0].lnum)
1637 call assert_equal('Line 20', l.items[0].text)
1638 set ignorecase&
1639
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001640 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001641 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001642endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001643
Bram Moolenaare9283662020-06-07 14:10:47 +02001644" Test for '%t' (error type) field in 'efm'
1645func Test_efm_error_type()
1646 let save_efm = &efm
1647
1648 " error type
1649 set efm=%f:%l:%t:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001650 let lines =<< trim END
1651 Xfile1:10:E:msg1
1652 Xfile1:20:W:msg2
1653 Xfile1:30:I:msg3
1654 Xfile1:40:N:msg4
1655 Xfile1:50:R:msg5
1656 END
1657 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001658 let output = split(execute('clist'), "\n")
1659 call assert_equal([
1660 \ ' 1 Xfile1:10 error: msg1',
1661 \ ' 2 Xfile1:20 warning: msg2',
1662 \ ' 3 Xfile1:30 info: msg3',
1663 \ ' 4 Xfile1:40 note: msg4',
1664 \ ' 5 Xfile1:50 R: msg5'], output)
1665
1666 " error type and a error number
1667 set efm=%f:%l:%t:%n:%m
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001668 let lines =<< trim END
1669 Xfile1:10:E:2:msg1
1670 Xfile1:20:W:4:msg2
1671 Xfile1:30:I:6:msg3
1672 Xfile1:40:N:8:msg4
1673 Xfile1:50:R:3:msg5
1674 END
1675 cexpr lines
Bram Moolenaare9283662020-06-07 14:10:47 +02001676 let output = split(execute('clist'), "\n")
1677 call assert_equal([
1678 \ ' 1 Xfile1:10 error 2: msg1',
1679 \ ' 2 Xfile1:20 warning 4: msg2',
1680 \ ' 3 Xfile1:30 info 6: msg3',
1681 \ ' 4 Xfile1:40 note 8: msg4',
1682 \ ' 5 Xfile1:50 R 3: msg5'], output)
1683 let &efm = save_efm
1684endfunc
1685
haya14busae023d492022-02-08 18:09:29 +00001686" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1687func Test_efm_end_lnum_col()
1688 let save_efm = &efm
1689
1690 " single line
1691 set efm=%f:%l-%e:%c-%k:%t:%m
1692 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1693 let output = split(execute('clist'), "\n")
1694 call assert_equal([
1695 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1696 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1697
1698 " multiple lines
1699 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01001700 let lines =<< trim END
1701 1)msg1
1702 Xfile1:14-24:1-2
1703 2)msg2
1704 Xfile1:24-34:3-4
1705 END
1706 cexpr lines
haya14busae023d492022-02-08 18:09:29 +00001707 let output = split(execute('clist'), "\n")
1708 call assert_equal([
1709 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1710 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1711 let &efm = save_efm
1712endfunc
1713
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001714func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001715 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001716 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001717 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001718 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001719 colder
1720 cgetexpr []
1721 endfunc
1722 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001723 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001724 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001725 lolder
1726 lgetexpr []
1727 endfunc
1728 endif
1729
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001730 augroup QF_Test
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001731 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001732 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001733 augroup END
1734
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001735 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001736 let words = [ "a", "b" ]
1737 let qflist = []
1738 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001739 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001740 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001741 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001742 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001743
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001744 augroup QF_Test
1745 au!
1746 augroup END
1747
1748 if a:cchar == 'c'
1749 cexpr ["Xtest1:1:Line"]
1750 cwindow
1751 only
1752 augroup QF_Test
1753 au!
1754 autocmd WinEnter * call setqflist([], 'f')
1755 augroup END
1756 call assert_fails('exe "normal \<CR>"', 'E925:')
1757 augroup QF_Test
1758 au!
1759 augroup END
1760 endif
1761 %bw!
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001762endfunc
1763
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001764func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001765 call XquickfixChangedByAutocmd('c')
1766 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001767endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001768
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001769func Test_setloclist_in_autocommand()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01001770 call writefile(['test1', 'test2'], 'Xfile', 'D')
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001771 edit Xfile
1772 let s:bufnr = bufnr()
1773 call setloclist(1,
1774 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1775 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1776
1777 augroup Test_LocList
1778 au!
1779 autocmd BufEnter * call setloclist(1,
1780 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1781 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1782 augroup END
1783
1784 lopen
1785 call assert_fails('exe "normal j\<CR>"', 'E926:')
1786
1787 augroup Test_LocList
1788 au!
1789 augroup END
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001790endfunc
1791
Bram Moolenaar8b201792016-03-25 15:01:10 +01001792func Test_caddbuffer_to_empty()
1793 helpgr quickfix
1794 call setqflist([], 'r')
1795 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001796 try
1797 cn
1798 catch
1799 " number of matches is unknown
1800 call assert_true(v:exception =~ 'E553:')
1801 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001802 quit!
1803endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001804
1805func Test_cgetexpr_works()
1806 " this must not crash Vim
1807 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001808 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001809endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001810
1811" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001812func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001813 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001814
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001815 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Tom Praschanca6ac992023-08-11 23:26:12 +02001816 \ {'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 +02001817 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001818 call assert_equal(2, len(l))
1819 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001820 call assert_equal(3, l[1].end_lnum)
1821 call assert_equal(4, l[1].col)
1822 call assert_equal(5, l[1].end_col)
Tom Praschanca6ac992023-08-11 23:26:12 +02001823 call assert_equal({'6': [7, 8]}, l[1].user_data)
1824
1825 " Test that user_data is garbage collected
1826 call g:Xsetlist([{'user_data': ['high', 5]},
1827 \ {'user_data': {'this': [7, 'eight'], 'is': ['a', 'dictionary']}}])
1828 call test_garbagecollect_now()
1829 let l = g:Xgetlist()
1830 call assert_equal(2, len(l))
1831 call assert_equal(['high', 5], l[0].user_data)
1832 call assert_equal({'this': [7, 'eight'], 'is': ['a', 'dictionary']}, l[1].user_data)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001833
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001834 Xnext
1835 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1836 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001837 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001838 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001839 call assert_equal(3, line('.'))
1840
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001841 " Appending entries to the list should not change the cursor position
1842 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001843 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001844 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001845 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001846 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1847 call assert_equal(1, line('.'))
1848 close
1849
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001850 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001851 \ {'bufnr': a:bnum, 'lnum': 4},
1852 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001853 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001854 call assert_equal(3, len(l))
1855 call assert_equal(5, l[2].lnum)
1856
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001857 call g:Xsetlist([])
1858 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001859 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001860
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001861 " Tests for setting the 'valid' flag
1862 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1863 Xwindow
1864 call assert_equal(1, winnr('$'))
1865 let l = g:Xgetlist()
1866 call g:Xsetlist(l)
1867 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001868 " Adding a non-valid entry should not mark the list as having valid entries
1869 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1870 Xwindow
1871 call assert_equal(1, winnr('$'))
1872
1873 " :cnext/:cprev should still work even with invalid entries in the list
1874 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1875 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1876 call g:Xsetlist(l)
1877 Xnext
1878 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1879 Xprev
1880 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1881 " :cnext/:cprev should still work after appending invalid entries to an
1882 " empty list
1883 call g:Xsetlist([])
1884 call g:Xsetlist(l, 'a')
1885 Xnext
1886 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1887 Xprev
1888 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1889
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001890 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1891 Xwindow
1892 call assert_equal(2, winnr('$'))
1893 Xclose
1894 let save_efm = &efm
1895 set efm=%m
1896 Xgetexpr 'TestMessage'
1897 let l = g:Xgetlist()
1898 call g:Xsetlist(l)
1899 call assert_equal(1, g:Xgetlist()[0].valid)
1900 let &efm = save_efm
1901
Bram Moolenaaree85df32017-03-19 14:19:50 +01001902 " Error cases:
1903 " Refer to a non-existing buffer and pass a non-dictionary type
1904 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1905 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1906 call g:Xsetlist([[1, 2,3]])
1907 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001908 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001909 call g:Xsetlist([test_null_dict()])
1910 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001911endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001912
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001913func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001914 new Xtestfile | only
1915 let bnum = bufnr('%')
1916 call setline(1, range(1,5))
1917
1918 call SetXlistTests('c', bnum)
1919 call SetXlistTests('l', bnum)
1920
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001921 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001922 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001923endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001924
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001925func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001926 call s:setup_commands(a:cchar)
1927
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001928 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001929 let @/ = 'Test_'
1930 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001931 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001932 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001933 Xvimgrep empty test_quickfix.vim
1934 call assert_true(len(g:Xgetlist()) > 0)
1935 Xvimgrep matches test_quickfix.vim
1936 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001937 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001938 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001939 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001940 call g:Xsetlist([], 'r')
1941 call assert_true(len(g:Xgetlist()) == 0)
1942 Xolder
1943 call assert_equal(testlen, len(g:Xgetlist()))
1944 Xnewer
1945 Xnewer
1946 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001947endfunc
1948
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001949func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001950 call Xlist_empty_middle('c')
1951 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001952endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001953
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001954func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001955 call s:setup_commands(a:cchar)
1956
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001957 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001958 Xvimgrep one test_quickfix.vim
1959 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001960 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001961 Xvimgrep two test_quickfix.vim
1962 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001963 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001964 Xvimgrep three test_quickfix.vim
1965 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001966 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001967 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001968 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001969 call g:Xsetlist([], 'r')
1970 call assert_true(len(g:Xgetlist()) == 0)
1971 Xnewer
1972 call assert_equal(twolen, len(g:Xgetlist()))
1973 Xnewer
1974 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001975endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001976
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001977func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001978 call Xlist_empty_older('c')
1979 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001980endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001981
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001982func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001983 call s:setup_commands(a:cchar)
1984
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001985 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1986 \ {'filename': 'fnameB', 'text': 'B'}]
1987 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1988 \ {'filename': 'fnameD', 'text': 'D'},
1989 \ {'filename': 'fnameE', 'text': 'E'}]
1990
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001991 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001992 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001993 silent! Xnewer 99
1994 call g:Xsetlist(list1)
1995 call g:Xsetlist(list2)
1996 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001997 call assert_equal(3, len(li))
1998 call assert_equal('C', li[0]['text'])
1999 call assert_equal('D', li[1]['text'])
2000 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002001 silent! Xolder
2002 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002003 call assert_equal(2, len(li))
2004 call assert_equal('A', li[0]['text'])
2005 call assert_equal('B', li[1]['text'])
2006
2007 " {action} is specified ' '.
2008 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002009 silent! Xnewer 99
2010 call g:Xsetlist(list1)
2011 call g:Xsetlist(list2, ' ')
2012 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002013 call assert_equal(3, len(li))
2014 call assert_equal('C', li[0]['text'])
2015 call assert_equal('D', li[1]['text'])
2016 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002017 silent! Xolder
2018 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002019 call assert_equal(2, len(li))
2020 call assert_equal('A', li[0]['text'])
2021 call assert_equal('B', li[1]['text'])
2022
2023 " {action} is specified 'a'.
2024 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002025 silent! Xnewer 99
2026 call g:Xsetlist(list1)
2027 call g:Xsetlist(list2, 'a')
2028 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002029 call assert_equal(5, len(li))
2030 call assert_equal('A', li[0]['text'])
2031 call assert_equal('B', li[1]['text'])
2032 call assert_equal('C', li[2]['text'])
2033 call assert_equal('D', li[3]['text'])
2034 call assert_equal('E', li[4]['text'])
2035
2036 " {action} is specified 'r'.
2037 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002038 silent! Xnewer 99
2039 call g:Xsetlist(list1)
2040 call g:Xsetlist(list2, 'r')
2041 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002042 call assert_equal(3, len(li))
2043 call assert_equal('C', li[0]['text'])
2044 call assert_equal('D', li[1]['text'])
2045 call assert_equal('E', li[2]['text'])
2046
2047 " Test for wrong value.
2048 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002049 call assert_fails("call g:Xsetlist(0)", 'E714:')
2050 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
2051 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
2052 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
2053 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002054endfunc
2055
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002056func Test_setqflist_invalid_nr()
2057 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02002058 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01002059endfunc
2060
Bram Moolenaar99234f22020-02-10 22:56:54 +01002061func Test_setqflist_user_sets_buftype()
2062 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
2063 set buftype=quickfix
2064 call setqflist([], 'a')
2065 enew
2066endfunc
2067
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002068func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02002069 call XquickfixSetListWithAct('c')
2070 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002071endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002072
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002073func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002074 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002075
Bram Moolenaar049cba92016-06-26 14:38:04 +02002076 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002077 call assert_equal(1, l[0].lnum)
2078 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002079 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002080 call assert_equal(2, l[1].lnum)
2081 call assert_equal(1, l[1].col)
2082 call assert_equal(4070, len(l[1].text))
2083 call assert_equal(3, l[2].lnum)
2084 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002085 call assert_equal(4070, len(l[2].text))
2086 call assert_equal(4, l[3].lnum)
2087 call assert_equal(1, l[3].col)
2088 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002089
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002090 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002091endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002092
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002093func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002094 call s:setup_commands(a:cchar)
2095
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002096 let testfile = 'samples/quickfix.txt'
2097
2098 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002099 exe 'Xgetfile' testfile
2100 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002101
2102 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002103 Xexpr readfile(testfile)
2104 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002105
2106 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002107 Xexpr join(readfile(testfile), "\n")
2108 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02002109
2110 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002111 exe 'edit' testfile
2112 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02002113 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002114endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002115
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002116func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02002117 call s:long_lines_tests('c')
2118 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002119endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002120
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002121func Test_cgetfile_on_long_lines()
2122 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
2123 " are read at a time.
2124 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002125 let lines =<< trim END
2126 /tmp/file1:1:1:aaa
2127 /tmp/file2:1:1:%s
2128 /tmp/file3:1:1:bbb
2129 /tmp/file4:1:1:ccc
2130 END
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002131 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002132 call writefile(lines, 'Xcqetfile.txt', 'D')
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002133 cgetfile Xcqetfile.txt
2134 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
2135 endfor
Bram Moolenaar59941cb2020-09-05 17:03:40 +02002136endfunc
2137
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002138func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002139 let l = []
2140 for i in range(1, 20)
2141 call add(l, 'Line' . i)
2142 endfor
2143 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002144endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002145
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002146func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002147 call s:create_test_file('Xqftestfile1')
2148 call s:create_test_file('Xqftestfile2')
2149 call s:create_test_file('Xqftestfile3')
2150
2151 new | only
2152 edit Xqftestfile1
2153 let file1_winid = win_getid()
2154 new Xqftestfile2
2155 let file2_winid = win_getid()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002156 let lines =<< trim END
2157 Xqftestfile1:5:Line5
2158 Xqftestfile1:6:Line6
2159 Xqftestfile2:10:Line10
2160 Xqftestfile2:11:Line11
2161 Xqftestfile3:15:Line15
2162 Xqftestfile3:16:Line16
2163 END
2164 cgetexpr lines
Bram Moolenaar049cba92016-06-26 14:38:04 +02002165
2166 new
2167 let winid = win_getid()
2168 cfirst | cnext
2169 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002170 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002171 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002172 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002173 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002174
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002175 " Test for 'switchbuf' set to search for files in windows in the current
2176 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002177 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002178 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02002179 cfirst | cnext
2180 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002181 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002182 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002183 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002184 call assert_equal(file2_winid, win_getid())
2185
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002186 " Test for 'switchbuf' set to search for files in tabpages and jump to an
2187 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002188 enew | only
2189 set switchbuf=usetab
2190 tabedit Xqftestfile1
2191 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01002192 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02002193 tabfirst
2194 cfirst | cnext
2195 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002196 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002197 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002198 6cnext
2199 call assert_equal(4, tabpagenr())
2200 2cpfile
2201 call assert_equal(2, tabpagenr())
2202 2cnfile
2203 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002204 tabfirst | tabonly | enew
2205
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002206 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002207 set switchbuf=split
2208 cfirst | cnext
2209 call assert_equal(1, winnr('$'))
2210 cnext | cnext
2211 call assert_equal(2, winnr('$'))
2212 cnext | cnext
2213 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002214
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002215 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002216 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002217 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002218 cfirst | cnext
2219 call assert_equal(1, tabpagenr('$'))
2220 cnext | cnext
2221 call assert_equal(2, tabpagenr('$'))
2222 cnext | cnext
2223 call assert_equal(3, tabpagenr('$'))
2224 tabfirst | enew | tabonly | only
2225
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002226 set switchbuf=uselast
2227 split
2228 let last_winid = win_getid()
2229 copen
2230 exe "normal 1G\<CR>"
2231 call assert_equal(last_winid, win_getid())
2232 enew | only
2233
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002234 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2235 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002236 set switchbuf=
2237 edit Xqftestfile1
2238 let file1_winid = win_getid()
2239 new Xqftestfile2
2240 let file2_winid = win_getid()
2241 copen
2242 exe "normal 1G\<CR>"
2243 call assert_equal(file1_winid, win_getid())
2244 copen
2245 exe "normal 3G\<CR>"
2246 call assert_equal(file2_winid, win_getid())
2247 copen | only
2248 exe "normal 5G\<CR>"
2249 call assert_equal(2, winnr('$'))
2250 call assert_equal(1, bufwinnr('Xqftestfile3'))
2251
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002252 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002253 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002254 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002255 set switchbuf=usetab
2256 tabedit Xqftestfile1
2257 tabedit Xqftestfile2
2258 tabedit Xqftestfile3
2259 tabfirst
2260 copen | only
2261 clast
2262 call assert_equal(4, tabpagenr())
2263 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002264
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002265 " Jumping to a file that is not present in any of the tabpages and the
2266 " current tabpage doesn't have any usable windows, should open it in a new
2267 " window in the current tabpage.
2268 copen | only
2269 cfirst
2270 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002271 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002272
2273 " If opening a file changes 'switchbuf', then the new value should be
2274 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002275 set modeline&vim
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002276 call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002277 enew | only
2278 set switchbuf&vim
2279 cexpr "Xqftestfile1:1:10"
2280 call assert_equal('split', &switchbuf)
2281 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2282 enew | only
2283 set switchbuf=useopen
2284 cexpr "Xqftestfile1:1:10"
2285 call assert_equal('usetab', &switchbuf)
2286 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2287 enew | only
2288 set switchbuf=useopen
2289 cexpr "Xqftestfile1:1:10"
2290 call assert_equal('', &switchbuf)
2291
Bram Moolenaar049cba92016-06-26 14:38:04 +02002292 call delete('Xqftestfile2')
2293 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002294 set switchbuf&vim
2295
2296 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002297endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002298
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002299func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002300 call s:setup_commands(a:cchar)
2301
2302 enew | only
2303
Bram Moolenaarc1542742016-07-20 21:44:37 +02002304 let fname = 'Xqftestfile' . a:cchar
2305 call s:create_test_file(fname)
2306 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002307
Bram Moolenaarc1542742016-07-20 21:44:37 +02002308 Xgetexpr [fname . ':5:Line5',
2309 \ fname . ':10:Line10',
2310 \ fname . ':15:Line15',
2311 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002312
2313 6,14delete
2314 call append(6, ['Buffer', 'Window'])
2315
2316 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002317 call assert_equal(5, l[0].lnum)
2318 call assert_equal(6, l[2].lnum)
2319 call assert_equal(13, l[3].lnum)
2320
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002321 " If a file doesn't have any quickfix entries, then deleting lines in the
2322 " file should not update the quickfix list
2323 call g:Xsetlist([], 'f')
2324 1,2delete
2325 call assert_equal([], g:Xgetlist())
2326
Bram Moolenaar049cba92016-06-26 14:38:04 +02002327 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002328 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002329endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002330
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002331func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002332 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002333 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002334 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002335 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002336endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002337
2338" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002339func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002340 call s:setup_commands(a:cchar)
2341
2342 " The following lines are used for the grep test. Don't remove.
2343 " Grep_Test_Text: Match 1
2344 " Grep_Test_Text: Match 2
2345 " GrepAdd_Test_Text: Match 1
2346 " GrepAdd_Test_Text: Match 2
2347 enew! | only
2348 set makeef&vim
2349 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002350 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002351 Xopen
2352 call assert_true(w:quickfix_title =~ '^:grep')
2353 Xclose
2354 enew
2355 set makeef=Temp_File_##
2356 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002357 call assert_true(len(g:Xgetlist()) == 9)
2358
2359 " Try with 'grepprg' set to 'internal'
2360 set grepprg=internal
2361 silent Xgrep Grep_Test_Text: test_quickfix.vim
2362 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2363 call assert_true(len(g:Xgetlist()) == 9)
2364 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002365
2366 call writefile(['Vim'], 'XtestTempFile')
2367 set makeef=XtestTempFile
2368 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002369 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002370 call assert_false(filereadable('XtestTempFile'))
2371 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002372endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002373
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002374func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002375 " The grepprg may not be set on non-Unix systems
2376 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002377
2378 call s:test_xgrep('c')
2379 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002380endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002381
glepnir7b9eb632025-05-16 19:49:23 +02002382func Test_local_grepformat()
2383 let save_grepformat = &grepformat
2384 set grepformat=%f:%l:%m
2385 " The following line are used for the local grep test. Don't remove.
2386 " UNIQUEPREFIX:2:3: Local grepformat test
2387 new
2388 setlocal grepformat=UNIQUEPREFIX:%c:%n:%m
2389 call assert_equal('UNIQUEPREFIX:%c:%n:%m', &l:grepformat)
2390 call assert_equal('%f:%l:%m', &g:grepformat)
2391
2392 set grepprg=internal
2393 silent grep "^[[:space:]]*\" UNIQUEPREFIX:" test_quickfix.vim
2394 call assert_equal(1, len(getqflist()))
2395 set grepprg&vim
2396
2397 bwipe!
2398 let &grepformat = save_grepformat
2399endfunc
2400
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002401func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002402 " Use one 'errorformat' for two windows. Add an expression to each of them,
2403 " make sure they each keep their own state.
2404 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002405 call mkdir('Xone/a', 'pR')
2406 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002407 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2408 call writefile(lines, 'Xone/a/one.txt')
2409 call writefile(lines, 'Xtwo/a/two.txt')
2410
2411 new one
2412 let one_id = win_getid()
2413 lexpr ""
2414 new two
2415 let two_id = win_getid()
2416 lexpr ""
2417
2418 laddexpr "Entering dir 'Xtwo/a'"
2419 call win_gotoid(one_id)
2420 laddexpr "Entering dir 'Xone/a'"
2421 call win_gotoid(two_id)
2422 laddexpr 'two.txt:5:two two two'
2423 call win_gotoid(one_id)
2424 laddexpr 'one.txt:3:one one one'
2425
2426 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002427 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2428 call assert_equal(3, loc_one[1].lnum)
2429
2430 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002431 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2432 call assert_equal(5, loc_two[1].lnum)
2433
2434 call win_gotoid(one_id)
2435 bwipe!
2436 call win_gotoid(two_id)
2437 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002438endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002439
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002440func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002441 call s:setup_commands(a:cchar)
2442
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002443 " Calling lbottom without any errors should fail
2444 if a:cchar == 'l'
2445 call assert_fails('lbottom', 'E776:')
2446 endif
2447
Bram Moolenaar875feea2017-06-11 16:07:51 +02002448 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002449 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002450 let wid = win_getid()
2451 call assert_equal(1, line('.'))
2452 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002453 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002454 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002455 call win_gotoid(wid)
2456 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002457 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002458endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002459
2460" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002461func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002462 call XbottomTests('c')
2463 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002464endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002465
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002466func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002467 call s:setup_commands(a:cchar)
2468
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002469 " clear all lists after the first one, then replace the first one.
2470 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002471 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002472 let entry = {'filename': 'foo', 'lnum': 42}
2473 call g:Xsetlist([entry], 'r')
2474 call g:Xsetlist([entry, entry])
2475 call g:Xsetlist([entry, entry, entry])
2476 let res = split(execute(a:cchar . 'hist'), "\n")
2477 call assert_equal(3, len(res))
2478 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2479 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2480 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2481 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002482
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002483 " Test for changing the quickfix lists
2484 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2485 exe '1' . a:cchar . 'hist'
2486 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2487 exe '3' . a:cchar . 'hist'
2488 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2489 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2490 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2491
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002492 call g:Xsetlist([], 'f')
2493 let l = split(execute(a:cchar . 'hist'), "\n")
2494 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002495 if a:cchar == 'c'
2496 call assert_fails('4chist', 'E16:')
2497 else
2498 call assert_fails('4lhist', 'E776:')
2499 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002500
2501 " An empty list should still show the stack history
2502 call g:Xsetlist([])
2503 let res = split(execute(a:cchar . 'hist'), "\n")
2504 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2505
2506 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002507endfunc
2508
2509func Test_history()
2510 call HistoryTest('c')
2511 call HistoryTest('l')
2512endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002513
2514func Test_duplicate_buf()
2515 " make sure we can get the highest buffer number
2516 edit DoesNotExist
2517 edit DoesNotExist2
2518 let last_buffer = bufnr("$")
2519
2520 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002521 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002522 vimgrep one Xgrepthis
2523 vimgrep one Xgrepthis
2524 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002525endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002526
2527" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002528func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002529 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002530
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002531 " Error cases
2532 call assert_fails('call g:Xgetlist(99)', 'E715:')
2533 call assert_fails('call g:Xsetlist(99)', 'E714:')
2534 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002535
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002536 " Set and get the title
2537 call g:Xsetlist([])
2538 Xopen
2539 wincmd p
2540 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2541 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2542 call assert_equal(0, s)
2543 let d = g:Xgetlist({"title":1})
2544 call assert_equal('Sample', d.title)
2545 " Try setting title to a non-string value
2546 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2547 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2548
2549 Xopen
2550 call assert_equal('Sample', w:quickfix_title)
2551 Xclose
2552
2553 " Tests for action argument
2554 silent! Xolder 999
2555 let qfnr = g:Xgetlist({'all':1}).nr
2556 call g:Xsetlist([], 'r', {'title' : 'N1'})
2557 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2558 call g:Xsetlist([], ' ', {'title' : 'N2'})
2559 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2560
2561 let res = g:Xgetlist({'nr': 0})
2562 call assert_equal(qfnr + 1, res.nr)
2563 call assert_equal(['nr'], keys(res))
2564
2565 call g:Xsetlist([], ' ', {'title' : 'N3'})
2566 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2567
2568 " Changing the title of an earlier quickfix list
2569 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2570 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2571
2572 " Changing the title of an invalid quickfix list
2573 call assert_equal(-1, g:Xsetlist([], ' ',
2574 \ {'title' : 'SomeTitle', 'nr' : 99}))
2575 call assert_equal(-1, g:Xsetlist([], ' ',
2576 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2577
2578 if a:cchar == 'c'
2579 copen
2580 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2581 cclose
2582 endif
2583
2584 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002585 call assert_fails('call g:Xgetlist([])', 'E715:')
2586 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002587 let s = g:Xsetlist([], 'a', {'abc':1})
2588 call assert_equal(-1, s)
2589
2590 call assert_equal({}, g:Xgetlist({'abc':1}))
2591 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2592 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2593
2594 if a:cchar == 'l'
2595 call assert_equal({}, getloclist(99, {'title': 1}))
2596 endif
2597
2598 " Context related tests
2599 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2600 call assert_equal(0, s)
2601 call test_garbagecollect_now()
2602 let d = g:Xgetlist({'context':1})
2603 call assert_equal([1,2,3], d.context)
2604 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2605 let d = g:Xgetlist({'context':1})
2606 call assert_equal({'color':'green'}, d.context)
2607 call g:Xsetlist([], 'a', {'context':"Context info"})
2608 let d = g:Xgetlist({'context':1})
2609 call assert_equal("Context info", d.context)
2610 call g:Xsetlist([], 'a', {'context':246})
2611 let d = g:Xgetlist({'context':1})
2612 call assert_equal(246, d.context)
2613 " set other Vim data types as context
2614 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2615 if has('channel')
2616 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2617 endif
2618 if has('job')
2619 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2620 endif
2621 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2622 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2623 call g:Xsetlist([], 'a', {'context' : ''})
2624 call test_garbagecollect_now()
2625 if a:cchar == 'l'
2626 " Test for copying context across two different location lists
2627 new | only
2628 let w1_id = win_getid()
2629 let l = [1]
2630 call setloclist(0, [], 'a', {'context':l})
2631 new
2632 let w2_id = win_getid()
2633 call add(l, 2)
2634 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2635 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2636 unlet! l
2637 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2638 only
2639 call setloclist(0, [], 'f')
2640 call assert_equal('', getloclist(0, {'context':1}).context)
2641 endif
2642
2643 " Test for changing the context of previous quickfix lists
2644 call g:Xsetlist([], 'f')
2645 Xexpr "One"
2646 Xexpr "Two"
2647 Xexpr "Three"
2648 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2649 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2650 " Also, check for setting the context using quickfix list number zero.
2651 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2652 call test_garbagecollect_now()
2653 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2654 call assert_equal([1], l.context)
2655 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2656 call assert_equal([2], l.context)
2657 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2658 call assert_equal([3], l.context)
2659
2660 " Test for changing the context through reference and for garbage
2661 " collection of quickfix context
2662 let l = ["red"]
2663 call g:Xsetlist([], ' ', {'context' : l})
2664 call add(l, "blue")
2665 let x = g:Xgetlist({'context' : 1})
2666 call add(x.context, "green")
2667 call assert_equal(["red", "blue", "green"], l)
2668 call assert_equal(["red", "blue", "green"], x.context)
2669 unlet l
2670 call test_garbagecollect_now()
2671 let m = g:Xgetlist({'context' : 1})
2672 call assert_equal(["red", "blue", "green"], m.context)
2673
2674 " Test for setting/getting items
2675 Xexpr ""
2676 let qfprev = g:Xgetlist({'nr':0})
2677 let s = g:Xsetlist([], ' ', {'title':'Green',
2678 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2679 call assert_equal(0, s)
2680 let qfcur = g:Xgetlist({'nr':0})
2681 call assert_true(qfcur.nr == qfprev.nr + 1)
2682 let l = g:Xgetlist({'items':1})
2683 call assert_equal('F1', bufname(l.items[0].bufnr))
2684 call assert_equal(10, l.items[0].lnum)
2685 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2686 \ {'filename':'F2', 'lnum':30}]})
2687 let l = g:Xgetlist({'items':1})
2688 call assert_equal('F2', bufname(l.items[2].bufnr))
2689 call assert_equal(30, l.items[2].lnum)
2690 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2691 let l = g:Xgetlist({'items':1})
2692 call assert_equal('F3', bufname(l.items[0].bufnr))
2693 call assert_equal(40, l.items[0].lnum)
2694 call g:Xsetlist([], 'r', {'items' : []})
2695 let l = g:Xgetlist({'items':1})
2696 call assert_equal(0, len(l.items))
2697
2698 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2699 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2700 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2701 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2702
2703 " Test for getting id of window associated with a location list window
2704 if a:cchar == 'l'
2705 only
2706 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2707 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002708 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002709 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2710 wincmd w
2711 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2712 only
2713 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002714
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002715 " The following used to crash Vim with address sanitizer
2716 call g:Xsetlist([], 'f')
2717 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2718 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002719
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002720 " Try setting the items using a string
2721 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002722
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002723 " Save and restore the quickfix stack
2724 call g:Xsetlist([], 'f')
2725 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2726 Xexpr "File1:10:Line1"
2727 Xexpr "File2:20:Line2"
2728 Xexpr "File3:30:Line3"
2729 let last_qf = g:Xgetlist({'nr':'$'}).nr
2730 call assert_equal(3, last_qf)
2731 let qstack = []
2732 for i in range(1, last_qf)
2733 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2734 endfor
2735 call g:Xsetlist([], 'f')
2736 for i in range(len(qstack))
2737 call g:Xsetlist([], ' ', qstack[i])
2738 endfor
2739 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2740 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2741 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2742 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2743 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002744
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002745 " Swap two quickfix lists
2746 Xexpr "File1:10:Line10"
2747 Xexpr "File2:20:Line20"
2748 Xexpr "File3:30:Line30"
2749 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2750 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2751 let l1=g:Xgetlist({'nr':1,'all':1})
2752 let l2=g:Xgetlist({'nr':2,'all':1})
2753 let save_id = l1.id
2754 let l1.id=l2.id
2755 let l2.id=save_id
2756 call g:Xsetlist([], 'r', l1)
2757 call g:Xsetlist([], 'r', l2)
2758 let newl1=g:Xgetlist({'nr':1,'all':1})
2759 let newl2=g:Xgetlist({'nr':2,'all':1})
2760 call assert_equal('Fruits', newl1.title)
2761 call assert_equal(['Fruits'], newl1.context)
2762 call assert_equal('Line20', newl1.items[0].text)
2763 call assert_equal('Colors', newl2.title)
2764 call assert_equal(['Colors'], newl2.context)
2765 call assert_equal('Line10', newl2.items[0].text)
2766 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002767
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002768 " Cannot specify both a non-empty list argument and a dict argument
2769 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002770endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002771
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002772func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002773 call Xproperty_tests('c')
2774 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002775endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002776
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002777" Test for setting the current index in the location/quickfix list
2778func Xtest_setqfidx(cchar)
2779 call s:setup_commands(a:cchar)
2780
2781 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2782 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2783 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2784
2785 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2786 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2787 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2788 Xolder 2
2789 Xopen
2790 call assert_equal(3, line('.'))
2791 Xnewer
2792 call assert_equal(2, line('.'))
2793 Xnewer
2794 call assert_equal(2, line('.'))
2795 " Update the current index with the quickfix window open
2796 wincmd w
2797 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2798 Xopen
2799 call assert_equal(3, line('.'))
2800 Xclose
2801
2802 " Set the current index to the last entry
2803 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2804 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2805 " A large value should set the index to the last index
2806 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2807 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2808 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2809 " Invalid index values
2810 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2811 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2812 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2813 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2814 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2815 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2816 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2817
2818 call g:Xsetlist([], 'f')
2819 new | only
2820endfunc
2821
2822func Test_setqfidx()
2823 call Xtest_setqfidx('c')
2824 call Xtest_setqfidx('l')
2825endfunc
2826
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002827" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002828func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002829 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002830endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002831
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002832func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002833 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2834 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2835
2836 let g:acmds = []
2837 cexpr "F1:10:Line 10"
2838 caddexpr "F1:20:Line 20"
2839 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002840 cexpr ""
2841 caddexpr ""
2842 cgetexpr ""
2843 silent! cexpr non_existing_func()
2844 silent! caddexpr non_existing_func()
2845 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002846 let l =<< trim END
2847 precexpr
2848 postcexpr
2849 precaddexpr
2850 postcaddexpr
2851 precgetexpr
2852 postcgetexpr
2853 precexpr
2854 postcexpr
2855 precaddexpr
2856 postcaddexpr
2857 precgetexpr
2858 postcgetexpr
2859 precexpr
2860 precaddexpr
2861 precgetexpr
2862 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002863 call assert_equal(l, g:acmds)
2864
2865 let g:acmds = []
2866 enew! | call append(0, "F2:10:Line 10")
2867 cbuffer!
2868 enew! | call append(0, "F2:20:Line 20")
2869 cgetbuffer
2870 enew! | call append(0, "F2:30:Line 30")
2871 caddbuffer
2872 new
2873 let bnum = bufnr('%')
2874 bunload
2875 exe 'silent! cbuffer! ' . bnum
2876 exe 'silent! cgetbuffer ' . bnum
2877 exe 'silent! caddbuffer ' . bnum
2878 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002879 let l =<< trim END
2880 precbuffer
2881 postcbuffer
2882 precgetbuffer
2883 postcgetbuffer
2884 precaddbuffer
2885 postcaddbuffer
2886 precbuffer
2887 precgetbuffer
2888 precaddbuffer
2889 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002890 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002891
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002892 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2893 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002894 let g:acmds = []
2895 cfile Xtest
2896 caddfile Xtest
2897 cgetfile Xtest
2898 cfile Xempty
2899 caddfile Xempty
2900 cgetfile Xempty
2901 silent! cfile do_not_exist
2902 silent! caddfile do_not_exist
2903 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002904 let l =<< trim END
2905 precfile
2906 postcfile
2907 precaddfile
2908 postcaddfile
2909 precgetfile
2910 postcgetfile
2911 precfile
2912 postcfile
2913 precaddfile
2914 postcaddfile
2915 precgetfile
2916 postcgetfile
2917 precfile
2918 postcfile
2919 precaddfile
2920 postcaddfile
2921 precgetfile
2922 postcgetfile
2923 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002924 call assert_equal(l, g:acmds)
2925
2926 let g:acmds = []
2927 helpgrep quickfix
2928 silent! helpgrep non_existing_help_topic
2929 vimgrep test Xtest
2930 vimgrepadd test Xtest
2931 silent! vimgrep non_existing_test Xtest
2932 silent! vimgrepadd non_existing_test Xtest
2933 set makeprg=
2934 silent! make
2935 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002936 let l =<< trim END
2937 prehelpgrep
2938 posthelpgrep
2939 prehelpgrep
2940 posthelpgrep
2941 previmgrep
2942 postvimgrep
2943 previmgrepadd
2944 postvimgrepadd
2945 previmgrep
2946 postvimgrep
2947 previmgrepadd
2948 postvimgrepadd
2949 premake
2950 postmake
2951 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002952 call assert_equal(l, g:acmds)
2953
2954 if has('unix')
2955 " Run this test only on Unix-like systems. The grepprg may not be set on
2956 " non-Unix systems.
2957 " The following lines are used for the grep test. Don't remove.
2958 " Grep_Autocmd_Text: Match 1
2959 " GrepAdd_Autocmd_Text: Match 2
2960 let g:acmds = []
2961 silent grep Grep_Autocmd_Text test_quickfix.vim
2962 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2963 silent grep abc123def Xtest
2964 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002965 set grepprg=internal
2966 silent grep Grep_Autocmd_Text test_quickfix.vim
2967 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2968 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2969 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2970 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002971 let l =<< trim END
2972 pregrep
2973 postgrep
2974 pregrepadd
2975 postgrepadd
2976 pregrep
2977 postgrep
2978 pregrepadd
2979 postgrepadd
2980 pregrep
2981 postgrep
2982 pregrepadd
2983 postgrepadd
2984 prelgrep
2985 postlgrep
2986 prelgrepadd
2987 postlgrepadd
2988 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002989 call assert_equal(l, g:acmds)
2990 endif
2991
Bram Moolenaarb254af32017-12-18 19:48:58 +01002992 au! QuickFixCmdPre
2993 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002994endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002995
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002996func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002997 set efm=%m
2998 lgetexpr '?'
2999
3000 try
3001 call DoesNotExit()
3002 catch
3003 lgetexpr '1'
3004 finally
3005 lgetexpr '1'
3006 endtry
3007
3008 call assert_equal('1', getloclist(0)[0].text)
3009
3010 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003011endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003012
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003013func Test_caddbuffer_wrong()
3014 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003015 let save_efm = &efm
3016 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
3017 cgetexpr ['WWWW', 'EEEE', 'CCCC']
3018 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003019 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003020 bwipe!
3021endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003022
3023func Test_caddexpr_wrong()
3024 " This used to cause a memory access in freed memory.
3025 cbuffer
3026 cbuffer
3027 copen
3028 let save_efm = &efm
3029 set efm=%
3030 call assert_fails('caddexpr ""', 'E376:')
3031 let &efm = save_efm
3032endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01003033
3034func Test_dirstack_cleanup()
3035 " This used to cause a memory access in freed memory.
3036 let save_efm = &efm
3037 lexpr '0'
3038 lopen
3039 fun X(c)
3040 let save_efm=&efm
3041 set efm=%D%f
3042 if a:c == 'c'
3043 caddexpr '::'
3044 else
3045 laddexpr ':0:0'
3046 endif
3047 let &efm=save_efm
3048 endfun
3049 call X('c')
3050 call X('l')
3051 call setqflist([], 'r')
3052 caddbuffer
3053 let &efm = save_efm
3054endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003055
3056" Tests for jumping to entries from the location list window and quickfix
3057" window
3058func Test_cwindow_jump()
3059 set efm=%f%%%l%%%m
3060 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3061 lopen | only
3062 lfirst
3063 call assert_true(winnr('$') == 2)
3064 call assert_true(winnr() == 1)
3065 " Location list for the new window should be set
3066 call assert_true(getloclist(0)[2].text == 'Line 30')
3067
3068 " Open a scratch buffer
3069 " Open a new window and create a location list
3070 " Open the location list window and close the other window
3071 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003072 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003073 " should not be used.
3074 enew | only
3075 set buftype=nofile
3076 below new
3077 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3078 lopen
3079 2wincmd c
3080 lnext
3081 call assert_true(winnr('$') == 3)
3082 call assert_true(winnr() == 2)
3083
3084 " Open two windows with two different location lists
3085 " Open the location list window and close the previous window
3086 " Jump to an entry in the location list window
3087 " Should open the file in the first window and not set the location list.
3088 enew | only
3089 lgetexpr ["F1%5%Line 5"]
3090 below new
3091 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3092 lopen
3093 2wincmd c
3094 lnext
3095 call assert_true(winnr() == 1)
3096 call assert_true(getloclist(0)[0].text == 'Line 5')
3097
3098 enew | only
3099 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3100 copen
3101 cnext
3102 call assert_true(winnr('$') == 2)
3103 call assert_true(winnr() == 1)
3104
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003105 " open the quickfix buffer in two windows and jump to an entry. Should open
3106 " the file in the first quickfix window.
3107 enew | only
3108 copen
3109 let bnum = bufnr('')
3110 exe 'sbuffer ' . bnum
3111 wincmd b
3112 cfirst
3113 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003114 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003115 enew | only
3116 exe 'sb' bnum
3117 exe 'botright sb' bnum
3118 wincmd t
3119 clast
3120 call assert_equal(2, winnr())
3121 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3122 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3123
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003124 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003125 " window by wrapping around the window list.
3126 enew | only
3127 call setloclist(0, [], 'f')
3128 new | new
3129 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3130 lopen
3131 1close
3132 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3133 lnext
3134 call assert_equal(3, winnr())
3135 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3136
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003137 enew | only
3138 set efm&vim
3139endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003140
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003141func Test_cwindow_highlight()
3142 CheckScreendump
3143
3144 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003145 call setline(1, ['some', 'text', 'with', 'matches'])
3146 write XCwindow
3147 vimgrep e XCwindow
3148 redraw
3149 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003150 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003151 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003152 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3153 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3154
3155 call term_sendkeys(buf, ":cnext\<CR>")
3156 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3157
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003158 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003159 call term_sendkeys(buf, ":\<CR>")
3160 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3161
3162 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3163 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003164 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3165
3166 call term_sendkeys(buf, "j")
3167 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3168
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003169 " clean up
3170 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003171 call delete('XCwindow')
3172endfunc
3173
Bram Moolenaaree85df32017-03-19 14:19:50 +01003174func XvimgrepTests(cchar)
3175 call s:setup_commands(a:cchar)
3176
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003177 let lines =<< trim END
3178 Editor:VIM vim
3179 Editor:Emacs EmAcS
3180 Editor:Notepad NOTEPAD
3181 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003182 call writefile(lines, 'Xtestfile1', 'D')
3183 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003184
3185 " Error cases
3186 call assert_fails('Xvimgrep /abc *', 'E682:')
3187
3188 let @/=''
3189 call assert_fails('Xvimgrep // *', 'E35:')
3190
3191 call assert_fails('Xvimgrep abc', 'E683:')
3192 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3193 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3194
3195 Xexpr ""
3196 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003197 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003198 let l = g:Xgetlist()
3199 call assert_equal(2, len(l))
3200 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3201
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003202 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003203 let l = g:Xgetlist()
3204 call assert_equal(2, len(l))
3205 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003206 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003207 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003208 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003209
3210 1Xvimgrep ?Editor? Xtestfile*
3211 let l = g:Xgetlist()
3212 call assert_equal(1, len(l))
3213 call assert_equal('Editor:VIM vim', l[0].text)
3214
3215 edit +3 Xtestfile2
3216 Xvimgrep +\cemacs+j Xtestfile1
3217 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003218 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003219 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3220
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003221 " Test for unloading a buffer after vimgrep searched the buffer
3222 %bwipe
3223 Xvimgrep /Editor/j Xtestfile*
3224 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3225 call assert_equal([], getbufinfo('Xtestfile2'))
3226
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003227 " Test for opening the dummy buffer used by vimgrep in a window. The new
3228 " window should be closed
3229 %bw!
3230 augroup QF_Test
3231 au!
3232 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3233 augroup END
3234 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3235 call assert_equal(1, winnr('$'))
3236 augroup QF_Test
3237 au!
3238 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003239endfunc
3240
3241" Tests for the :vimgrep command
3242func Test_vimgrep()
3243 call XvimgrepTests('c')
3244 call XvimgrepTests('l')
3245endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003246
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003247func Test_vimgrep_wildcards_expanded_once()
3248 new X[id-01] file.txt
3249 call setline(1, 'some text to search for')
3250 vimgrep text %
3251 bwipe!
3252endfunc
3253
Bram Moolenaar1c299432018-10-28 14:36:09 +01003254" Test for incsearch highlighting of the :vimgrep pattern
3255" This test used to cause "E315: ml_get: invalid lnum" errors.
3256func Test_vimgrep_incsearch()
3257 enew
3258 set incsearch
3259 call test_override("char_avail", 1)
3260
3261 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3262 let l = getqflist()
3263 call assert_equal(2, len(l))
3264
3265 call test_override("ALL", 0)
3266 set noincsearch
3267endfunc
3268
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003269" Test vimgrep with the last search pattern not set
3270func Test_vimgrep_with_no_last_search_pat()
3271 let lines =<< trim [SCRIPT]
3272 call assert_fails('vimgrep // *', 'E35:')
3273 call writefile(v:errors, 'Xresult')
3274 qall!
3275 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003276 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003277 if RunVim([], [], '--clean -S Xscript')
3278 call assert_equal([], readfile('Xresult'))
3279 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003280 call delete('Xresult')
3281endfunc
3282
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003283" Test vimgrep without swap file
3284func Test_vimgrep_without_swap_file()
3285 let lines =<< trim [SCRIPT]
3286 vimgrep grep test_c*
3287 call writefile(['done'], 'Xresult')
3288 qall!
3289 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003290 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003291 if RunVim([], [], '--clean -n -S Xscript Xscript')
3292 call assert_equal(['done'], readfile('Xresult'))
3293 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003294 call delete('Xresult')
3295endfunc
3296
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003297func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003298 call writefile(['match apple with apple'], 'Xapple', 'D')
3299 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003300 let g:foundSwap = 0
3301 let g:ignoreSwapExists = 1
3302 augroup grep
3303 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3304 augroup END
3305 vimgrep apple Xapple
3306 call assert_equal(1, g:foundSwap)
3307 call assert_match('.Xapple.swo', swapname(''))
3308
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003309 augroup grep
3310 au! SwapExists
3311 augroup END
3312 unlet g:ignoreSwapExists
3313endfunc
3314
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003315func XfreeTests(cchar)
3316 call s:setup_commands(a:cchar)
3317
3318 enew | only
3319
3320 " Deleting the quickfix stack should work even When the current list is
3321 " somewhere in the middle of the stack
3322 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3323 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3324 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3325 Xolder
3326 call g:Xsetlist([], 'f')
3327 call assert_equal(0, len(g:Xgetlist()))
3328
3329 " After deleting the stack, adding a new list should create a stack with a
3330 " single list.
3331 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3332 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3333
3334 " Deleting the stack from a quickfix window should update/clear the
3335 " quickfix/location list window.
3336 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3337 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3338 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3339 Xolder
3340 Xwindow
3341 call g:Xsetlist([], 'f')
3342 call assert_equal(2, winnr('$'))
3343 call assert_equal(1, line('$'))
3344 Xclose
3345
3346 " Deleting the stack from a non-quickfix window should update/clear the
3347 " quickfix/location list window.
3348 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3349 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3350 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3351 Xolder
3352 Xwindow
3353 wincmd p
3354 call g:Xsetlist([], 'f')
3355 call assert_equal(0, len(g:Xgetlist()))
3356 wincmd p
3357 call assert_equal(2, winnr('$'))
3358 call assert_equal(1, line('$'))
3359
3360 " After deleting the location list stack, if the location list window is
3361 " opened, then a new location list should be created. So opening the
3362 " location list window again should not create a new window.
3363 if a:cchar == 'l'
3364 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3365 wincmd p
3366 lopen
3367 call assert_equal(2, winnr('$'))
3368 endif
3369 Xclose
3370endfunc
3371
Bram Moolenaar74240d32017-12-10 15:26:15 +01003372" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003373func Test_qf_free()
3374 call XfreeTests('c')
3375 call XfreeTests('l')
3376endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003377
3378" Test for buffer overflow when parsing lines and adding new entries to
3379" the quickfix list.
3380func Test_bufoverflow()
3381 set efm=%f:%l:%m
3382 cgetexpr ['File1:100:' . repeat('x', 1025)]
3383
3384 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3385 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3386
3387 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003388 let lines =<< trim eval END
3389 Entering directory $"{repeat('a', 1006)}"
3390 File1:10:Hello World
3391 END
3392 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003393 set efm&vim
3394endfunc
3395
Bram Moolenaar875feea2017-06-11 16:07:51 +02003396" Tests for getting the quickfix stack size
3397func XsizeTests(cchar)
3398 call s:setup_commands(a:cchar)
3399
3400 call g:Xsetlist([], 'f')
3401 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003402 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3403 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003404
3405 Xexpr "File1:10:Line1"
3406 Xexpr "File2:20:Line2"
3407 Xexpr "File3:30:Line3"
3408 Xolder | Xolder
3409 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3410 call g:Xsetlist([], 'f')
3411
3412 Xexpr "File1:10:Line1"
3413 Xexpr "File2:20:Line2"
3414 Xexpr "File3:30:Line3"
3415 Xolder | Xolder
3416 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3417 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3418endfunc
3419
3420func Test_Qf_Size()
3421 call XsizeTests('c')
3422 call XsizeTests('l')
3423endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003424
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003425func Test_cclose_from_copen()
3426 augroup QF_Test
3427 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003428 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003429 augroup END
3430 copen
3431 augroup QF_Test
3432 au!
3433 augroup END
3434 augroup! QF_Test
3435endfunc
3436
Bram Moolenaar18141832017-06-25 21:17:25 +02003437func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003438 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003439 " event will be triggered.
3440 call test_override('starting', 1)
3441 augroup QF_Test
3442 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003443 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003444 augroup END
3445 copen
3446 augroup QF_Test
3447 au!
3448 augroup END
3449 augroup! QF_Test
3450 call test_override('starting', 0)
3451endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003452
Bram Moolenaar379fb762018-08-30 15:58:28 +02003453" Check that ":file" without an argument is possible even when "curbuf_lock"
3454" is set.
3455func Test_file_from_copen()
3456 " Works without argument.
3457 augroup QF_Test
3458 au!
3459 au FileType qf file
3460 augroup END
3461 copen
3462
3463 augroup QF_Test
3464 au!
3465 augroup END
3466 cclose
3467
3468 " Fails with argument.
3469 augroup QF_Test
3470 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003471 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003472 augroup END
3473 copen
3474 augroup QF_Test
3475 au!
3476 augroup END
3477 cclose
3478
3479 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003480endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003481
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003482func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003483 augroup QF_Test
3484 au!
3485 au FileType qf resize 5
3486 augroup END
3487 try
3488 " This should succeed without any exception. No other buffers are
3489 " involved in the autocmd.
3490 copen
3491 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003492 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003493 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003494 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003495 augroup! QF_Test
3496 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003497endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003498
Bram Moolenaard0fab102022-10-20 16:03:33 +01003499func Test_filetype_autocmd()
3500 " this changes the location list while it is in use to fill a buffer
3501 lexpr ''
3502 lopen
3503 augroup FT_loclist
3504 au FileType * call setloclist(0, [], 'f')
3505 augroup END
3506 silent! lolder
3507 lexpr ''
3508
3509 augroup FT_loclist
3510 au! FileType
3511 augroup END
3512endfunc
3513
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003514func Test_vimgrep_with_textlock()
3515 new
3516
zeertzjqcfe45652022-05-27 17:26:55 +01003517 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003518 " Check that vimgrep without jumping can be executed.
3519 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3520 normal ax
3521 let qflist = getqflist()
3522 call assert_true(len(qflist) > 0)
3523 call assert_match('RunTheTest', qflist[0].text)
3524 call setqflist([], 'r')
3525 au! InsertCharPre
3526
3527 " Check that vimgrepadd without jumping can be executed.
3528 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3529 normal ax
3530 let qflist = getqflist()
3531 call assert_true(len(qflist) > 0)
3532 call assert_match('RunTheTest', qflist[0].text)
3533 call setqflist([], 'r')
3534 au! InsertCharPre
3535
3536 " Check that lvimgrep without jumping can be executed.
3537 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3538 normal ax
3539 let qflist = getloclist(0)
3540 call assert_true(len(qflist) > 0)
3541 call assert_match('RunTheTest', qflist[0].text)
3542 call setloclist(0, [], 'r')
3543 au! InsertCharPre
3544
3545 " Check that lvimgrepadd without jumping can be executed.
3546 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3547 normal ax
3548 let qflist = getloclist(0)
3549 call assert_true(len(qflist) > 0)
3550 call assert_match('RunTheTest', qflist[0].text)
3551 call setloclist(0, [], 'r')
3552 au! InsertCharPre
3553
3554 " trying to jump will give an error
3555 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3556 call assert_fails('normal ax', 'E565:')
3557 au! InsertCharPre
3558
3559 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3560 call assert_fails('normal ax', 'E565:')
3561 au! InsertCharPre
3562
3563 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3564 call assert_fails('normal ax', 'E565:')
3565 au! InsertCharPre
3566
3567 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3568 call assert_fails('normal ax', 'E565:')
3569 au! InsertCharPre
3570
3571 bwipe!
3572endfunc
3573
Bram Moolenaara8788f42017-07-19 17:06:20 +02003574" Tests for the quickfix buffer b:changedtick variable
3575func Xchangedtick_tests(cchar)
3576 call s:setup_commands(a:cchar)
3577
3578 new | only
3579
3580 Xexpr "" | Xexpr "" | Xexpr ""
3581
3582 Xopen
3583 Xolder
3584 Xolder
3585 Xaddexpr "F1:10:Line10"
3586 Xaddexpr "F2:20:Line20"
3587 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3588 call g:Xsetlist([], 'f')
3589 call assert_equal(8, getbufvar('%', 'changedtick'))
3590 Xclose
3591endfunc
3592
3593func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003594 call Xchangedtick_tests('c')
3595 call Xchangedtick_tests('l')
3596endfunc
3597
3598" Tests for parsing an expression using setqflist()
3599func Xsetexpr_tests(cchar)
3600 call s:setup_commands(a:cchar)
3601
3602 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003603 call g:Xsetlist([], ' ', {'lines' : t})
3604 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003605
3606 let l = g:Xgetlist()
3607 call assert_equal(3, len(l))
3608 call assert_equal(20, l[1].lnum)
3609 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003610 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003611 let l = g:Xgetlist()
3612 call assert_equal(1, len(l))
3613 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003614 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3615 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003616
3617 call g:Xsetlist([], 'f')
3618 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003619 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3620 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3621 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3622 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003623 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3624 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003625
3626 " Adding entries using a custom efm
3627 set efm&
3628 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3629 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3630 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3631 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3632 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3633 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3634 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3635 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003636endfunc
3637
3638func Test_setexpr()
3639 call Xsetexpr_tests('c')
3640 call Xsetexpr_tests('l')
3641endfunc
3642
3643" Tests for per quickfix/location list directory stack
3644func Xmultidirstack_tests(cchar)
3645 call s:setup_commands(a:cchar)
3646
3647 call g:Xsetlist([], 'f')
3648 Xexpr "" | Xexpr ""
3649
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003650 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3651 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3652 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3653 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003654
3655 let l1 = g:Xgetlist({'nr':1, 'items':1})
3656 let l2 = g:Xgetlist({'nr':2, 'items':1})
3657 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3658 call assert_equal(3, l1.items[1].lnum)
3659 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3660 call assert_equal(5, l2.items[1].lnum)
3661endfunc
3662
3663func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003664 call mkdir('Xone/a', 'pR')
3665 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003666 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3667 call writefile(lines, 'Xone/a/one.txt')
3668 call writefile(lines, 'Xtwo/a/two.txt')
3669 let save_efm = &efm
3670 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3671
3672 call Xmultidirstack_tests('c')
3673 call Xmultidirstack_tests('l')
3674
3675 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003676endfunc
3677
3678" Tests for per quickfix/location list file stack
3679func Xmultifilestack_tests(cchar)
3680 call s:setup_commands(a:cchar)
3681
3682 call g:Xsetlist([], 'f')
3683 Xexpr "" | Xexpr ""
3684
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003685 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3686 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3687 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3688 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003689
3690 let l1 = g:Xgetlist({'nr':1, 'items':1})
3691 let l2 = g:Xgetlist({'nr':2, 'items':1})
3692 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3693 call assert_equal(3, l1.items[1].lnum)
3694 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3695 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003696
3697 " Test for start of a new error line in the same line where a previous
3698 " error line ends with a file stack.
3699 let efm_val = 'Error\ l%l\ in\ %f,'
3700 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003701 let lines =<< trim END
3702 (one.txt
3703 Error l4 in one.txt
3704 ) (two.txt
3705 Error l6 in two.txt
3706 )
3707 Error l8 in one.txt
3708 END
3709 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003710 call assert_equal(3, len(l.items))
3711 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3712 call assert_equal(4, l.items[0].lnum)
3713 call assert_equal('one.txt', l.items[0].text)
3714 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3715 call assert_equal(6, l.items[1].lnum)
3716 call assert_equal('two.txt', l.items[1].text)
3717 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3718 call assert_equal(8, l.items[2].lnum)
3719 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003720endfunc
3721
3722func Test_multifilestack()
3723 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003724 call writefile(lines, 'one.txt', 'D')
3725 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003726 let save_efm = &efm
3727 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3728
3729 call Xmultifilestack_tests('c')
3730 call Xmultifilestack_tests('l')
3731
3732 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003733endfunc
3734
3735" Tests for per buffer 'efm' setting
3736func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003737 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3738 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003739 set efm=%f#%l#%m
3740 new | only
3741 new
3742 setlocal efm=%f-%l-%m
3743 cfile one.txt
3744 wincmd w
3745 caddfile two.txt
3746
3747 let l = getqflist()
3748 call assert_equal(10, l[0].lnum)
3749 call assert_equal('Line20', l[1].text)
3750
3751 set efm&
3752 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003753endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003754
3755" Open multiple help windows using ":lhelpgrep
3756" This test used to crash Vim
3757func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003758 new | only
3759 lhelpgrep window
3760 lopen
3761 e#
3762 lhelpgrep buffer
3763 call assert_equal(3, winnr('$'))
3764 call assert_true(len(getloclist(1)) != 0)
3765 call assert_true(len(getloclist(2)) != 0)
3766 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003767endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003768
3769" Tests for adding new quickfix lists using setqflist()
3770func XaddQf_tests(cchar)
3771 call s:setup_commands(a:cchar)
3772
3773 " Create a new list using ' ' for action
3774 call g:Xsetlist([], 'f')
3775 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3776 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3777 call assert_equal(1, l.nr)
3778 call assert_equal('Test1', l.title)
3779
3780 " Create a new list using ' ' for action and '$' for 'nr'
3781 call g:Xsetlist([], 'f')
3782 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3783 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3784 call assert_equal(1, l.nr)
3785 call assert_equal('Test2', l.title)
3786
3787 " Create a new list using 'a' for action
3788 call g:Xsetlist([], 'f')
3789 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3790 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3791 call assert_equal(1, l.nr)
3792 call assert_equal('Test3', l.title)
3793
3794 " Create a new list using 'a' for action and '$' for 'nr'
3795 call g:Xsetlist([], 'f')
3796 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3797 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3798 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3799 call assert_equal(1, l.nr)
3800 call assert_equal('Test4', l.title)
3801
3802 " Adding a quickfix list should remove all the lists following the current
3803 " list.
3804 Xexpr "" | Xexpr "" | Xexpr ""
3805 silent! 10Xolder
3806 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3807 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3808 call assert_equal(2, l.nr)
3809 call assert_equal('Test5', l.title)
3810
3811 " Add a quickfix list using '$' as the list number.
3812 let lastqf = g:Xgetlist({'nr':'$'}).nr
3813 silent! 99Xolder
3814 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3815 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3816 call assert_equal(lastqf + 1, l.nr)
3817 call assert_equal('Test6', l.title)
3818
3819 " Add a quickfix list using 'nr' set to one more than the quickfix
3820 " list size.
3821 let lastqf = g:Xgetlist({'nr':'$'}).nr
3822 silent! 99Xolder
3823 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3824 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3825 call assert_equal(lastqf + 1, l.nr)
3826 call assert_equal('Test7', l.title)
3827
3828 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3829 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3830 silent! 99Xolder
3831 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3832 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3833 call assert_equal(10, l.nr)
3834 call assert_equal('Test8', l.title)
3835
3836 " Add a quickfix list using 'nr' set to a value greater than 10
3837 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3838
3839 " Try adding a quickfix list with 'nr' set to a value greater than the
3840 " quickfix list size but less than 10.
3841 call g:Xsetlist([], 'f')
3842 Xexpr "" | Xexpr "" | Xexpr ""
3843 silent! 99Xolder
3844 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3845
3846 " Add a quickfix list using 'nr' set to a some string or list
3847 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3848endfunc
3849
3850func Test_add_qf()
3851 call XaddQf_tests('c')
3852 call XaddQf_tests('l')
3853endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003854
3855" Test for getting the quickfix list items from some text without modifying
3856" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003857func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003858 call s:setup_commands(a:cchar)
3859 call g:Xsetlist([], 'f')
3860
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003861 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003862 call assert_equal(2, len(l))
3863 call assert_equal(30, l[1].lnum)
3864
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003865 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3866 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3867 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3868 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003869
Bram Moolenaar36538222017-09-02 19:51:44 +02003870 " Parse text using a custom efm
3871 set efm&
3872 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3873 call assert_equal('Line30', l[0].text)
3874 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3875 call assert_equal('File3:30:Line30', l[0].text)
3876 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3877 call assert_equal({}, l)
3878 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3879 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3880
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003881 " Make sure that the quickfix stack is not modified
3882 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3883endfunc
3884
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003885func Test_get_list_from_lines()
3886 call XgetListFromLines('c')
3887 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003888endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003889
3890" Tests for the quickfix list id
3891func Xqfid_tests(cchar)
3892 call s:setup_commands(a:cchar)
3893
3894 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003895 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003896 Xexpr ''
3897 let start_id = g:Xgetlist({'id' : 0}).id
3898 Xexpr '' | Xexpr ''
3899 Xolder
3900 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3901 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3902 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003903 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003904 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003905 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3906 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003907
3908 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3909 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003910 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003911 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3912 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3913 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3914
3915 let qfid = g:Xgetlist({'id':0, 'nr':0})
3916 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003917 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003918endfunc
3919
3920func Test_qf_id()
3921 call Xqfid_tests('c')
3922 call Xqfid_tests('l')
3923endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003924
3925func Xqfjump_tests(cchar)
3926 call s:setup_commands(a:cchar)
3927
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003928 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3929 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3930 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003931
3932 call g:Xsetlist([], 'f')
3933
3934 " Tests for
3935 " Jumping to a line using a pattern
3936 " Jumping to a column greater than the last column in a line
3937 " Jumping to a line greater than the last line in the file
3938 let l = []
3939 for i in range(1, 7)
3940 call add(l, {})
3941 endfor
3942 let l[0].filename='F1'
3943 let l[0].pattern='Line1'
3944 let l[1].filename='F2'
3945 let l[1].pattern='Line1'
3946 let l[2].filename='F3'
3947 let l[2].pattern='Line1'
3948 let l[3].filename='F3'
3949 let l[3].lnum=1
3950 let l[3].col=9
3951 let l[3].vcol=1
3952 let l[4].filename='F3'
3953 let l[4].lnum=99
3954 let l[5].filename='F3'
3955 let l[5].lnum=1
3956 let l[5].col=99
3957 let l[5].vcol=1
3958 let l[6].filename='F3'
3959 let l[6].pattern='abcxyz'
3960
3961 call g:Xsetlist([], ' ', {'items' : l})
3962 Xopen | only
3963 2Xnext
3964 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003965 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003966 Xnext
3967 call assert_equal(7, col('.'))
3968 Xnext
3969 call assert_equal(2, line('.'))
3970 Xnext
3971 call assert_equal(9, col('.'))
3972 2
3973 Xnext
3974 call assert_equal(2, line('.'))
3975
3976 if a:cchar == 'l'
3977 " When jumping to a location list entry in the location list window and
3978 " no usable windows are available, then a new window should be opened.
3979 enew! | new | only
3980 call g:Xsetlist([], 'f')
3981 setlocal buftype=nofile
3982 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003983 let lines =<< trim END
3984 F1:1:1:Line1
3985 F1:2:2:Line2
3986 F2:1:1:Line1
3987 F2:2:2:Line2
3988 F3:1:1:Line1
3989 F3:2:2:Line2
3990 END
3991 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003992 Xopen
3993 let winid = win_getid()
3994 wincmd p
3995 close
3996 call win_gotoid(winid)
3997 Xnext
3998 call assert_equal(3, winnr('$'))
3999 call assert_equal(1, winnr())
4000 call assert_equal(2, line('.'))
4001
4002 " When jumping to an entry in the location list window and the window
4003 " associated with the location list is not present and a window containing
4004 " the file is already present, then that window should be used.
4005 close
4006 belowright new
4007 call g:Xsetlist([], 'f')
4008 edit F3
4009 call win_gotoid(winid)
4010 Xlast
4011 call assert_equal(3, winnr())
4012 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
4013 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
4014 endif
4015
4016 " Cleanup
4017 enew!
4018 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01004019endfunc
4020
4021func Test_qfjump()
4022 call Xqfjump_tests('c')
4023 call Xqfjump_tests('l')
4024endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01004025
4026" Tests for the getqflist() and getloclist() functions when the list is not
4027" present or is empty
4028func Xgetlist_empty_tests(cchar)
4029 call s:setup_commands(a:cchar)
4030
4031 " Empty quickfix stack
4032 call g:Xsetlist([], 'f')
4033 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4034 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
4035 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4036 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4037 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4038 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4039 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4040 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004041 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004042 if a:cchar == 'c'
4043 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004044 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004045 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4046 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004047 else
4048 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4049 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004050 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004051 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004052 \ g:Xgetlist({'all' : 0}))
4053 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004054
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004055 " Quickfix window with empty stack
4056 silent! Xopen
4057 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004058 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004059 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4060 Xclose
4061
Bram Moolenaara6d48492017-12-12 22:45:31 +01004062 " Empty quickfix list
4063 Xexpr ""
4064 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4065 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4066 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4067 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4068 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4069 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4070 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4071 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004072 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004073
4074 let qfid = g:Xgetlist({'id' : 0}).id
4075 call g:Xsetlist([], 'f')
4076
4077 " Non-existing quickfix identifier
4078 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4079 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4080 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4081 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4082 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4083 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4084 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4085 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004086 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004087 if a:cchar == 'c'
4088 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4089 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004090 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004091 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4092 else
4093 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4094 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004095 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4096 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004097 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4098 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004099
4100 " Non-existing quickfix list number
4101 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4102 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4103 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4104 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4105 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4106 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4107 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4108 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004109 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004110 if a:cchar == 'c'
4111 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4112 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004113 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4114 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004115 else
4116 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4117 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004118 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4119 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004120 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004121endfunc
4122
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004123func Test_empty_list_quickfixtextfunc()
4124 " This was crashing. Can only reproduce by running it in a separate Vim
4125 " instance.
4126 let lines =<< trim END
4127 func s:Func(o)
4128 cgetexpr '0'
4129 endfunc
4130 cope
4131 let &quickfixtextfunc = 's:Func'
4132 cgetfile [ex
4133 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004134 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004135 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004136endfunc
4137
Bram Moolenaara6d48492017-12-12 22:45:31 +01004138func Test_getqflist()
4139 call Xgetlist_empty_tests('c')
4140 call Xgetlist_empty_tests('l')
4141endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004142
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004143func Test_getqflist_invalid_nr()
4144 " The following commands used to crash Vim
4145 cexpr ""
4146 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4147
4148 " Cleanup
4149 call setqflist([], 'r')
4150endfunc
4151
Bram Moolenaarb254af32017-12-18 19:48:58 +01004152" Tests for the quickfix/location list changedtick
4153func Xqftick_tests(cchar)
4154 call s:setup_commands(a:cchar)
4155
4156 call g:Xsetlist([], 'f')
4157
4158 Xexpr "F1:10:Line10"
4159 let qfid = g:Xgetlist({'id' : 0}).id
4160 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4161 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4162 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4163 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4164 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4165 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4166 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4167 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4168 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4169
4170 enew!
4171 call append(0, ["F5:50:L50", "F6:60:L60"])
4172 Xaddbuffer
4173 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4174 enew!
4175
4176 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4177 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4178 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4179 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4180 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4181 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4182 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4183 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4184 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4185 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4186 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4187
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004188 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004189 Xfile Xone
4190 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4191 Xaddfile Xone
4192 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4193
4194 " Test case for updating a non-current quickfix list
4195 call g:Xsetlist([], 'f')
4196 Xexpr "F1:1:L1"
4197 Xexpr "F2:2:L2"
4198 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4199 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4200 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004201endfunc
4202
4203func Test_qf_tick()
4204 call Xqftick_tests('c')
4205 call Xqftick_tests('l')
4206endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004207
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004208" Test helpgrep with lang specifier
4209func Xtest_helpgrep_with_lang_specifier(cchar)
4210 call s:setup_commands(a:cchar)
4211 Xhelpgrep Vim@en
4212 call assert_equal('help', &filetype)
4213 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4214 new | only
4215endfunc
4216
4217func Test_helpgrep_with_lang_specifier()
4218 call Xtest_helpgrep_with_lang_specifier('c')
4219 call Xtest_helpgrep_with_lang_specifier('l')
4220endfunc
4221
Bram Moolenaar12237442017-12-19 12:38:52 +01004222" The following test used to crash Vim.
4223" Open the location list window and close the regular window associated with
4224" the location list. When the garbage collection runs now, it incorrectly
4225" marks the location list context as not in use and frees the context.
4226func Test_ll_window_ctx()
4227 call setloclist(0, [], 'f')
4228 call setloclist(0, [], 'a', {'context' : []})
4229 lopen | only
4230 call test_garbagecollect_now()
4231 echo getloclist(0, {'context' : 1}).context
4232 enew | only
4233endfunc
4234
zeertzjqbe4bd182024-09-14 10:32:31 +02004235" Similar to the problem above, but for user data.
4236func Test_ll_window_user_data()
4237 call setloclist(0, [#{bufnr: bufnr(), user_data: {}}])
4238 lopen
4239 wincmd t
4240 close
4241 call test_garbagecollect_now()
4242 call feedkeys("\<CR>", 'tx')
4243 call test_garbagecollect_now()
4244 %bwipe!
4245endfunc
4246
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004247" The following test used to crash vim
4248func Test_lfile_crash()
4249 sp Xtest
4250 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004251 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004252 au! QuickFixCmdPre
4253endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004254
4255" The following test used to crash vim
4256func Test_lbuffer_crash()
4257 sv Xtest
4258 augroup QF_Test
4259 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004260 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004261 augroup END
4262 lbuffer
4263 augroup QF_Test
4264 au!
4265 augroup END
4266endfunc
4267
4268" The following test used to crash vim
4269func Test_lexpr_crash()
4270 augroup QF_Test
4271 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004272 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004273 augroup END
4274 lexpr ""
4275 augroup QF_Test
4276 au!
4277 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004278
Bram Moolenaar3c097222017-12-21 20:54:49 +01004279 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004280 augroup QF_Test
4281 au!
4282 au BufNew * call setloclist(0, [], 'f')
4283 augroup END
4284 lexpr 'x:1:x'
4285 augroup QF_Test
4286 au!
4287 augroup END
4288
4289 enew | only
4290 lexpr ''
4291 lopen
4292 augroup QF_Test
4293 au!
4294 au FileType * call setloclist(0, [], 'f')
4295 augroup END
4296 lexpr ''
4297 augroup QF_Test
4298 au!
4299 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004300endfunc
4301
4302" The following test used to crash Vim
4303func Test_lvimgrep_crash()
Austin Chang29822992024-10-03 10:50:05 +02004304 " this leaves a swapfile .test_quickfix.vim.swp around, why?
Bram Moolenaar3c097222017-12-21 20:54:49 +01004305 sv Xtest
4306 augroup QF_Test
4307 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004308 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004309 augroup END
4310 lvimgrep quickfix test_quickfix.vim
4311 augroup QF_Test
4312 au!
4313 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004314
4315 new | only
4316 augroup QF_Test
4317 au!
4318 au BufEnter * call setloclist(0, [], 'r')
4319 augroup END
4320 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4321 augroup QF_Test
4322 au!
4323 augroup END
4324
Bram Moolenaar3c097222017-12-21 20:54:49 +01004325 enew | only
4326endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004327
Bram Moolenaar2573af32020-03-14 17:21:34 +01004328func Test_lvimgrep_crash2()
4329 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004330 call assert_fails('lvimgrep x x', 'E471:')
4331 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004332
4333 au! BufNewFile
4334endfunc
4335
Bram Moolenaarde046542017-12-26 13:53:11 +01004336" Test for the position of the quickfix and location list window
4337func Test_qfwin_pos()
4338 " Open two windows
4339 new | only
4340 new
4341 cexpr ['F1:10:L10']
4342 copen
4343 " Quickfix window should be the bottom most window
4344 call assert_equal(3, winnr())
4345 close
4346 " Open at the very top
4347 wincmd t
4348 topleft copen
4349 call assert_equal(1, winnr())
4350 close
4351 " open left of the current window
4352 wincmd t
4353 below new
4354 leftabove copen
4355 call assert_equal(2, winnr())
4356 close
4357 " open right of the current window
4358 rightbelow copen
4359 call assert_equal(3, winnr())
4360 close
4361endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004362
4363" Tests for quickfix/location lists changed by autocommands when
4364" :vimgrep/:lvimgrep commands are running.
4365func Test_vimgrep_autocmd()
4366 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004367 call writefile(['stars'], 'Xtest1.txt', 'D')
4368 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004369
4370 " Test 1:
4371 " When searching for a pattern using :vimgrep, if the quickfix list is
4372 " changed by an autocmd, the results should be added to the correct quickfix
4373 " list.
4374 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4375 silent vimgrep stars Xtest*.txt
4376 call assert_equal(1, getqflist({'nr' : 0}).nr)
4377 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4378 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4379 au! BufRead Xtest2.txt
4380
4381 " Test 2:
4382 " When searching for a pattern using :vimgrep, if the quickfix list is
4383 " freed, then a error should be given.
4384 silent! %bwipe!
4385 call setqflist([], 'f')
4386 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4387 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4388 au! BufRead Xtest2.txt
4389
4390 " Test 3:
4391 " When searching for a pattern using :lvimgrep, if the location list is
4392 " freed, then the command should error out.
4393 silent! %bwipe!
4394 let g:save_winid = win_getid()
4395 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4396 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4397 au! BufRead Xtest2.txt
Austin Chang29822992024-10-03 10:50:05 +02004398 " cleanup the swap files
4399 bw! Xtest2.txt Xtest1.txt
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004400
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004401 call setqflist([], 'f')
4402endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004403
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004404" Test for an autocmd changing the current directory when running vimgrep
4405func Xvimgrep_autocmd_cd(cchar)
4406 call s:setup_commands(a:cchar)
4407
4408 %bwipe
4409 let save_cwd = getcwd()
4410
4411 augroup QF_Test
4412 au!
4413 autocmd BufRead * silent cd %:p:h
4414 augroup END
4415
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004416 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004417 let l = g:Xgetlist()
4418 call assert_equal('f1.txt', bufname(l[0].bufnr))
4419 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4420
4421 augroup QF_Test
4422 au!
4423 augroup END
4424
4425 exe 'cd ' . save_cwd
4426endfunc
4427
4428func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004429 call mkdir('Xgrepdir/a', 'pR')
4430 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004431 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4432 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004433 call Xvimgrep_autocmd_cd('c')
4434 call Xvimgrep_autocmd_cd('l')
4435 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004436endfunc
4437
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004438" The following test used to crash Vim
4439func Test_lhelpgrep_autocmd()
4440 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004441 augroup QF_Test
4442 au!
4443 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4444 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004445 lhelpgrep buffer
4446 call assert_equal('help', &filetype)
4447 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4448 lhelpgrep tabpage
4449 call assert_equal('help', &filetype)
4450 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004451 augroup QF_Test
4452 au!
4453 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004454
4455 new | only
4456 augroup QF_Test
4457 au!
4458 au BufEnter * call setqflist([], 'f')
4459 augroup END
4460 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004461 " run the test with a help window already open
4462 help
4463 wincmd w
4464 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004465 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004466 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004467 augroup END
4468
4469 new | only
4470 augroup QF_Test
4471 au!
4472 au BufEnter * call setqflist([], 'r')
4473 augroup END
4474 call assert_fails('helpgrep quickfix', 'E925:')
4475 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004476 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004477 augroup END
4478
4479 new | only
4480 augroup QF_Test
4481 au!
4482 au BufEnter * call setloclist(0, [], 'r')
4483 augroup END
4484 call assert_fails('lhelpgrep quickfix', 'E926:')
4485 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004486 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004487 augroup END
4488
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004489 " Replace the contents of a help window location list when it is still in
4490 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004491 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004492 lhelpgrep quickfix
4493 wincmd w
4494 augroup QF_Test
4495 au!
4496 autocmd WinEnter * call setloclist(0, [], 'r')
4497 augroup END
4498 call assert_fails('lhelpgrep win_getid', 'E926:')
4499 augroup QF_Test
4500 au!
4501 augroup END
4502
4503 %bw!
4504endfunc
4505
4506" The following test used to crash Vim
4507func Test_lhelpgrep_autocmd_free_loclist()
4508 %bw!
4509 lhelpgrep quickfix
4510 wincmd w
4511 augroup QF_Test
4512 au!
4513 autocmd WinEnter * call setloclist(0, [], 'f')
4514 augroup END
4515 lhelpgrep win_getid
4516 wincmd w
4517 wincmd w
4518 wincmd w
4519 augroup QF_Test
4520 au!
4521 augroup END
4522 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004523endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004524
4525" Test for shortening/simplifying the file name when opening the
4526" quickfix window or when displaying the quickfix list
4527func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004528 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004529 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004530 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004531 let fname = getcwd() . '/test_quickfix.vim'
4532 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4533 call assert_equal(fname, bufname('test_quickfix.vim'))
4534 " Opening the quickfix window should simplify the file path
4535 cwindow
4536 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4537 cclose
4538 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004539 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004540 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4541 call assert_equal(fname, bufname('test_quickfix.vim'))
4542 " Displaying the quickfix list should simplify the file path
4543 silent! clist
4544 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004545 " Add a few entries for the same file with different paths and check whether
4546 " the buffer name is shortened
4547 %bwipe
4548 call setqflist([], 'f')
4549 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4550 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4551 \ {'filename' : fname, 'lnum' : 30}], ' ')
4552 copen
4553 call assert_equal(['test_quickfix.vim|10| ',
4554 \ 'test_quickfix.vim|20| ',
4555 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4556 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004557endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004558
4559" Quickfix title tests
4560" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4561" Otherwise due to indentation, the title is set with spaces at the beginning
4562" of the command.
4563func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004564 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004565
4566 " :cexpr
4567 exe "cexpr readfile('Xerr')"
4568 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4569
4570 " :cgetexpr
4571 exe "cgetexpr readfile('Xerr')"
4572 call assert_equal(":cgetexpr readfile('Xerr')",
4573 \ getqflist({'title' : 1}).title)
4574
4575 " :caddexpr
4576 call setqflist([], 'f')
4577 exe "caddexpr readfile('Xerr')"
4578 call assert_equal(":caddexpr readfile('Xerr')",
4579 \ getqflist({'title' : 1}).title)
4580
4581 " :cbuffer
4582 new Xerr
4583 exe "cbuffer"
4584 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4585
4586 " :cgetbuffer
4587 edit Xerr
4588 exe "cgetbuffer"
4589 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4590
4591 " :caddbuffer
4592 call setqflist([], 'f')
4593 edit Xerr
4594 exe "caddbuffer"
4595 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4596
4597 " :cfile
4598 exe "cfile Xerr"
4599 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4600
4601 " :cgetfile
4602 exe "cgetfile Xerr"
4603 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4604
4605 " :caddfile
4606 call setqflist([], 'f')
4607 exe "caddfile Xerr"
4608 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4609
4610 " :grep
4611 set grepprg=internal
4612 exe "grep F1 Xerr"
4613 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4614
4615 " :grepadd
4616 call setqflist([], 'f')
4617 exe "grepadd F1 Xerr"
4618 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4619 set grepprg&vim
4620
4621 " :vimgrep
4622 exe "vimgrep F1 Xerr"
4623 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4624
4625 " :vimgrepadd
4626 call setqflist([], 'f')
4627 exe "vimgrepadd F1 Xerr"
4628 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4629
4630 call setqflist(['F1:10:L10'], ' ')
4631 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4632
4633 call setqflist([], 'f')
4634 call setqflist(['F1:10:L10'], 'a')
4635 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4636
4637 call setqflist([], 'f')
4638 call setqflist(['F1:10:L10'], 'r')
4639 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4640
4641 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004642
4643 call setqflist([], ' ', {'title' : 'Errors'})
4644 copen
4645 call assert_equal('Errors', w:quickfix_title)
4646 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4647 call assert_equal('Errors', w:quickfix_title)
4648 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004649
4650 " Switching to another quickfix list in one tab page should update the
4651 " quickfix window title and statusline in all the other tab pages also
4652 call setqflist([], 'f')
4653 %bw!
4654 cgetexpr ['file_one:1:1: error in the first quickfix list']
4655 call setqflist([], 'a', {'title': 'first quickfix list'})
4656 cgetexpr ['file_two:2:1: error in the second quickfix list']
4657 call setqflist([], 'a', {'title': 'second quickfix list'})
4658 copen
4659 wincmd t
4660 tabnew two
4661 copen
4662 wincmd t
4663 colder
4664 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4665 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4666 call assert_equal(1, tabpagewinnr(1))
4667 call assert_equal(1, tabpagewinnr(2))
4668 tabnew
4669 call setqflist([], 'a', {'title': 'new quickfix title'})
4670 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4671 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4672 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004673endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004674
4675func Test_lbuffer_with_bwipe()
4676 new
4677 new
4678 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004679 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004680 augroup END
4681 lbuffer
4682 augroup nasty
4683 au!
4684 augroup END
4685endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004686
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004687" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4688" running
4689func Xexpr_acmd_freelist(cchar)
4690 call s:setup_commands(a:cchar)
4691
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004692 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004693 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004694 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004695 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004696 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004697 augroup nasty
4698 au!
4699 augroup END
4700endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004701
4702func Test_cexpr_acmd_freelist()
4703 call Xexpr_acmd_freelist('c')
4704 call Xexpr_acmd_freelist('l')
4705endfunc
4706
4707" Test for commands that create a new quickfix/location list and jump to the
4708" first error automatically.
4709func Xjumpto_first_error_test(cchar)
4710 call s:setup_commands(a:cchar)
4711
4712 call s:create_test_file('Xtestfile1')
4713 call s:create_test_file('Xtestfile2')
4714 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4715
4716 " Test for cexpr/lexpr
4717 enew
4718 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004719 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004720 call assert_equal(2, line('.'))
4721
4722 " Test for cfile/lfile
4723 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004724 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004725 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004726 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004727 call assert_equal(2, line('.'))
4728
4729 " Test for cbuffer/lbuffer
4730 edit Xerr
4731 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004732 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004733 call assert_equal(2, line('.'))
4734
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004735 call delete('Xtestfile1')
4736 call delete('Xtestfile2')
4737endfunc
4738
4739func Test_jumpto_first_error()
4740 call Xjumpto_first_error_test('c')
4741 call Xjumpto_first_error_test('l')
4742endfunc
4743
4744" Test for a quickfix autocmd changing the quickfix/location list before
4745" jumping to the first error in the new list.
4746func Xautocmd_changelist(cchar)
4747 call s:setup_commands(a:cchar)
4748
4749 " Test for cfile/lfile
4750 call s:create_test_file('Xtestfile1')
4751 call s:create_test_file('Xtestfile2')
4752 Xexpr 'Xtestfile1:2:Line2'
4753 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004754 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004755 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004756 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004757 call assert_equal(4, line('.'))
4758 autocmd! QuickFixCmdPost
4759
4760 " Test for cbuffer/lbuffer
4761 call g:Xsetlist([], 'f')
4762 Xexpr 'Xtestfile1:2:Line2'
4763 autocmd QuickFixCmdPost * Xolder
4764 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4765 edit Xerr
4766 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004767 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004768 call assert_equal(4, line('.'))
4769 autocmd! QuickFixCmdPost
4770
4771 " Test for cexpr/lexpr
4772 call g:Xsetlist([], 'f')
4773 Xexpr 'Xtestfile1:2:Line2'
4774 autocmd QuickFixCmdPost * Xolder
4775 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004776 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004777 call assert_equal(4, line('.'))
4778 autocmd! QuickFixCmdPost
4779
Bram Moolenaar851332e2018-07-03 19:16:00 +02004780 " The grepprg may not be set on non-Unix systems
4781 if has('unix')
4782 " Test for grep/lgrep
4783 call g:Xsetlist([], 'f')
4784 Xexpr 'Xtestfile1:2:Line2'
4785 autocmd QuickFixCmdPost * Xolder
4786 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004787 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004788 call assert_equal(5, line('.'))
4789 autocmd! QuickFixCmdPost
4790 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004791
4792 " Test for vimgrep/lvimgrep
4793 call g:Xsetlist([], 'f')
4794 Xexpr 'Xtestfile1:2:Line2'
4795 autocmd QuickFixCmdPost * Xolder
4796 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004797 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004798 call assert_equal(5, line('.'))
4799 autocmd! QuickFixCmdPost
4800
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004801 " Test for autocommands clearing the quickfix list before jumping to the
4802 " first error. This should not result in an error
4803 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4804 let v:errmsg = ''
4805 " Test for cfile/lfile
4806 Xfile Xerr
4807 call assert_true(v:errmsg !~# 'E42:')
4808 " Test for cbuffer/lbuffer
4809 edit Xerr
4810 Xbuffer
4811 call assert_true(v:errmsg !~# 'E42:')
4812 " Test for cexpr/lexpr
4813 Xexpr 'Xtestfile2:4:Line4'
4814 call assert_true(v:errmsg !~# 'E42:')
4815 " Test for grep/lgrep
4816 " The grepprg may not be set on non-Unix systems
4817 if has('unix')
4818 silent Xgrep Line5 Xtestfile2
4819 call assert_true(v:errmsg !~# 'E42:')
4820 endif
4821 " Test for vimgrep/lvimgrep
4822 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4823 autocmd! QuickFixCmdPost
4824
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004825 call delete('Xtestfile1')
4826 call delete('Xtestfile2')
4827endfunc
4828
4829func Test_autocmd_changelist()
4830 call Xautocmd_changelist('c')
4831 call Xautocmd_changelist('l')
4832endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004833
4834" Tests for the ':filter /pat/ clist' command
4835func Test_filter_clist()
4836 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4837 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4838 \ split(execute('filter /Line 15/ clist'), "\n"))
4839 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4840 \ split(execute('filter /Xfile1/ clist'), "\n"))
4841 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4842
4843 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4844 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4845 call assert_equal([' 2 pqr:pat2: '],
4846 \ split(execute('filter /pqr/ clist'), "\n"))
4847 call assert_equal([' 1 abc:pat1: '],
4848 \ split(execute('filter /pat1/ clist'), "\n"))
4849endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004850
4851" Tests for the "CTRL-W <CR>" command.
4852func Xview_result_split_tests(cchar)
4853 call s:setup_commands(a:cchar)
4854
4855 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4856 call g:Xsetlist([])
4857 Xopen
4858 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004859 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004860 call assert_equal(l:win_count, winnr('$'))
4861 Xclose
4862endfunc
4863
4864func Test_view_result_split()
4865 call Xview_result_split_tests('c')
4866 call Xview_result_split_tests('l')
4867endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004868
4869" Test that :cc sets curswant
4870func Test_curswant()
4871 helpgrep quickfix
4872 normal! llll
4873 1cc
4874 call assert_equal(getcurpos()[4], virtcol('.'))
4875 cclose | helpclose
4876endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004877
4878" Test for opening a file from the quickfix window using CTRL-W <Enter>
4879" doesn't leave an empty buffer around.
4880func Test_splitview()
4881 call s:create_test_file('Xtestfile1')
4882 call s:create_test_file('Xtestfile2')
4883 new | only
4884 let last_bufnr = bufnr('Test_sv_1', 1)
4885 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4886 cgetexpr l
4887 copen
4888 let numbufs = len(getbufinfo())
4889 exe "normal \<C-W>\<CR>"
4890 copen
4891 exe "normal j\<C-W>\<CR>"
4892 " Make sure new empty buffers are not created
4893 call assert_equal(numbufs, len(getbufinfo()))
4894 " Creating a new buffer should use the next available buffer number
4895 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4896 bwipe Test_sv_1
4897 bwipe Test_sv_2
4898 new | only
4899
4900 " When split opening files from location list window, make sure that two
4901 " windows doesn't refer to the same location list
4902 lgetexpr l
4903 let locid = getloclist(0, {'id' : 0}).id
4904 lopen
4905 exe "normal \<C-W>\<CR>"
4906 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4907 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4908 new | only
4909
4910 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004911 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004912 lhelpgrep window
4913 let locid = getloclist(0, {'id' : 0}).id
4914 lwindow
4915 exe "normal j\<C-W>\<CR>"
4916 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4917 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4918 new | only
4919
Bram Moolenaar406cd902020-02-18 21:54:41 +01004920 " Using :split or :vsplit from a quickfix window should behave like a :new
4921 " or a :vnew command
4922 copen
4923 split
4924 call assert_equal(3, winnr('$'))
4925 let l = getwininfo()
4926 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4927 close
4928 copen
4929 vsplit
4930 let l = getwininfo()
4931 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4932 new | only
4933
Bram Moolenaarb2443732018-11-11 22:50:27 +01004934 call delete('Xtestfile1')
4935 call delete('Xtestfile2')
4936endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004937
4938" Test for parsing entries using visual screen column
4939func Test_viscol()
4940 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004941 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004942 edit Xfile1
4943
4944 " Use byte offset for column number
4945 set efm&
4946 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4947 call assert_equal([5, 8], [col('.'), virtcol('.')])
4948 cnext
4949 call assert_equal([9, 12], [col('.'), virtcol('.')])
4950 cnext
4951 call assert_equal([14, 20], [col('.'), virtcol('.')])
4952
4953 " Use screen column offset for column number
4954 set efm=%f:%l:%v:%m
4955 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4956 call assert_equal([5, 8], [col('.'), virtcol('.')])
4957 cnext
4958 call assert_equal([9, 12], [col('.'), virtcol('.')])
4959 cnext
4960 call assert_equal([14, 20], [col('.'), virtcol('.')])
4961 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4962 call assert_equal([5, 8], [col('.'), virtcol('.')])
4963 cnext
4964 call assert_equal([10, 16], [col('.'), virtcol('.')])
4965 cnext
4966 call assert_equal([14, 20], [col('.'), virtcol('.')])
4967
4968 enew
4969 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4970
4971 " Use byte offset for column number
4972 set efm&
4973 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4974 call assert_equal([8, 10], [col('.'), virtcol('.')])
4975 cnext
4976 call assert_equal([11, 17], [col('.'), virtcol('.')])
4977 cnext
4978 call assert_equal([16, 25], [col('.'), virtcol('.')])
4979
4980 " Use screen column offset for column number
4981 set efm=%f:%l:%v:%m
4982 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4983 call assert_equal([8, 10], [col('.'), virtcol('.')])
4984 cnext
4985 call assert_equal([11, 17], [col('.'), virtcol('.')])
4986 cnext
4987 call assert_equal([16, 25], [col('.'), virtcol('.')])
4988
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004989 " Use screen column number with a multi-line error message
4990 enew
4991 call writefile(["à test"], 'Xfile1')
4992 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4993 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4994 call assert_equal('Xfile1', @%)
4995 call assert_equal([0, 1, 4, 0], getpos('.'))
4996
4997 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4998 " does not break this
4999 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
5000 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
5001 call assert_equal('Xfile1', @%)
5002 call assert_equal([0, 1, 3, 0], getpos('.'))
5003
Bram Moolenaarc45eb772019-01-31 14:27:04 +01005004 enew | only
5005 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01005006endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005007
5008" Test for the quickfix window buffer
5009func Xqfbuf_test(cchar)
5010 call s:setup_commands(a:cchar)
5011
5012 " Quickfix buffer should be reused across closing and opening a quickfix
5013 " window
5014 Xexpr "F1:10:Line10"
5015 Xopen
5016 let qfbnum = bufnr('')
5017 Xclose
5018 " Even after the quickfix window is closed, the buffer should be loaded
5019 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005020 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005021 Xopen
5022 " Buffer should be reused when opening the window again
5023 call assert_equal(qfbnum, bufnr(''))
5024 Xclose
5025
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00005026 " When quickfix buffer is wiped out, getqflist() should return 0
5027 %bw!
5028 Xexpr ""
5029 Xopen
5030 bw!
5031 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
5032
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005033 if a:cchar == 'l'
5034 %bwipe
5035 " For a location list, when both the file window and the location list
5036 " window for the list are closed, then the buffer should be freed.
5037 new | only
5038 lexpr "F1:10:Line10"
5039 let wid = win_getid()
5040 lopen
5041 let qfbnum = bufnr('')
5042 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
5043 close
5044 " When the location list window is closed, the buffer name should not
5045 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005046 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005047 call assert_true(bufloaded(qfbnum))
5048
Bram Moolenaard82a81c2019-03-02 07:57:18 +01005049 " After deleting a location list buffer using ":bdelete", opening the
5050 " location list window should mark the buffer as a location list buffer.
5051 exe "bdelete " . qfbnum
5052 lopen
5053 call assert_equal("quickfix", &buftype)
5054 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5055 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5056 call assert_false(&swapfile)
5057 lclose
5058
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005059 " When the location list is cleared for the window, the buffer should be
5060 " removed
5061 call setloclist(0, [], 'f')
5062 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005063 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005064
5065 " When the location list is freed with the location list window open, the
5066 " location list buffer should not be lost. It should be reused when the
5067 " location list is again populated.
5068 lexpr "F1:10:Line10"
5069 lopen
5070 let wid = win_getid()
5071 let qfbnum = bufnr('')
5072 wincmd p
5073 call setloclist(0, [], 'f')
5074 lexpr "F1:10:Line10"
5075 lopen
5076 call assert_equal(wid, win_getid())
5077 call assert_equal(qfbnum, bufnr(''))
5078 lclose
5079
5080 " When the window with the location list is closed, the buffer should be
5081 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005082 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005083 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005084 endif
5085endfunc
5086
5087func Test_qfbuf()
5088 call Xqfbuf_test('c')
5089 call Xqfbuf_test('l')
5090endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005091
5092" If there is an autocmd to use only one window, then opening the location
5093" list window used to crash Vim.
5094func Test_winonly_autocmd()
5095 call s:create_test_file('Xtest1')
5096 " Autocmd to show only one Vim window at a time
5097 autocmd WinEnter * only
5098 new
5099 " Load the location list
5100 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5101 let loclistid = getloclist(0, {'id' : 0}).id
5102 " Open the location list window. Only this window will be shown and the file
5103 " window is closed.
5104 lopen
5105 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5106 " Jump to an entry in the location list and make sure that the cursor is
5107 " positioned correctly.
5108 ll 3
5109 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005110 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005111 call assert_equal(15, line('.'))
5112 " Cleanup
5113 autocmd! WinEnter
5114 new | only
5115 call delete('Xtest1')
5116endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005117
5118" Test to make sure that an empty quickfix buffer is not reused for loading
5119" a normal buffer.
5120func Test_empty_qfbuf()
5121 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005122 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005123 call setqflist([], 'f')
5124 copen | only
5125 let qfbuf = bufnr('')
5126 edit Xfile1
5127 call assert_notequal(qfbuf, bufnr(''))
5128 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005129endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005130
5131" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005132" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005133func Xtest_below(cchar)
5134 call s:setup_commands(a:cchar)
5135
5136 " No quickfix/location list
5137 call assert_fails('Xbelow', 'E42:')
5138 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005139 call assert_fails('Xbefore', 'E42:')
5140 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005141
5142 " Empty quickfix/location list
5143 call g:Xsetlist([])
5144 call assert_fails('Xbelow', 'E42:')
5145 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005146 call assert_fails('Xbefore', 'E42:')
5147 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005148
5149 call s:create_test_file('X1')
5150 call s:create_test_file('X2')
5151 call s:create_test_file('X3')
5152 call s:create_test_file('X4')
5153
5154 " Invalid entries
5155 edit X1
5156 call g:Xsetlist(["E1", "E2"])
5157 call assert_fails('Xbelow', 'E42:')
5158 call assert_fails('Xabove', 'E42:')
5159 call assert_fails('3Xbelow', 'E42:')
5160 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005161 call assert_fails('Xbefore', 'E42:')
5162 call assert_fails('Xafter', 'E42:')
5163 call assert_fails('3Xbefore', 'E42:')
5164 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005165
5166 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005167 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 +02005168 edit +7 X2
5169 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005170 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005171 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005172 normal 7G
5173 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005174 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005175 call assert_fails('Xbefore', 'E553:')
5176
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005177 normal 2j
5178 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005179 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005180 normal 7G
5181 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005182 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005183
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005184 " Last error in this file
5185 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005186 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005187 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005188 normal gg
5189 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005190 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005191 call assert_fails('Xafter', 'E553:')
5192
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005193 " First error in this file
5194 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005195 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005196 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005197 normal G
5198 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005199 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005200 call assert_fails('Xbefore', 'E553:')
5201
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005202 normal gg
5203 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005204 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005205 normal gg
5206 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005207 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005208
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005209 normal G
5210 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005211 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005212 normal G
5213 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005214 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005215
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005216 edit X4
5217 call assert_fails('Xabove', 'E42:')
5218 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005219 call assert_fails('Xbefore', 'E42:')
5220 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005221 if a:cchar == 'l'
5222 " If a buffer has location list entries from some other window but not
5223 " from the current window, then the commands should fail.
5224 edit X1 | split | call setloclist(0, [], 'f')
5225 call assert_fails('Xabove', 'E776:')
5226 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005227 call assert_fails('Xbefore', 'E776:')
5228 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005229 close
5230 endif
5231
5232 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005233 let lines =<< trim END
5234 X1:5:L5
5235 X2:5:1:L5_1
5236 X2:5:2:L5_2
5237 X2:5:3:L5_3
5238 X2:10:1:L10_1
5239 X2:10:2:L10_2
5240 X2:10:3:L10_3
5241 X2:15:1:L15_1
5242 X2:15:2:L15_2
5243 X2:15:3:L15_3
5244 X3:3:L3
5245 END
5246 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005247 edit +1 X2
5248 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005249 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005250 normal 1G
5251 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005252 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005253
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005254 normal gg
5255 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005256 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005257 normal gg
5258 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005259 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005260
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005261 normal G
5262 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005263 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005264 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005265 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005266 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005267
5268 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005269 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005270 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005271 normal G
5272 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005273 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005274
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005275 normal 10G
5276 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005277 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005278 normal 10G$
5279 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005280 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005281
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005282 normal 10G
5283 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005284 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005285 normal 9G
5286 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005287 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005288
5289 " Invalid range
5290 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005291 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005292 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005293 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005294 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005295 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005296 endif
5297
5298 call delete('X1')
5299 call delete('X2')
5300 call delete('X3')
5301 call delete('X4')
5302endfunc
5303
5304func Test_cbelow()
5305 call Xtest_below('c')
5306 call Xtest_below('l')
5307endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005308
5309func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005310 let commands =<< trim END
5311 cNext
5312 cNfile
5313 cabove
5314 cbelow
5315 cfirst
5316 clast
5317 cnewer
5318 cnext
5319 cnfile
5320 colder
5321 cprevious
5322 crewind
5323 lNext
5324 lNfile
5325 labove
5326 lbelow
5327 lfirst
5328 llast
5329 lnewer
5330 lnext
5331 lnfile
5332 lolder
5333 lprevious
5334 lrewind
5335 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005336 for cmd in commands
5337 call assert_fails('-1' .. cmd, 'E16:')
5338 call assert_fails('.' .. cmd, 'E16:')
5339 call assert_fails('%' .. cmd, 'E16:')
5340 call assert_fails('$' .. cmd, 'E16:')
5341 endfor
5342endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005343
5344" Test for aborting quickfix commands using QuickFixCmdPre
5345func Xtest_qfcmd_abort(cchar)
5346 call s:setup_commands(a:cchar)
5347
5348 call g:Xsetlist([], 'f')
5349
5350 " cexpr/lexpr
5351 let e = ''
5352 try
5353 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5354 catch /.*/
5355 let e = v:exception
5356 endtry
5357 call assert_equal('AbortCmd', e)
5358 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5359
5360 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005361 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005362 let e = ''
5363 try
5364 Xfile Xfile1
5365 catch /.*/
5366 let e = v:exception
5367 endtry
5368 call assert_equal('AbortCmd', e)
5369 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005370
5371 " cgetbuffer/lgetbuffer
5372 enew!
5373 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5374 let e = ''
5375 try
5376 Xgetbuffer
5377 catch /.*/
5378 let e = v:exception
5379 endtry
5380 call assert_equal('AbortCmd', e)
5381 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5382 enew!
5383
5384 " vimgrep/lvimgrep
5385 let e = ''
5386 try
5387 Xvimgrep /func/ test_quickfix.vim
5388 catch /.*/
5389 let e = v:exception
5390 endtry
5391 call assert_equal('AbortCmd', e)
5392 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5393
5394 " helpgrep/lhelpgrep
5395 let e = ''
5396 try
5397 Xhelpgrep quickfix
5398 catch /.*/
5399 let e = v:exception
5400 endtry
5401 call assert_equal('AbortCmd', e)
5402 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5403
5404 " grep/lgrep
5405 if has('unix')
5406 let e = ''
5407 try
5408 silent Xgrep func test_quickfix.vim
5409 catch /.*/
5410 let e = v:exception
5411 endtry
5412 call assert_equal('AbortCmd', e)
5413 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5414 endif
5415endfunc
5416
5417func Test_qfcmd_abort()
5418 augroup QF_Test
5419 au!
5420 autocmd QuickFixCmdPre * throw "AbortCmd"
5421 augroup END
5422
5423 call Xtest_qfcmd_abort('c')
5424 call Xtest_qfcmd_abort('l')
5425
5426 augroup QF_Test
5427 au!
5428 augroup END
5429endfunc
5430
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005431" Test for using a file in one of the parent directories.
5432func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005433 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005434 let save_cwd = getcwd()
5435 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5436 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5437 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5438 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5439
5440 let lines = "Entering dir Xtestdir\n" .
5441 \ "Entering dir a\n" .
5442 \ "Entering dir b\n" .
5443 \ "Xfile2:2:X2_L2\n" .
5444 \ "Leaving dir a\n" .
5445 \ "Xfile1:2:X1_L2\n" .
5446 \ "Xfile3:1:X3_L1\n" .
5447 \ "Entering dir c\n" .
5448 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005449 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005450 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005451 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005452 call assert_equal(11, getqflist({'size' : 0}).size)
5453 call assert_equal(4, getqflist({'idx' : 0}).idx)
5454 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005455 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005456 cnext
5457 call assert_equal(6, getqflist({'idx' : 0}).idx)
5458 call assert_equal('X1_L2', getline('.'))
5459 cnext
5460 call assert_equal(7, getqflist({'idx' : 0}).idx)
5461 call assert_equal(1, line('$'))
5462 call assert_equal('', getline(1))
5463 cnext
5464 call assert_equal(9, getqflist({'idx' : 0}).idx)
5465 call assert_equal(1, line('$'))
5466 call assert_equal('', getline(1))
5467
5468 set efm&
5469 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005470endfunc
5471
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005472" Test for :cquit
5473func Test_cquit()
5474 " Exit Vim with a non-zero value
5475 if RunVim([], ["cquit 7"], '')
5476 call assert_equal(7, v:shell_error)
5477 endif
5478
5479 if RunVim([], ["50cquit"], '')
5480 call assert_equal(50, v:shell_error)
5481 endif
5482
5483 " Exit Vim with default value
5484 if RunVim([], ["cquit"], '')
5485 call assert_equal(1, v:shell_error)
5486 endif
5487
5488 " Exit Vim with zero value
5489 if RunVim([], ["cquit 0"], '')
5490 call assert_equal(0, v:shell_error)
5491 endif
5492
5493 " Exit Vim with negative value
5494 call assert_fails('-3cquit', 'E16:')
5495endfunc
5496
Bram Moolenaar858ba062020-05-31 23:11:59 +02005497" Test for getting a specific item from a quickfix list
5498func Xtest_getqflist_by_idx(cchar)
5499 call s:setup_commands(a:cchar)
5500 " Empty list
5501 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5502 Xexpr ['F1:10:L10', 'F1:20:L20']
5503 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5504 call assert_equal(bufnr('F1'), l[0].bufnr)
5505 call assert_equal(20, l[0].lnum)
5506 call assert_equal('L20', l[0].text)
5507 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5508 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005509 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005510 %bwipe!
5511endfunc
5512
5513func Test_getqflist_by_idx()
5514 call Xtest_getqflist_by_idx('c')
5515 call Xtest_getqflist_by_idx('l')
5516endfunc
5517
5518" Test for the 'quickfixtextfunc' setting
5519func Tqfexpr(info)
5520 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005521 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005522 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005523 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005524 endif
5525
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005526 let l = []
5527 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5528 let e = qfl[idx]
5529 let s = ''
5530 if e.bufnr != 0
5531 let bname = bufname(e.bufnr)
5532 let s ..= fnamemodify(bname, ':.')
5533 endif
5534 let s ..= '-'
5535 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5536 let s ..= e.text
5537 call add(l, s)
5538 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005539
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005540 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005541endfunc
5542
5543func Xtest_qftextfunc(cchar)
5544 call s:setup_commands(a:cchar)
5545
5546 set efm=%f:%l:%c:%m
5547 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005548 call assert_equal('Tqfexpr', &quickfixtextfunc)
5549 call assert_equal('',
5550 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005551 call g:Xsetlist([
5552 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5553 \ 'end_col': 7, 'text': 'green'},
5554 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5555 \ 'end_col': 8, 'text': 'blue'},
5556 \ ])
5557
Bram Moolenaar858ba062020-05-31 23:11:59 +02005558 Xwindow
5559 call assert_equal('F1-L10C2-green', getline(1))
5560 call assert_equal('F1-L20C4-blue', getline(2))
5561 Xclose
5562 set quickfixtextfunc&vim
5563 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005564 call assert_equal('F1|10 col 2-7| green', getline(1))
5565 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005566 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005567
5568 set efm=%f:%l:%c:%m
5569 set quickfixtextfunc=Tqfexpr
5570 " Update the list with only the cwindow
5571 Xwindow
5572 only
5573 call g:Xsetlist([
5574 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5575 \ 'end_col': 7, 'text': 'red'}
5576 \ ])
5577 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5578 new
5579 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005580 set efm&
5581 set quickfixtextfunc&
5582
5583 " Test for per list 'quickfixtextfunc' setting
5584 func PerQfText(info)
5585 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005586 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005587 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005588 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005589 endif
5590 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005591 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005592 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005593 let l = []
5594 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5595 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5596 endfor
5597 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005598 endfunc
5599 set quickfixtextfunc=Tqfexpr
5600 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5601 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5602 Xwindow
5603 call assert_equal('Line 10, Col 2', getline(1))
5604 call assert_equal('Line 20, Col 4', getline(2))
5605 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005606 call assert_equal(function('PerQfText'),
5607 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005608 " Add entries to the list when the quickfix buffer is hidden
5609 Xaddexpr ['F1:30:6:red']
5610 Xwindow
5611 call assert_equal('Line 30, Col 6', getline(3))
5612 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005613 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005614 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005615 set quickfixtextfunc&
5616 delfunc PerQfText
5617
5618 " Non-existing function
5619 set quickfixtextfunc=Tabc
5620 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5621 call assert_fails("Xwindow", 'E117:')
5622 Xclose
5623 set quickfixtextfunc&
5624
5625 " set option to a non-function
5626 set quickfixtextfunc=[10,\ 20]
5627 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5628 call assert_fails("Xwindow", 'E117:')
5629 Xclose
5630 set quickfixtextfunc&
5631
5632 " set option to a function with different set of arguments
5633 func Xqftext(a, b, c)
5634 return a:a .. a:b .. a:c
5635 endfunc
5636 set quickfixtextfunc=Xqftext
5637 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5638 call assert_fails("Xwindow", 'E119:')
5639 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005640
5641 " set option to a function that returns a list with non-strings
5642 func Xqftext2(d)
5643 return ['one', [], 'two']
5644 endfunc
5645 set quickfixtextfunc=Xqftext2
5646 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5647 \ 'E730:')
5648 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005649 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5650 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005651 Xclose
5652
Bram Moolenaar858ba062020-05-31 23:11:59 +02005653 set quickfixtextfunc&
5654 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005655 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005656
5657 " set the global option to a lambda function
5658 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5659 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5660 Xwindow
5661 call assert_equal(['green', 'blue'], getline(1, '$'))
5662 Xclose
5663 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)
5664 set quickfixtextfunc&
5665
5666 " use a lambda function that returns an empty list
5667 set quickfixtextfunc={d\ ->\ []}
5668 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5669 Xwindow
5670 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5671 \ getline(1, '$'))
5672 Xclose
5673 set quickfixtextfunc&
5674
5675 " use a lambda function that returns a list with empty strings
5676 set quickfixtextfunc={d\ ->\ ['',\ '']}
5677 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5678 Xwindow
5679 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5680 \ getline(1, '$'))
5681 Xclose
5682 set quickfixtextfunc&
5683
5684 " set the per-quickfix list text function to a lambda function
5685 call g:Xsetlist([], ' ',
5686 \ {'quickfixtextfunc' :
5687 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5688 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5689 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5690 Xwindow
5691 call assert_equal('Line 10, Col 2', getline(1))
5692 call assert_equal('Line 20, Col 4', getline(2))
5693 Xclose
5694 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5695 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005696endfunc
5697
5698func Test_qftextfunc()
5699 call Xtest_qftextfunc('c')
5700 call Xtest_qftextfunc('l')
5701endfunc
5702
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005703func Test_qftextfunc_callback()
5704 let lines =<< trim END
5705 set efm=%f:%l:%c:%m
5706
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005707 #" Test for using a function name
5708 LET &qftf = 'g:Tqfexpr'
5709 cexpr "F0:0:0:L0"
5710 copen
5711 call assert_equal('F0-L0C0-L0', getline(1))
5712 cclose
5713
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005714 #" Test for using a function()
5715 set qftf=function('g:Tqfexpr')
5716 cexpr "F1:1:1:L1"
5717 copen
5718 call assert_equal('F1-L1C1-L1', getline(1))
5719 cclose
5720
5721 #" Using a funcref variable to set 'quickfixtextfunc'
5722 VAR Fn = function('g:Tqfexpr')
5723 LET &qftf = Fn
5724 cexpr "F2:2:2:L2"
5725 copen
5726 call assert_equal('F2-L2C2-L2', getline(1))
5727 cclose
5728
5729 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5730 LET Fn = function('g:Tqfexpr')
5731 LET &qftf = string(Fn)
5732 cexpr "F3:3:3:L3"
5733 copen
5734 call assert_equal('F3-L3C3-L3', getline(1))
5735 cclose
5736
5737 #" Test for using a funcref()
5738 set qftf=funcref('g:Tqfexpr')
5739 cexpr "F4:4:4:L4"
5740 copen
5741 call assert_equal('F4-L4C4-L4', getline(1))
5742 cclose
5743
5744 #" Using a funcref variable to set 'quickfixtextfunc'
5745 LET Fn = funcref('g:Tqfexpr')
5746 LET &qftf = Fn
5747 cexpr "F5:5:5:L5"
5748 copen
5749 call assert_equal('F5-L5C5-L5', getline(1))
5750 cclose
5751
5752 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5753 LET Fn = funcref('g:Tqfexpr')
5754 LET &qftf = string(Fn)
5755 cexpr "F5:5:5:L5"
5756 copen
5757 call assert_equal('F5-L5C5-L5', getline(1))
5758 cclose
5759
5760 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005761 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005762 LET optval = substitute(optval, ' ', '\\ ', 'g')
5763 exe "set qftf=" .. optval
5764 cexpr "F6:6:6:L6"
5765 copen
5766 call assert_equal('F6-L6C6-L6', getline(1))
5767 cclose
5768
5769 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005770 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005771 cexpr "F7:7:7:L7"
5772 copen
5773 call assert_equal('F7-L7C7-L7', getline(1))
5774 cclose
5775
5776 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005777 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005778 cexpr "F8:8:8:L8"
5779 copen
5780 call assert_equal('F8-L8C8-L8', getline(1))
5781 cclose
5782
5783 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005784 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005785 LET &qftf = Lambda
5786 cexpr "F9:9:9:L9"
5787 copen
5788 call assert_equal('F9-L9C9-L9', getline(1))
5789 cclose
5790
5791 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005792 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005793 LET &qftf = string(Lambda)
5794 cexpr "F9:9:9:L9"
5795 copen
5796 call assert_equal('F9-L9C9-L9', getline(1))
5797 cclose
5798 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005799 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005800
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005801 " Test for using a script-local function name
5802 func s:TqfFunc2(info)
5803 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5804 return ''
5805 endfunc
5806 let g:TqfFunc2Args = []
5807 set quickfixtextfunc=s:TqfFunc2
5808 cexpr "F10:10:10:L10"
5809 cclose
5810 call assert_equal([1, 1], g:TqfFunc2Args)
5811
5812 let &quickfixtextfunc = 's:TqfFunc2'
5813 cexpr "F11:11:11:L11"
5814 cclose
5815 call assert_equal([1, 1], g:TqfFunc2Args)
5816 delfunc s:TqfFunc2
5817
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005818 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5819 func SetQftfFunc()
5820 let params = {'qftf': function('g:DictQftfFunc')}
5821 let &quickfixtextfunc = params.qftf
5822 endfunc
5823 func g:DictQftfFunc(_) dict
5824 endfunc
5825 call SetQftfFunc()
5826 new
5827 call SetQftfFunc()
5828 bw
5829 call test_garbagecollect_now()
5830 new
5831 set qftf=
5832 wincmd w
5833 set qftf=
5834 :%bw!
5835
5836 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5837 " to cause a crash.
5838 let &qftf = ''
5839 func SetLocalQftfFunc()
5840 let params = {'qftf': function('g:DictQftfFunc')}
5841 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5842 endfunc
5843 call SetLocalQftfFunc()
5844 call test_garbagecollect_now()
5845 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5846 delfunc g:DictQftfFunc
5847 delfunc SetQftfFunc
5848 delfunc SetLocalQftfFunc
5849 set efm&
5850endfunc
5851
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005852" Test for updating a location list for some other window and check that
5853" 'qftextfunc' uses the correct location list.
5854func Test_qftextfunc_other_loclist()
5855 %bw!
5856 call setloclist(0, [], 'f')
5857
5858 " create a window and a location list for it and open the location list
5859 " window
5860 lexpr ['F1:10:12:one', 'F1:20:14:two']
5861 let w1_id = win_getid()
5862 call setloclist(0, [], ' ',
5863 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5864 \ 'quickfixtextfunc':
5865 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5866 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5867 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5868 lwindow
5869 let w2_id = win_getid()
5870
5871 " create another window and a location list for it and open the location
5872 " list window
5873 topleft new
5874 let w3_id = win_getid()
5875 call setloclist(0, [], ' ',
5876 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5877 \ 'quickfixtextfunc':
5878 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5879 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5880 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5881 lwindow
5882 let w4_id = win_getid()
5883
5884 topleft new
5885 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5886 let w5_id = win_getid()
5887
5888 " change the location list for some other window
5889 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5890 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5891 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5892 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5893 \ getbufline(winbufnr(w2_id), 1, '$'))
5894 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5895 \ getbufline(winbufnr(w4_id), 1, '$'))
5896 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5897 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5898 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5899 \ getbufline(winbufnr(w2_id), 1, '$'))
5900 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5901 \ getbufline(winbufnr(w4_id), 1, '$'))
5902
5903 call win_gotoid(w5_id)
5904 lwindow
5905 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5906 \ getline(1, '$'))
5907 %bw!
5908endfunc
5909
Bram Moolenaarec98e932020-06-08 19:35:59 +02005910" Running :lhelpgrep command more than once in a help window, doesn't jump to
5911" the help topic
5912func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005913 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005914 call writefile(['window'], 'Xtestdir/doc/a.txt')
5915 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5916 let save_rtp = &rtp
5917 let &rtp = 'Xtestdir'
5918 lhelpgrep window
5919 lhelpgrep buffer
5920 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5921 lhelpgrep window
5922 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5923 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005924 new | only!
5925endfunc
5926
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005927" Test for the crash fixed by 7.3.715
5928func Test_setloclist_crash()
5929 %bw!
5930 let g:BufNum = bufnr()
5931 augroup QF_Test
5932 au!
5933 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5934 augroup END
5935
5936 try
5937 lvimgrep /.*/ *.mak
5938 catch /E926:/
5939 endtry
5940 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5941 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5942
5943 augroup QF_Test
5944 au!
5945 augroup END
5946 unlet g:BufNum
5947 %bw!
5948endfunc
5949
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005950" Test for adding an invalid entry with the quickfix window open and making
5951" sure that the window contents are not changed
5952func Test_add_invalid_entry_with_qf_window()
5953 call setqflist([], 'f')
5954 cexpr "Xfile1:10:aa"
5955 copen
5956 call setqflist(['bb'], 'a')
5957 call assert_equal(1, line('$'))
5958 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005959 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())
5960
5961 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5962 call assert_equal(1 , line('$'))
5963 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5964 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())
5965
5966 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')
5967 call assert_equal(1 , line('$'))
5968 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5969 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())
5970
5971 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')
5972 call assert_equal(1 , line('$'))
5973 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5974 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())
5975
5976 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')
5977 call assert_equal(1 , line('$'))
5978 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5979 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())
5980
5981 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')
5982 call assert_equal(1 , line('$'))
5983 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5984 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())
5985
5986 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')
5987 call assert_equal(1 , line('$'))
5988 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5989 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())
5990
5991 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')
5992 call assert_equal(1 , line('$'))
5993 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5994 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 +01005995 cclose
5996endfunc
5997
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005998" Test for very weird problem: autocommand causes a failure, resulting opening
5999" the quickfix window to fail. This still splits the window, but otherwise
6000" should not mess up buffers.
6001func Test_quickfix_window_fails_to_open()
6002 CheckScreendump
6003
6004 let lines =<< trim END
6005 anything
6006 try
6007 anything
6008 endtry
6009 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006010 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006011
6012 let lines =<< trim END
6013 split XquickfixFails
6014 silent vimgrep anything %
6015 normal o
6016 au BufLeave * ++once source XquickfixFails
6017 " This will trigger the autocommand, which causes an error, what follows
6018 " is aborted but the window was already split.
6019 silent! cwindow
6020 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006021 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006022 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
6023 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
6024
6025 " clean up
6026 call term_sendkeys(buf, ":bwipe!\<CR>")
6027 call term_wait(buf)
6028 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006029endfunc
6030
Bram Moolenaar2d870f82020-12-05 13:41:01 +01006031" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01006032" is changed.
6033func Xqfbuf_update(cchar)
6034 call s:setup_commands(a:cchar)
6035
6036 Xexpr "F1:1:line1"
6037 Xopen
6038 call assert_equal(['F1|1| line1'], getline(1, '$'))
6039 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6040
6041 " Test setqflist() using the 'lines' key in 'what'
6042 " add a new entry
6043 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
6044 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
6045 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6046 " replace all the entries with a single entry
6047 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
6048 call assert_equal(['F3|3| line3'], getline(1, '$'))
6049 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6050 " remove all the entries
6051 call g:Xsetlist([], 'r', {'lines' : []})
6052 call assert_equal([''], getline(1, '$'))
6053 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6054 " add a new list
6055 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6056 call assert_equal(['F4|4| line4'], getline(1, '$'))
6057 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6058
6059 " Test setqflist() using the 'items' key in 'what'
6060 " add a new entry
6061 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6062 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6063 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6064 " replace all the entries with a single entry
6065 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6066 call assert_equal(['F6|6| line6'], getline(1, '$'))
6067 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6068 " remove all the entries
6069 call g:Xsetlist([], 'r', {'items' : []})
6070 call assert_equal([''], getline(1, '$'))
6071 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6072 " add a new list
6073 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6074 call assert_equal(['F7|7| line7'], getline(1, '$'))
6075 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6076
6077 call g:Xsetlist([], ' ', {})
6078 call assert_equal([''], getline(1, '$'))
6079 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6080
6081 Xclose
6082endfunc
6083
6084func Test_qfbuf_update()
6085 call Xqfbuf_update('c')
6086 call Xqfbuf_update('l')
6087endfunc
6088
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006089func Test_vimgrep_noswapfile()
6090 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006091 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006092 vimgrep two Xgreppie
6093 call assert_equal('two', getline('.'))
6094
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006095 set swapfile
6096endfunc
6097
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006098" Test for the :vimgrep 'f' flag (fuzzy match)
6099func Xvimgrep_fuzzy_match(cchar)
6100 call s:setup_commands(a:cchar)
6101
6102 Xvimgrep /three one/f Xfile*
6103 let l = g:Xgetlist()
6104 call assert_equal(2, len(l))
6105 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6106 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6107 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6108 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6109
6110 Xvimgrep /the/f Xfile*
6111 let l = g:Xgetlist()
6112 call assert_equal(3, len(l))
6113 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6114 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6115 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6116 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6117 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6118 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6119
6120 Xvimgrep /aaa/fg Xfile*
6121 let l = g:Xgetlist()
6122 call assert_equal(4, len(l))
6123 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6124 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6125 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6126 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6127 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6128 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6129 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6130 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6131
6132 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6133endfunc
6134
6135func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006136 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6137 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006138 call Xvimgrep_fuzzy_match('c')
6139 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006140endfunc
6141
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006142func Test_locationlist_open_in_newtab()
6143 call s:create_test_file('Xqftestfile1')
6144 call s:create_test_file('Xqftestfile2')
6145 call s:create_test_file('Xqftestfile3')
6146
6147 %bwipe!
6148
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006149 let lines =<< trim END
6150 Xqftestfile1:5:Line5
6151 Xqftestfile2:10:Line10
6152 Xqftestfile3:16:Line16
6153 END
6154 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006155
6156 silent! llast
6157 call assert_equal(1, tabpagenr('$'))
6158 call assert_equal('Xqftestfile3', bufname())
6159
6160 set switchbuf=newtab
6161
6162 silent! lfirst
6163 call assert_equal(2, tabpagenr('$'))
6164 call assert_equal('Xqftestfile1', bufname())
6165
6166 silent! lnext
6167 call assert_equal(3, tabpagenr('$'))
6168 call assert_equal('Xqftestfile2', bufname())
6169
6170 call delete('Xqftestfile1')
6171 call delete('Xqftestfile2')
6172 call delete('Xqftestfile3')
6173 set switchbuf&vim
6174
6175 %bwipe!
6176endfunc
6177
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006178" Test for win_gettype() in quickfix and location list windows
6179func Test_win_gettype()
6180 copen
6181 call assert_equal("quickfix", win_gettype())
6182 let wid = win_getid()
6183 wincmd p
6184 call assert_equal("quickfix", win_gettype(wid))
6185 cclose
6186 lexpr ''
6187 lopen
6188 call assert_equal("loclist", win_gettype())
6189 let wid = win_getid()
6190 wincmd p
6191 call assert_equal("loclist", win_gettype(wid))
6192 lclose
6193endfunc
6194
Christian Brabandt0b226f62021-12-01 10:54:24 +00006195fun Test_vimgrep_nomatch()
6196 call XexprTests('c')
6197 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6198 copen
6199 if has("win32")
6200 call assert_fails('vimgrep foo *.zzz', 'E479:')
6201 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'}]
6202 else
6203 call assert_fails('vimgrep foo *.zzz', 'E480:')
6204 let expected = []
6205 endif
6206 call assert_equal(expected, getqflist())
6207 cclose
6208endfunc
6209
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006210" Test for opening the quickfix window in two tab pages and then closing one
6211" of the quickfix windows. This should not make the quickfix buffer unlisted.
6212" (github issue #9300).
6213func Test_two_qf_windows()
6214 cexpr "F1:1:line1"
6215 copen
6216 tabnew
6217 copen
6218 call assert_true(&buflisted)
6219 cclose
6220 tabfirst
6221 call assert_true(&buflisted)
6222 let bnum = bufnr()
6223 cclose
6224 " if all the quickfix windows are closed, then buffer should be unlisted.
6225 call assert_false(buflisted(bnum))
6226 %bw!
6227
6228 " Repeat the test for a location list
6229 lexpr "F2:2:line2"
6230 lopen
6231 let bnum = bufnr()
6232 tabnew
6233 exe "buffer" bnum
6234 tabfirst
6235 lclose
6236 tablast
6237 call assert_true(buflisted(bnum))
6238 tabclose
6239 lopen
6240 call assert_true(buflisted(bnum))
6241 lclose
6242 call assert_false(buflisted(bnum))
6243 %bw!
6244endfunc
6245
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006246" Weird sequence of commands that caused entering a wiped-out buffer
6247func Test_lopen_bwipe()
6248 func R()
6249 silent! tab lopen
6250 e x
6251 silent! lfile
6252 endfunc
6253
6254 cal R()
6255 cal R()
6256 cal R()
6257 bw!
6258 delfunc R
6259endfunc
6260
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006261" Another sequence of commands that caused all buffers to be wiped out
6262func Test_lopen_bwipe_all()
6263 let lines =<< trim END
6264 func R()
6265 silent! tab lopen
6266 e foo
6267 silent! lfile
6268 endfunc
6269 cal R()
6270 exe "norm \<C-W>\<C-V>0"
6271 cal R()
6272 bwipe
6273
6274 call writefile(['done'], 'Xresult')
6275 qall!
6276 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006277 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006278 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6279 call assert_equal(['done'], readfile('Xresult'))
6280 endif
6281
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006282 call delete('Xresult')
6283endfunc
6284
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006285" Test for calling setqflist() function recursively
6286func Test_recursive_setqflist()
6287 augroup QF_Test
6288 au!
6289 autocmd BufWinEnter quickfix call setqflist([], 'r')
6290 augroup END
6291
6292 copen
6293 call assert_fails("call setqflist([], 'a')", 'E952:')
6294
6295 augroup QF_Test
6296 au!
6297 augroup END
6298 %bw!
6299endfunc
6300
6301" Test for failure to create a new window when selecting a file from the
6302" quickfix window
6303func Test_cwindow_newwin_fails()
6304 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6305 cwindow
6306 only
6307 let qf_wid = win_getid()
6308 " create the maximum number of scratch windows
6309 let hor_win_count = (&lines - 1)/2
6310 let hor_split_count = hor_win_count - 1
6311 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6312 call win_gotoid(qf_wid)
6313 call assert_fails('exe "normal \<CR>"', 'E36:')
6314 %bw!
6315endfunc
6316
6317" Test for updating the location list when only the location list window is
6318" present and the corresponding file window is closed.
6319func Test_loclist_update_with_llwin_only()
6320 %bw!
6321 new
6322 wincmd w
6323 lexpr ["Xfile1:1:Line1"]
6324 lopen
6325 wincmd p
6326 close
6327 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6328 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6329 %bw!
6330endfunc
6331
6332" Test for getting the quickfix list after a buffer with an error is wiped out
6333func Test_getqflist_wiped_out_buffer()
6334 %bw!
6335 cexpr ["Xtest1:34:Wiped out"]
6336 let bnum = bufnr('Xtest1')
6337 call assert_equal(bnum, getqflist()[0].bufnr)
6338 bw Xtest1
6339 call assert_equal(0, getqflist()[0].bufnr)
6340 %bw!
6341endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006342
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006343" Test for the status message that is displayed when opening a new quickfix
6344" list
6345func Test_qflist_statusmsg()
6346 cexpr "1\n2"
6347 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6348 call assert_equal('(4 of 4): msg', v:statusmsg)
6349 call setqflist([], 'f')
6350 %bw!
6351
6352 " When creating a new quickfix list, if an autocmd changes the quickfix list
6353 " in the stack, then an error message should be displayed.
6354 augroup QF_Test
6355 au!
6356 au BufEnter test_quickfix.vim colder
6357 augroup END
6358 cexpr "1\n2"
6359 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6360 call setqflist([], 'f')
6361 augroup QF_Test
6362 au!
6363 augroup END
6364 %bw!
6365
6366 augroup QF_Test
6367 au!
6368 au BufEnter test_quickfix.vim caddexpr "4"
6369 augroup END
6370 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6371 call setqflist([], 'f')
6372 augroup QF_Test
6373 au!
6374 augroup END
6375 %bw!
6376endfunc
6377
Bram Moolenaard6c67622022-08-24 20:07:22 +01006378func Test_quickfixtextfunc_recursive()
6379 func s:QFTfunc(o)
6380 cgete '0'
6381 endfunc
6382 copen
6383 let &quickfixtextfunc = 's:QFTfunc'
6384 cex ""
6385
6386 let &quickfixtextfunc = ''
6387 cclose
6388endfunc
6389
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006390" Test for replacing the location list from an autocmd. This used to cause a
6391" read from freed memory.
6392func Test_loclist_replace_autocmd()
6393 %bw!
6394 call setloclist(0, [], 'f')
6395 let s:bufnr = bufnr()
6396 cal setloclist(0, [{'0': 0, '': ''}])
6397 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6398 lopen
6399 try
6400 exe "norm j\<CR>"
6401 catch
6402 endtry
6403 lnext
6404 %bw!
6405 call setloclist(0, [], 'f')
6406endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006407
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006408" Test for a very long error line and a very long information line
6409func Test_very_long_error_line()
6410 let msg = repeat('abcdefghijklmn', 146)
6411 let emsg = 'Xlonglines.c:1:' . msg
6412 call writefile([msg, emsg], 'Xerror', 'D')
6413 cfile Xerror
6414 cwindow
6415 call assert_equal($'|| {msg}', getline(1))
6416 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6417 cclose
6418
6419 let l = execute('clist!')->split("\n")
6420 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6421
6422 let l = execute('cc')->split("\n")
6423 call assert_equal([$'(2 of 2): {msg}'], l)
6424
6425 call setqflist([], 'f')
6426endfunc
6427
6428" In the quickfix window, spaces at the beginning of an informational line
6429" should not be removed but should be removed from an error line.
6430func Test_info_line_with_space()
6431 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6432 \ ' 20 | Afunc():', '', ' | ^']
6433 copen
6434 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6435 \ '|| 20 | Afunc():', '|| ',
6436 \ '|| | ^'], getline(1, '$'))
6437 cclose
6438
6439 let l = execute('clist!')->split("\n")
6440 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6441 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6442
6443 call setqflist([], 'f')
6444endfunc
6445
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006446func s:QfTf(_)
6447endfunc
6448
6449func Test_setqflist_cb_arg()
6450 " This was changing the callback name in the dictionary.
6451 let d = #{quickfixtextfunc: 's:QfTf'}
6452 call setqflist([], 'a', d)
6453 call assert_equal('s:QfTf', d.quickfixtextfunc)
6454
6455 call setqflist([], 'f')
6456endfunc
6457
zeertzjqa40c0bc2023-05-27 14:10:08 +01006458" Test that setqflist() should not prevent :stopinsert from working
6459func Test_setqflist_stopinsert()
6460 new
6461 call setqflist([], 'f')
6462 copen
6463 cclose
6464 func StopInsert()
6465 stopinsert
6466 call setqflist([{'text': 'foo'}])
6467 return ''
6468 endfunc
6469
6470 call setline(1, 'abc')
6471 call cursor(1, 1)
6472 call feedkeys("i\<C-R>=StopInsert()\<CR>$", 'tnix')
6473 call assert_equal('foo', getqflist()[0].text)
6474 call assert_equal([0, 1, 3, 0, v:maxcol], getcurpos())
6475 call assert_equal(['abc'], getline(1, '$'))
6476
6477 delfunc StopInsert
6478 call setqflist([], 'f')
6479 bwipe!
6480endfunc
Bram Moolenaard0fab102022-10-20 16:03:33 +01006481
Shane Harper5bf04282023-06-07 19:09:57 +01006482func Test_quickfix_buffer_contents()
6483 call setqflist([{'filename':'filename', 'pattern':'pattern', 'text':'text'}])
6484 copen
6485 call assert_equal(['filename|pattern| text'], getline(1, '$')) " The assert failed with Vim v9.0.0736; '| text' did not appear after the pattern.
6486 call setqflist([], 'f')
6487endfunc
6488
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006489func XquickfixUpdateTests(cchar)
6490 call s:setup_commands(a:cchar)
6491
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006492 " Setup: populate a couple buffers
6493 new
6494 call setline(1, range(1, 5))
6495 let b1 = bufnr()
6496 new
6497 call setline(1, range(1, 3))
6498 let b2 = bufnr()
6499 " Setup: set a quickfix list.
6500 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 +02006501 call g:Xsetlist(items)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006502
6503 " Open the quickfix list, select the third entry.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006504 Xopen
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006505 exe "normal jj\<CR>"
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006506 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006507
6508 " Update the quickfix list. Make sure the third entry is still selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006509 call g:Xsetlist([], 'u', { 'items': items })
6510 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006511
6512 " Update the quickfix list again, but this time with missing line number
6513 " information. Confirm that we keep the current buffer selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006514 call g:Xsetlist([{'bufnr': b1}, {'bufnr': b2}], 'u')
6515 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
6516
6517 Xclose
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006518
6519 " Cleanup the buffers we allocated during this test.
6520 %bwipe!
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006521endfunc
6522
6523" Test for updating a quickfix list using the "u" flag in setqflist()
6524func Test_quickfix_update()
6525 call XquickfixUpdateTests('c')
6526 call XquickfixUpdateTests('l')
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006527endfunc
6528
6529func Test_quickfix_update_with_missing_coordinate_info()
6530 new
6531 call setline(1, range(1, 5))
6532 let b1 = bufnr()
6533
6534 new
6535 call setline(1, range(1, 3))
6536 let b2 = bufnr()
6537
6538 new
6539 call setline(1, range(1, 2))
6540 let b3 = bufnr()
6541
6542 " Setup: set a quickfix list with no coordinate information at all.
6543 call setqflist([{}, {}])
6544
6545 " Open the quickfix list, select the second entry.
6546 copen
6547 exe "normal j\<CR>"
6548 call assert_equal(2, getqflist({'idx' : 0}).idx)
6549
6550 " Update the quickfix list. As the previously selected entry has no
6551 " coordinate information, we expect the first entry to now be selected.
6552 call setqflist([{'bufnr': b1}, {'bufnr': b2}, {'bufnr': b3}], 'u')
6553 call assert_equal(1, getqflist({'idx' : 0}).idx)
6554
6555 " Select the second entry in the quickfix list.
6556 copen
6557 exe "normal j\<CR>"
6558 call assert_equal(2, getqflist({'idx' : 0}).idx)
6559
6560 " Update the quickfix list again. The currently selected entry does not have
6561 " a line number, but we should keep the file selected.
6562 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 3}, {'bufnr': b3}], 'u')
6563 call assert_equal(2, getqflist({'idx' : 0}).idx)
6564
6565 " Update the quickfix list again. The currently selected entry (bufnr=b2, lnum=3)
6566 " is no longer present. We should pick the nearest entry.
6567 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 1}, {'bufnr': b2, 'lnum': 4}], 'u')
6568 call assert_equal(3, getqflist({'idx' : 0}).idx)
6569
6570 " Set the quickfix list again, with a specific column number. The currently selected entry doesn't have a
6571 " column number, but they share a line number.
6572 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 5}, {'bufnr': b2, 'lnum': 4, 'col': 6}], 'u')
6573 call assert_equal(2, getqflist({'idx' : 0}).idx)
6574
6575 " Set the quickfix list again. The currently selected column number (6) is
6576 " no longer present. We should select the nearest column number.
6577 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 2}, {'bufnr': b2, 'lnum': 4, 'col': 4}], 'u')
6578 call assert_equal(3, getqflist({'idx' : 0}).idx)
6579
6580 " Now set the quickfix list, but without columns. We should still pick the
6581 " same line.
6582 call setqflist([{'bufnr': b2, 'lnum': 3}, {'bufnr': b2, 'lnum': 4}, {'bufnr': b2, 'lnum': 4}], 'u')
6583 call assert_equal(2, getqflist({'idx' : 0}).idx)
6584
6585 " Cleanup the buffers we allocated during this test.
6586 %bwipe!
6587endfunc
6588
Yegappan Lakshmananb7318002023-10-25 20:50:28 +02006589" Test for "%b" in "errorformat"
6590func Test_efm_format_b()
6591 call setqflist([], 'f')
6592 new
6593 call setline(1, ['1: abc', '1: def', '1: ghi'])
6594 let b1 = bufnr()
6595 new
6596 call setline(1, ['2: abc', '2: def', '2: ghi'])
6597 let b2 = bufnr()
6598 new
6599 call setline(1, ['3: abc', '3: def', '3: ghi'])
6600 let b3 = bufnr()
6601 new
6602 let lines =<< trim eval END
6603 {b1}:1:1
6604 {b2}:2:2
6605 {b3}:3:3
6606 END
6607 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c'})
6608 cfirst
6609 call assert_equal([b1, 1, 1], [bufnr(), line('.'), col('.')])
6610 cnext
6611 call assert_equal([b2, 2, 2], [bufnr(), line('.'), col('.')])
6612 cnext
6613 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6614 enew!
6615
6616 " Use a non-existing buffer
6617 let lines =<< trim eval END
6618 9991:1:1:m1
6619 9992:2:2:m2
6620 {b3}:3:3:m3
6621 END
6622 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c:%m'})
6623 cfirst | cnext
6624 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6625 " Lines with non-existing buffer numbers should be used as non-error lines
6626 call assert_equal([
6627 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6628 \ module: '', type: '', end_col: 0, col: 0, text: '9991:1:1:m1'},
6629 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6630 \ module: '', type: '', end_col: 0, col: 0, text: '9992:2:2:m2'},
6631 \ #{lnum: 3, bufnr: b3, end_lnum: 0, pattern: '', valid: 1, vcol: 0,
6632 \ nr: -1, module: '', type: '', end_col: 0, col: 3, text: 'm3'}],
6633 \ getqflist())
6634 %bw!
6635 call setqflist([], 'f')
6636endfunc
6637
Christian Brabandt652c8212024-04-29 20:36:49 +02006638func XbufferTests_range(cchar)
6639 call s:setup_commands(a:cchar)
6640
6641 enew!
6642 let lines =<< trim END
6643 Xtestfile7:700:10:Line 700
6644 Xtestfile8:800:15:Line 800
6645 END
6646 silent! call setline(1, lines)
6647 norm! Vy
6648 " Note: We cannot use :Xbuffer here,
6649 " it doesn't properly fail, so we need to
6650 " test using the raw c/l commands.
6651 " (also further down)
6652 if (a:cchar == 'c')
6653 exe "'<,'>cbuffer!"
6654 else
6655 exe "'<,'>lbuffer!"
6656 endif
6657 let l = g:Xgetlist()
6658 call assert_true(len(l) == 1 &&
6659 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700')
6660
6661 enew!
6662 let lines =<< trim END
6663 Xtestfile9:900:55:Line 900
6664 Xtestfile10:950:66:Line 950
6665 END
6666 silent! call setline(1, lines)
6667 if (a:cchar == 'c')
6668 1cgetbuffer
6669 else
6670 1lgetbuffer
6671 endif
6672 let l = g:Xgetlist()
6673 call assert_true(len(l) == 1 &&
6674 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900')
6675
6676 enew!
6677 let lines =<< trim END
6678 Xtestfile11:700:20:Line 700
6679 Xtestfile12:750:25:Line 750
6680 END
6681 silent! call setline(1, lines)
6682 if (a:cchar == 'c')
6683 1,1caddbuffer
6684 else
6685 1,1laddbuffer
6686 endif
6687 let l = g:Xgetlist()
6688 call assert_true(len(l) == 2 &&
6689 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
6690 \ l[1].lnum == 700 && l[1].col == 20 && l[1].text ==# 'Line 700')
6691 enew!
6692
6693 " Check for invalid range
6694 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
6695 " commands. So directly call the commands.
6696 if (a:cchar == 'c')
6697 call assert_fails('900,999caddbuffer', 'E16:')
6698 else
6699 call assert_fails('900,999laddbuffer', 'E16:')
6700 endif
6701endfunc
6702
6703func Test_cbuffer_range()
6704 call XbufferTests_range('c')
6705 call XbufferTests_range('l')
6706endfunc
6707
zeertzjq5df3cb22024-10-07 21:05:06 +02006708" Test for displaying fname passed from setqflist() when the names include
6709" hard links to prevent seemingly duplicate entries.
Austin Chang29822992024-10-03 10:50:05 +02006710func Xtest_hardlink_fname(cchar)
6711 call s:setup_commands(a:cchar)
6712 %bwipe
6713 " Create a sample source file
6714 let lines =<< trim END
6715 void sample() {}
6716 int main() { sample(); return 0; }
6717 END
6718 call writefile(lines, 'test_qf_hardlink1.c', 'D')
6719 defer delete('test_qf_hardlink1.c')
6720 defer delete('test_qf_hardlink2.c')
6721 call system('ln test_qf_hardlink1.c test_qf_hardlink2.c')
6722 if v:shell_error
6723 throw 'Skipped: ln throws error on this platform'
6724 endif
6725 call g:Xsetlist([], 'f')
6726 " Make a qflist that contains the file and it's hard link
6727 " like how LSP plugins set response into qflist
6728 call g:Xsetlist([{'filename' : 'test_qf_hardlink1.c', 'lnum' : 1},
6729 \ {'filename' : 'test_qf_hardlink2.c', 'lnum' : 1}], ' ')
6730 Xopen
6731 " Ensure that two entries are displayed with different name
6732 " so that they aren't seen as duplication.
6733 call assert_equal(['test_qf_hardlink1.c|1| ',
6734 \ 'test_qf_hardlink2.c|1| '], getline(1, '$'))
6735 Xclose
6736endfunc
6737
6738func Test_hardlink_fname()
6739 CheckUnix
6740 CheckExecutable ln
6741 call Xtest_hardlink_fname('c')
6742 call Xtest_hardlink_fname('l')
6743endfunc
6744
64-bitman88d41ab2025-04-06 17:20:39 +02006745" Test for checking if correct number of tests are deleted
6746" and current list stays the same after setting Xhistory
6747" to a smaller number. Do roughly the same for growing the stack.
6748func Xtest_resize_list_stack(cchar)
6749 call s:setup_commands(a:cchar)
6750 Xsethist 100
6751
6752 for i in range(1, 100)
6753 Xexpr string(i)
6754 endfor
6755 Xopen
6756 call assert_equal(g:Xgetlist({'nr': '$'}).nr, 100)
6757 call assert_equal("|| 100", getline(1))
6758 Xsethist 8
6759 call assert_equal("|| 100", getline(1))
6760 Xolder 5
6761 call assert_equal("|| 95", getline(1))
6762 Xsethist 6
6763 call assert_equal("|| 95", getline(1))
6764 Xsethist 1
6765 call assert_equal("|| 100", getline(1))
6766
6767 " grow array again
6768 Xsethist 100
6769 for i in range(1, 99)
6770 Xexpr string(i)
6771 endfor
6772 call assert_equal("|| 99", getline(1))
6773 Xolder 99
6774 call assert_equal("|| 100", getline(1))
6775
6776 Xsethistdefault
6777endfunc
6778
6779func Test_resize_list_stack()
6780 call Xtest_resize_list_stack('c')
6781 call Xtest_resize_list_stack('l')
6782endfunc
6783
6784" Test to check if order of lists is from
6785" oldest at the bottom to newest at the top
6786func Xtest_Xhistory_check_order(cchar)
6787
6788 Xsethist 100
6789
6790 for i in range(1, 100)
6791 Xexpr string(i)
6792 endfor
6793
6794 Xopen
6795 for i in range(100, 1, -1)
6796 let l:ret = assert_equal("|| " .. i, getline(1))
6797
6798 if ret == 1 || i == 1
6799 break
6800 endif
6801 Xolder
6802 endfor
6803
6804 for i in range(1, 50)
6805 Xexpr string(i)
6806 endfor
6807
6808 for i in range(50, 1, -1)
6809 let l:ret = assert_equal("|| " .. i, getline(1))
6810
6811 if ret == 1 || i == 50
6812 break
6813 endif
6814 Xolder
6815 endfor
6816
6817 for i in range(50, 1, -1)
6818 let l:ret = assert_equal("|| " .. i, getline(1))
6819
6820 if ret == 1 || i == 50
6821 break
6822 endif
6823 Xolder
6824 endfor
6825
6826 Xsethistdefault
6827endfunc
6828
6829func Test_set_history_to_check_order()
6830 call Xtest_Xhistory_check_order('c')
6831 call Xtest_Xhistory_check_order('l')
6832endfunc
6833
6834" Check if 'lhistory' is the same between the location list window
6835" and associated normal window
6836func Test_win_and_loc_synced()
6837 new
6838 set lhistory=2
6839 lexpr "Text"
6840 lopen
6841
6842 " check if lhistory is synced when modified inside the
6843 " location list window
6844 setlocal lhistory=1
6845 wincmd k
6846 call assert_equal(&lhistory, 1)
6847
6848 " check if lhistory is synced when modified inside the
6849 " normal window
6850 setlocal lhistory=10
6851 lopen
6852 call assert_equal(&lhistory, 10)
6853
6854 wincmd k
6855 lclose
6856 wincmd q
6857
6858 set lhistory&
6859endfunc
6860
6861" Test if setting the lhistory of one window doesn't affect the other
6862func Test_two_win_are_independent_of_history()
6863 setlocal lhistory=10
6864 new
6865 setlocal lhistory=20
6866 wincmd w
6867 call assert_equal(&lhistory, 10)
6868 wincmd w
6869 wincmd q
6870
6871 set lhistory&
6872endfunc
6873
6874" Test if lhistory is copied over to a new window
6875func Test_lhistory_copied_over()
6876 setlocal lhistory=3
6877 split
6878 call assert_equal(&lhistory, 3)
6879 wincmd q
6880
6881 set lhistory&
6882endfunc
6883
6884" Test if error occurs when given invalid history number
6885func Xtest_invalid_history_num(cchar)
6886 call s:setup_commands(a:cchar)
6887
6888 call assert_fails('Xsethist -10000', "E1542:")
6889 call assert_fails('Xsethist 10000', "E1543:")
6890 Xsethistdefault
6891endfunc
6892
6893func Test_invalid_history_num()
6894 call Xtest_invalid_history_num('c')
6895 call Xtest_invalid_history_num('l')
6896endfunc
6897
6898" Test if chistory and lhistory don't affect each other
6899func Test_chi_and_lhi_are_independent()
6900 set chistory=100
6901 set lhistory=100
6902
6903 set chistory=10
6904 call assert_equal(&lhistory, 100)
6905
6906 set lhistory=1
6907 call assert_equal(&chistory, 10)
6908
6909 set chistory&
6910 set lhistory&
6911endfunc
6912
Christian Brabandtce80c592025-03-28 19:13:32 +01006913func Test_quickfix_close_buffer_crash()
6914 new
6915 lexpr 'test' | lopen
6916 wincmd k
6917 lclose
6918 wincmd q
6919endfunc
6920
Sean Dewarb4074ea2025-05-10 14:30:36 +02006921func Test_vimgrep_dummy_buffer_crash()
6922 augroup DummyCrash
6923 autocmd!
6924 " Make the dummy buffer non-current, but still open in a window.
6925 autocmd BufReadCmd * ++once let s:dummy_buf = bufnr()
6926 \| split | wincmd p | enew
6927
6928 " Autocmds from cleaning up the dummy buffer in this case should be blocked.
6929 autocmd BufWipeout *
6930 \ call assert_notequal(s:dummy_buf, str2nr(expand('<abuf>')))
6931 augroup END
6932
6933 silent! vimgrep /./ .
6934 redraw! " Window to freed dummy buffer used to remain; heap UAF.
6935 call assert_equal([], win_findbuf(s:dummy_buf))
6936 call assert_equal(0, bufexists(s:dummy_buf))
6937
6938 unlet! s:dummy_buf
6939 autocmd! DummyCrash
6940 %bw!
6941endfunc
6942
Sean Dewar270124f2025-05-10 14:33:28 +02006943func Test_vimgrep_dummy_buffer_keep()
6944 augroup DummyKeep
6945 autocmd!
6946 " Trigger a wipe of the dummy buffer by aborting script processing. Prevent
6947 " wiping it by splitting it from the autocmd window into an only window.
6948 autocmd BufReadCmd * ++once let s:dummy_buf = bufnr()
6949 \| tab split | call interrupt()
6950 augroup END
6951
6952 call assert_fails('vimgrep /./ .')
6953 call assert_equal(1, bufexists(s:dummy_buf))
6954 " Ensure it's no longer considered a dummy; should be able to switch to it.
6955 execute s:dummy_buf 'sbuffer'
6956
6957 unlet! s:dummy_buf
6958 autocmd! DummyKeep
6959 %bw!
6960endfunc
6961
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006962" vim: shiftwidth=2 sts=2 expandtab