blob: df4cc80112887fb9e6bf14ab4d693999da7fe5fe [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
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002382func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002383 " Use one 'errorformat' for two windows. Add an expression to each of them,
2384 " make sure they each keep their own state.
2385 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002386 call mkdir('Xone/a', 'pR')
2387 call mkdir('Xtwo/a', 'pR')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002388 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2389 call writefile(lines, 'Xone/a/one.txt')
2390 call writefile(lines, 'Xtwo/a/two.txt')
2391
2392 new one
2393 let one_id = win_getid()
2394 lexpr ""
2395 new two
2396 let two_id = win_getid()
2397 lexpr ""
2398
2399 laddexpr "Entering dir 'Xtwo/a'"
2400 call win_gotoid(one_id)
2401 laddexpr "Entering dir 'Xone/a'"
2402 call win_gotoid(two_id)
2403 laddexpr 'two.txt:5:two two two'
2404 call win_gotoid(one_id)
2405 laddexpr 'one.txt:3:one one one'
2406
2407 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002408 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2409 call assert_equal(3, loc_one[1].lnum)
2410
2411 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002412 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2413 call assert_equal(5, loc_two[1].lnum)
2414
2415 call win_gotoid(one_id)
2416 bwipe!
2417 call win_gotoid(two_id)
2418 bwipe!
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002419endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002420
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002421func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002422 call s:setup_commands(a:cchar)
2423
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002424 " Calling lbottom without any errors should fail
2425 if a:cchar == 'l'
2426 call assert_fails('lbottom', 'E776:')
2427 endif
2428
Bram Moolenaar875feea2017-06-11 16:07:51 +02002429 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002430 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002431 let wid = win_getid()
2432 call assert_equal(1, line('.'))
2433 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002434 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002435 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002436 call win_gotoid(wid)
2437 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002438 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002439endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002440
2441" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002442func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002443 call XbottomTests('c')
2444 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002445endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002446
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002447func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002448 call s:setup_commands(a:cchar)
2449
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002450 " clear all lists after the first one, then replace the first one.
2451 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002452 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002453 let entry = {'filename': 'foo', 'lnum': 42}
2454 call g:Xsetlist([entry], 'r')
2455 call g:Xsetlist([entry, entry])
2456 call g:Xsetlist([entry, entry, entry])
2457 let res = split(execute(a:cchar . 'hist'), "\n")
2458 call assert_equal(3, len(res))
2459 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2460 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2461 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2462 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002463
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002464 " Test for changing the quickfix lists
2465 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2466 exe '1' . a:cchar . 'hist'
2467 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2468 exe '3' . a:cchar . 'hist'
2469 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2470 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2471 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2472
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002473 call g:Xsetlist([], 'f')
2474 let l = split(execute(a:cchar . 'hist'), "\n")
2475 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002476 if a:cchar == 'c'
2477 call assert_fails('4chist', 'E16:')
2478 else
2479 call assert_fails('4lhist', 'E776:')
2480 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002481
2482 " An empty list should still show the stack history
2483 call g:Xsetlist([])
2484 let res = split(execute(a:cchar . 'hist'), "\n")
2485 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2486
2487 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002488endfunc
2489
2490func Test_history()
2491 call HistoryTest('c')
2492 call HistoryTest('l')
2493endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002494
2495func Test_duplicate_buf()
2496 " make sure we can get the highest buffer number
2497 edit DoesNotExist
2498 edit DoesNotExist2
2499 let last_buffer = bufnr("$")
2500
2501 " make sure only one buffer is created
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002502 call writefile(['this one', 'that one'], 'Xgrepthis', 'D')
Bram Moolenaar015102e2016-07-16 18:24:56 +02002503 vimgrep one Xgrepthis
2504 vimgrep one Xgrepthis
2505 call assert_equal(last_buffer + 1, bufnr("$"))
Bram Moolenaar015102e2016-07-16 18:24:56 +02002506endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002507
2508" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002509func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002510 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002511
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002512 " Error cases
2513 call assert_fails('call g:Xgetlist(99)', 'E715:')
2514 call assert_fails('call g:Xsetlist(99)', 'E714:')
2515 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002516
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002517 " Set and get the title
2518 call g:Xsetlist([])
2519 Xopen
2520 wincmd p
2521 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2522 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2523 call assert_equal(0, s)
2524 let d = g:Xgetlist({"title":1})
2525 call assert_equal('Sample', d.title)
2526 " Try setting title to a non-string value
2527 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2528 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2529
2530 Xopen
2531 call assert_equal('Sample', w:quickfix_title)
2532 Xclose
2533
2534 " Tests for action argument
2535 silent! Xolder 999
2536 let qfnr = g:Xgetlist({'all':1}).nr
2537 call g:Xsetlist([], 'r', {'title' : 'N1'})
2538 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2539 call g:Xsetlist([], ' ', {'title' : 'N2'})
2540 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2541
2542 let res = g:Xgetlist({'nr': 0})
2543 call assert_equal(qfnr + 1, res.nr)
2544 call assert_equal(['nr'], keys(res))
2545
2546 call g:Xsetlist([], ' ', {'title' : 'N3'})
2547 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2548
2549 " Changing the title of an earlier quickfix list
2550 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2551 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2552
2553 " Changing the title of an invalid quickfix list
2554 call assert_equal(-1, g:Xsetlist([], ' ',
2555 \ {'title' : 'SomeTitle', 'nr' : 99}))
2556 call assert_equal(-1, g:Xsetlist([], ' ',
2557 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2558
2559 if a:cchar == 'c'
2560 copen
2561 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2562 cclose
2563 endif
2564
2565 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002566 call assert_fails('call g:Xgetlist([])', 'E715:')
2567 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002568 let s = g:Xsetlist([], 'a', {'abc':1})
2569 call assert_equal(-1, s)
2570
2571 call assert_equal({}, g:Xgetlist({'abc':1}))
2572 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2573 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2574
2575 if a:cchar == 'l'
2576 call assert_equal({}, getloclist(99, {'title': 1}))
2577 endif
2578
2579 " Context related tests
2580 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2581 call assert_equal(0, s)
2582 call test_garbagecollect_now()
2583 let d = g:Xgetlist({'context':1})
2584 call assert_equal([1,2,3], d.context)
2585 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2586 let d = g:Xgetlist({'context':1})
2587 call assert_equal({'color':'green'}, d.context)
2588 call g:Xsetlist([], 'a', {'context':"Context info"})
2589 let d = g:Xgetlist({'context':1})
2590 call assert_equal("Context info", d.context)
2591 call g:Xsetlist([], 'a', {'context':246})
2592 let d = g:Xgetlist({'context':1})
2593 call assert_equal(246, d.context)
2594 " set other Vim data types as context
2595 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2596 if has('channel')
2597 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2598 endif
2599 if has('job')
2600 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2601 endif
2602 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2603 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2604 call g:Xsetlist([], 'a', {'context' : ''})
2605 call test_garbagecollect_now()
2606 if a:cchar == 'l'
2607 " Test for copying context across two different location lists
2608 new | only
2609 let w1_id = win_getid()
2610 let l = [1]
2611 call setloclist(0, [], 'a', {'context':l})
2612 new
2613 let w2_id = win_getid()
2614 call add(l, 2)
2615 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2616 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2617 unlet! l
2618 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2619 only
2620 call setloclist(0, [], 'f')
2621 call assert_equal('', getloclist(0, {'context':1}).context)
2622 endif
2623
2624 " Test for changing the context of previous quickfix lists
2625 call g:Xsetlist([], 'f')
2626 Xexpr "One"
2627 Xexpr "Two"
2628 Xexpr "Three"
2629 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2630 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2631 " Also, check for setting the context using quickfix list number zero.
2632 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2633 call test_garbagecollect_now()
2634 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2635 call assert_equal([1], l.context)
2636 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2637 call assert_equal([2], l.context)
2638 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2639 call assert_equal([3], l.context)
2640
2641 " Test for changing the context through reference and for garbage
2642 " collection of quickfix context
2643 let l = ["red"]
2644 call g:Xsetlist([], ' ', {'context' : l})
2645 call add(l, "blue")
2646 let x = g:Xgetlist({'context' : 1})
2647 call add(x.context, "green")
2648 call assert_equal(["red", "blue", "green"], l)
2649 call assert_equal(["red", "blue", "green"], x.context)
2650 unlet l
2651 call test_garbagecollect_now()
2652 let m = g:Xgetlist({'context' : 1})
2653 call assert_equal(["red", "blue", "green"], m.context)
2654
2655 " Test for setting/getting items
2656 Xexpr ""
2657 let qfprev = g:Xgetlist({'nr':0})
2658 let s = g:Xsetlist([], ' ', {'title':'Green',
2659 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2660 call assert_equal(0, s)
2661 let qfcur = g:Xgetlist({'nr':0})
2662 call assert_true(qfcur.nr == qfprev.nr + 1)
2663 let l = g:Xgetlist({'items':1})
2664 call assert_equal('F1', bufname(l.items[0].bufnr))
2665 call assert_equal(10, l.items[0].lnum)
2666 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2667 \ {'filename':'F2', 'lnum':30}]})
2668 let l = g:Xgetlist({'items':1})
2669 call assert_equal('F2', bufname(l.items[2].bufnr))
2670 call assert_equal(30, l.items[2].lnum)
2671 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2672 let l = g:Xgetlist({'items':1})
2673 call assert_equal('F3', bufname(l.items[0].bufnr))
2674 call assert_equal(40, l.items[0].lnum)
2675 call g:Xsetlist([], 'r', {'items' : []})
2676 let l = g:Xgetlist({'items':1})
2677 call assert_equal(0, len(l.items))
2678
2679 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2680 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2681 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2682 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2683
2684 " Test for getting id of window associated with a location list window
2685 if a:cchar == 'l'
2686 only
2687 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2688 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002689 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002690 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2691 wincmd w
2692 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2693 only
2694 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002695
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002696 " The following used to crash Vim with address sanitizer
2697 call g:Xsetlist([], 'f')
2698 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2699 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002700
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002701 " Try setting the items using a string
2702 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002703
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002704 " Save and restore the quickfix stack
2705 call g:Xsetlist([], 'f')
2706 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2707 Xexpr "File1:10:Line1"
2708 Xexpr "File2:20:Line2"
2709 Xexpr "File3:30:Line3"
2710 let last_qf = g:Xgetlist({'nr':'$'}).nr
2711 call assert_equal(3, last_qf)
2712 let qstack = []
2713 for i in range(1, last_qf)
2714 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2715 endfor
2716 call g:Xsetlist([], 'f')
2717 for i in range(len(qstack))
2718 call g:Xsetlist([], ' ', qstack[i])
2719 endfor
2720 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2721 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2722 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2723 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2724 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002725
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002726 " Swap two quickfix lists
2727 Xexpr "File1:10:Line10"
2728 Xexpr "File2:20:Line20"
2729 Xexpr "File3:30:Line30"
2730 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2731 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2732 let l1=g:Xgetlist({'nr':1,'all':1})
2733 let l2=g:Xgetlist({'nr':2,'all':1})
2734 let save_id = l1.id
2735 let l1.id=l2.id
2736 let l2.id=save_id
2737 call g:Xsetlist([], 'r', l1)
2738 call g:Xsetlist([], 'r', l2)
2739 let newl1=g:Xgetlist({'nr':1,'all':1})
2740 let newl2=g:Xgetlist({'nr':2,'all':1})
2741 call assert_equal('Fruits', newl1.title)
2742 call assert_equal(['Fruits'], newl1.context)
2743 call assert_equal('Line20', newl1.items[0].text)
2744 call assert_equal('Colors', newl2.title)
2745 call assert_equal(['Colors'], newl2.context)
2746 call assert_equal('Line10', newl2.items[0].text)
2747 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002748
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002749 " Cannot specify both a non-empty list argument and a dict argument
2750 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002751endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002752
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002753func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002754 call Xproperty_tests('c')
2755 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002756endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002757
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002758" Test for setting the current index in the location/quickfix list
2759func Xtest_setqfidx(cchar)
2760 call s:setup_commands(a:cchar)
2761
2762 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2763 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2764 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2765
2766 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2767 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2768 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2769 Xolder 2
2770 Xopen
2771 call assert_equal(3, line('.'))
2772 Xnewer
2773 call assert_equal(2, line('.'))
2774 Xnewer
2775 call assert_equal(2, line('.'))
2776 " Update the current index with the quickfix window open
2777 wincmd w
2778 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2779 Xopen
2780 call assert_equal(3, line('.'))
2781 Xclose
2782
2783 " Set the current index to the last entry
2784 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2785 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2786 " A large value should set the index to the last index
2787 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2788 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2789 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2790 " Invalid index values
2791 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2792 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2793 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2794 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2795 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2796 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2797 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2798
2799 call g:Xsetlist([], 'f')
2800 new | only
2801endfunc
2802
2803func Test_setqfidx()
2804 call Xtest_setqfidx('c')
2805 call Xtest_setqfidx('l')
2806endfunc
2807
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002808" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002809func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002810 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002811endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002812
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002813func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002814 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2815 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2816
2817 let g:acmds = []
2818 cexpr "F1:10:Line 10"
2819 caddexpr "F1:20:Line 20"
2820 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002821 cexpr ""
2822 caddexpr ""
2823 cgetexpr ""
2824 silent! cexpr non_existing_func()
2825 silent! caddexpr non_existing_func()
2826 silent! cgetexpr non_existing_func()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002827 let l =<< trim END
2828 precexpr
2829 postcexpr
2830 precaddexpr
2831 postcaddexpr
2832 precgetexpr
2833 postcgetexpr
2834 precexpr
2835 postcexpr
2836 precaddexpr
2837 postcaddexpr
2838 precgetexpr
2839 postcgetexpr
2840 precexpr
2841 precaddexpr
2842 precgetexpr
2843 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002844 call assert_equal(l, g:acmds)
2845
2846 let g:acmds = []
2847 enew! | call append(0, "F2:10:Line 10")
2848 cbuffer!
2849 enew! | call append(0, "F2:20:Line 20")
2850 cgetbuffer
2851 enew! | call append(0, "F2:30:Line 30")
2852 caddbuffer
2853 new
2854 let bnum = bufnr('%')
2855 bunload
2856 exe 'silent! cbuffer! ' . bnum
2857 exe 'silent! cgetbuffer ' . bnum
2858 exe 'silent! caddbuffer ' . bnum
2859 enew!
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002860 let l =<< trim END
2861 precbuffer
2862 postcbuffer
2863 precgetbuffer
2864 postcgetbuffer
2865 precaddbuffer
2866 postcaddbuffer
2867 precbuffer
2868 precgetbuffer
2869 precaddbuffer
2870 END
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002871 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002872
Bram Moolenaardb77cb32022-10-05 21:45:30 +01002873 call writefile(['Xtest:1:Line1'], 'Xtest', 'D')
2874 call writefile([], 'Xempty', 'D')
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002875 let g:acmds = []
2876 cfile Xtest
2877 caddfile Xtest
2878 cgetfile Xtest
2879 cfile Xempty
2880 caddfile Xempty
2881 cgetfile Xempty
2882 silent! cfile do_not_exist
2883 silent! caddfile do_not_exist
2884 silent! cgetfile do_not_exist
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002885 let l =<< trim END
2886 precfile
2887 postcfile
2888 precaddfile
2889 postcaddfile
2890 precgetfile
2891 postcgetfile
2892 precfile
2893 postcfile
2894 precaddfile
2895 postcaddfile
2896 precgetfile
2897 postcgetfile
2898 precfile
2899 postcfile
2900 precaddfile
2901 postcaddfile
2902 precgetfile
2903 postcgetfile
2904 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002905 call assert_equal(l, g:acmds)
2906
2907 let g:acmds = []
2908 helpgrep quickfix
2909 silent! helpgrep non_existing_help_topic
2910 vimgrep test Xtest
2911 vimgrepadd test Xtest
2912 silent! vimgrep non_existing_test Xtest
2913 silent! vimgrepadd non_existing_test Xtest
2914 set makeprg=
2915 silent! make
2916 set makeprg&
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002917 let l =<< trim END
2918 prehelpgrep
2919 posthelpgrep
2920 prehelpgrep
2921 posthelpgrep
2922 previmgrep
2923 postvimgrep
2924 previmgrepadd
2925 postvimgrepadd
2926 previmgrep
2927 postvimgrep
2928 previmgrepadd
2929 postvimgrepadd
2930 premake
2931 postmake
2932 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002933 call assert_equal(l, g:acmds)
2934
2935 if has('unix')
2936 " Run this test only on Unix-like systems. The grepprg may not be set on
2937 " non-Unix systems.
2938 " The following lines are used for the grep test. Don't remove.
2939 " Grep_Autocmd_Text: Match 1
2940 " GrepAdd_Autocmd_Text: Match 2
2941 let g:acmds = []
2942 silent grep Grep_Autocmd_Text test_quickfix.vim
2943 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2944 silent grep abc123def Xtest
2945 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002946 set grepprg=internal
2947 silent grep Grep_Autocmd_Text test_quickfix.vim
2948 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2949 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2950 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2951 set grepprg&vim
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01002952 let l =<< trim END
2953 pregrep
2954 postgrep
2955 pregrepadd
2956 postgrepadd
2957 pregrep
2958 postgrep
2959 pregrepadd
2960 postgrepadd
2961 pregrep
2962 postgrep
2963 pregrepadd
2964 postgrepadd
2965 prelgrep
2966 postlgrep
2967 prelgrepadd
2968 postlgrepadd
2969 END
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002970 call assert_equal(l, g:acmds)
2971 endif
2972
Bram Moolenaarb254af32017-12-18 19:48:58 +01002973 au! QuickFixCmdPre
2974 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002975endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002976
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002977func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002978 set efm=%m
2979 lgetexpr '?'
2980
2981 try
2982 call DoesNotExit()
2983 catch
2984 lgetexpr '1'
2985 finally
2986 lgetexpr '1'
2987 endtry
2988
2989 call assert_equal('1', getloclist(0)[0].text)
2990
2991 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002992endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002993
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002994func Test_caddbuffer_wrong()
2995 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002996 let save_efm = &efm
2997 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2998 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2999 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003000 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01003001 bwipe!
3002endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01003003
3004func Test_caddexpr_wrong()
3005 " This used to cause a memory access in freed memory.
3006 cbuffer
3007 cbuffer
3008 copen
3009 let save_efm = &efm
3010 set efm=%
3011 call assert_fails('caddexpr ""', 'E376:')
3012 let &efm = save_efm
3013endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01003014
3015func Test_dirstack_cleanup()
3016 " This used to cause a memory access in freed memory.
3017 let save_efm = &efm
3018 lexpr '0'
3019 lopen
3020 fun X(c)
3021 let save_efm=&efm
3022 set efm=%D%f
3023 if a:c == 'c'
3024 caddexpr '::'
3025 else
3026 laddexpr ':0:0'
3027 endif
3028 let &efm=save_efm
3029 endfun
3030 call X('c')
3031 call X('l')
3032 call setqflist([], 'r')
3033 caddbuffer
3034 let &efm = save_efm
3035endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003036
3037" Tests for jumping to entries from the location list window and quickfix
3038" window
3039func Test_cwindow_jump()
3040 set efm=%f%%%l%%%m
3041 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3042 lopen | only
3043 lfirst
3044 call assert_true(winnr('$') == 2)
3045 call assert_true(winnr() == 1)
3046 " Location list for the new window should be set
3047 call assert_true(getloclist(0)[2].text == 'Line 30')
3048
3049 " Open a scratch buffer
3050 " Open a new window and create a location list
3051 " Open the location list window and close the other window
3052 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01003053 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003054 " should not be used.
3055 enew | only
3056 set buftype=nofile
3057 below new
3058 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3059 lopen
3060 2wincmd c
3061 lnext
3062 call assert_true(winnr('$') == 3)
3063 call assert_true(winnr() == 2)
3064
3065 " Open two windows with two different location lists
3066 " Open the location list window and close the previous window
3067 " Jump to an entry in the location list window
3068 " Should open the file in the first window and not set the location list.
3069 enew | only
3070 lgetexpr ["F1%5%Line 5"]
3071 below new
3072 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3073 lopen
3074 2wincmd c
3075 lnext
3076 call assert_true(winnr() == 1)
3077 call assert_true(getloclist(0)[0].text == 'Line 5')
3078
3079 enew | only
3080 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3081 copen
3082 cnext
3083 call assert_true(winnr('$') == 2)
3084 call assert_true(winnr() == 1)
3085
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003086 " open the quickfix buffer in two windows and jump to an entry. Should open
3087 " the file in the first quickfix window.
3088 enew | only
3089 copen
3090 let bnum = bufnr('')
3091 exe 'sbuffer ' . bnum
3092 wincmd b
3093 cfirst
3094 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003095 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003096 enew | only
3097 exe 'sb' bnum
3098 exe 'botright sb' bnum
3099 wincmd t
3100 clast
3101 call assert_equal(2, winnr())
3102 call assert_equal('quickfix', getwinvar(1, '&buftype'))
3103 call assert_equal('quickfix', getwinvar(3, '&buftype'))
3104
Bram Moolenaar4b96df52020-01-26 22:00:26 +01003105 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01003106 " window by wrapping around the window list.
3107 enew | only
3108 call setloclist(0, [], 'f')
3109 new | new
3110 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
3111 lopen
3112 1close
3113 call assert_equal(0, getloclist(3, {'id' : 0}).id)
3114 lnext
3115 call assert_equal(3, winnr())
3116 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
3117
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01003118 enew | only
3119 set efm&vim
3120endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01003121
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003122func Test_cwindow_highlight()
3123 CheckScreendump
3124
3125 let lines =<< trim END
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003126 call setline(1, ['some', 'text', 'with', 'matches'])
3127 write XCwindow
3128 vimgrep e XCwindow
3129 redraw
3130 cwindow 4
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003131 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003132 call writefile(lines, 'XtestCwindow', 'D')
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003133 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
3134 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
3135
3136 call term_sendkeys(buf, ":cnext\<CR>")
3137 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
3138
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003139 call term_sendkeys(buf, "\<C-W>j:set cursorline\<CR>")
zeertzjqb7acea12022-12-12 13:20:43 +00003140 call term_sendkeys(buf, ":\<CR>")
3141 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3142
3143 call term_sendkeys(buf, ":set cursorlineopt=number,screenline\<CR>")
3144 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaar7fe956d2022-07-03 14:21:09 +01003145 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_3', {})
3146
3147 call term_sendkeys(buf, "j")
3148 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_4', {})
3149
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003150 " clean up
3151 call StopVimInTerminal(buf)
Bram Moolenaare00fdf32019-09-15 19:09:42 +02003152 call delete('XCwindow')
3153endfunc
3154
Bram Moolenaaree85df32017-03-19 14:19:50 +01003155func XvimgrepTests(cchar)
3156 call s:setup_commands(a:cchar)
3157
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003158 let lines =<< trim END
3159 Editor:VIM vim
3160 Editor:Emacs EmAcS
3161 Editor:Notepad NOTEPAD
3162 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003163 call writefile(lines, 'Xtestfile1', 'D')
3164 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2', 'D')
Bram Moolenaaree85df32017-03-19 14:19:50 +01003165
3166 " Error cases
3167 call assert_fails('Xvimgrep /abc *', 'E682:')
3168
3169 let @/=''
3170 call assert_fails('Xvimgrep // *', 'E35:')
3171
3172 call assert_fails('Xvimgrep abc', 'E683:')
3173 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
3174 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
3175
3176 Xexpr ""
3177 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00003178 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01003179 let l = g:Xgetlist()
3180 call assert_equal(2, len(l))
3181 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
3182
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003183 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01003184 let l = g:Xgetlist()
3185 call assert_equal(2, len(l))
3186 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02003187 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003188 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02003189 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003190
3191 1Xvimgrep ?Editor? Xtestfile*
3192 let l = g:Xgetlist()
3193 call assert_equal(1, len(l))
3194 call assert_equal('Editor:VIM vim', l[0].text)
3195
3196 edit +3 Xtestfile2
3197 Xvimgrep +\cemacs+j Xtestfile1
3198 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003199 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01003200 call assert_equal('Editor:Emacs EmAcS', l[0].text)
3201
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02003202 " Test for unloading a buffer after vimgrep searched the buffer
3203 %bwipe
3204 Xvimgrep /Editor/j Xtestfile*
3205 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
3206 call assert_equal([], getbufinfo('Xtestfile2'))
3207
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00003208 " Test for opening the dummy buffer used by vimgrep in a window. The new
3209 " window should be closed
3210 %bw!
3211 augroup QF_Test
3212 au!
3213 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3214 augroup END
3215 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3216 call assert_equal(1, winnr('$'))
3217 augroup QF_Test
3218 au!
3219 augroup END
Bram Moolenaaree85df32017-03-19 14:19:50 +01003220endfunc
3221
3222" Tests for the :vimgrep command
3223func Test_vimgrep()
3224 call XvimgrepTests('c')
3225 call XvimgrepTests('l')
3226endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003227
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003228func Test_vimgrep_wildcards_expanded_once()
3229 new X[id-01] file.txt
3230 call setline(1, 'some text to search for')
3231 vimgrep text %
3232 bwipe!
3233endfunc
3234
Bram Moolenaar1c299432018-10-28 14:36:09 +01003235" Test for incsearch highlighting of the :vimgrep pattern
3236" This test used to cause "E315: ml_get: invalid lnum" errors.
3237func Test_vimgrep_incsearch()
3238 enew
3239 set incsearch
3240 call test_override("char_avail", 1)
3241
3242 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3243 let l = getqflist()
3244 call assert_equal(2, len(l))
3245
3246 call test_override("ALL", 0)
3247 set noincsearch
3248endfunc
3249
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003250" Test vimgrep with the last search pattern not set
3251func Test_vimgrep_with_no_last_search_pat()
3252 let lines =<< trim [SCRIPT]
3253 call assert_fails('vimgrep // *', 'E35:')
3254 call writefile(v:errors, 'Xresult')
3255 qall!
3256 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003257 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003258 if RunVim([], [], '--clean -S Xscript')
3259 call assert_equal([], readfile('Xresult'))
3260 endif
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003261 call delete('Xresult')
3262endfunc
3263
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003264" Test vimgrep without swap file
3265func Test_vimgrep_without_swap_file()
3266 let lines =<< trim [SCRIPT]
3267 vimgrep grep test_c*
3268 call writefile(['done'], 'Xresult')
3269 qall!
3270 [SCRIPT]
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003271 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003272 if RunVim([], [], '--clean -n -S Xscript Xscript')
3273 call assert_equal(['done'], readfile('Xresult'))
3274 endif
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003275 call delete('Xresult')
3276endfunc
3277
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003278func Test_vimgrep_existing_swapfile()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003279 call writefile(['match apple with apple'], 'Xapple', 'D')
3280 call writefile(['swapfile'], '.Xapple.swp', 'D')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003281 let g:foundSwap = 0
3282 let g:ignoreSwapExists = 1
3283 augroup grep
3284 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3285 augroup END
3286 vimgrep apple Xapple
3287 call assert_equal(1, g:foundSwap)
3288 call assert_match('.Xapple.swo', swapname(''))
3289
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003290 augroup grep
3291 au! SwapExists
3292 augroup END
3293 unlet g:ignoreSwapExists
3294endfunc
3295
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003296func XfreeTests(cchar)
3297 call s:setup_commands(a:cchar)
3298
3299 enew | only
3300
3301 " Deleting the quickfix stack should work even When the current list is
3302 " somewhere in the middle of the stack
3303 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3304 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3305 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3306 Xolder
3307 call g:Xsetlist([], 'f')
3308 call assert_equal(0, len(g:Xgetlist()))
3309
3310 " After deleting the stack, adding a new list should create a stack with a
3311 " single list.
3312 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3313 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3314
3315 " Deleting the stack from a quickfix window should update/clear the
3316 " quickfix/location list window.
3317 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3318 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3319 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3320 Xolder
3321 Xwindow
3322 call g:Xsetlist([], 'f')
3323 call assert_equal(2, winnr('$'))
3324 call assert_equal(1, line('$'))
3325 Xclose
3326
3327 " Deleting the stack from a non-quickfix window should update/clear the
3328 " quickfix/location list window.
3329 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3330 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3331 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3332 Xolder
3333 Xwindow
3334 wincmd p
3335 call g:Xsetlist([], 'f')
3336 call assert_equal(0, len(g:Xgetlist()))
3337 wincmd p
3338 call assert_equal(2, winnr('$'))
3339 call assert_equal(1, line('$'))
3340
3341 " After deleting the location list stack, if the location list window is
3342 " opened, then a new location list should be created. So opening the
3343 " location list window again should not create a new window.
3344 if a:cchar == 'l'
3345 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3346 wincmd p
3347 lopen
3348 call assert_equal(2, winnr('$'))
3349 endif
3350 Xclose
3351endfunc
3352
Bram Moolenaar74240d32017-12-10 15:26:15 +01003353" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003354func Test_qf_free()
3355 call XfreeTests('c')
3356 call XfreeTests('l')
3357endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003358
3359" Test for buffer overflow when parsing lines and adding new entries to
3360" the quickfix list.
3361func Test_bufoverflow()
3362 set efm=%f:%l:%m
3363 cgetexpr ['File1:100:' . repeat('x', 1025)]
3364
3365 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3366 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3367
3368 set efm=%DEntering\ directory\ %f,%f:%l:%m
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01003369 let lines =<< trim eval END
3370 Entering directory $"{repeat('a', 1006)}"
3371 File1:10:Hello World
3372 END
3373 cgetexpr lines
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003374 set efm&vim
3375endfunc
3376
Bram Moolenaar875feea2017-06-11 16:07:51 +02003377" Tests for getting the quickfix stack size
3378func XsizeTests(cchar)
3379 call s:setup_commands(a:cchar)
3380
3381 call g:Xsetlist([], 'f')
3382 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003383 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3384 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003385
3386 Xexpr "File1:10:Line1"
3387 Xexpr "File2:20:Line2"
3388 Xexpr "File3:30:Line3"
3389 Xolder | Xolder
3390 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3391 call g:Xsetlist([], 'f')
3392
3393 Xexpr "File1:10:Line1"
3394 Xexpr "File2:20:Line2"
3395 Xexpr "File3:30:Line3"
3396 Xolder | Xolder
3397 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3398 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3399endfunc
3400
3401func Test_Qf_Size()
3402 call XsizeTests('c')
3403 call XsizeTests('l')
3404endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003405
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003406func Test_cclose_from_copen()
3407 augroup QF_Test
3408 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003409 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003410 augroup END
3411 copen
3412 augroup QF_Test
3413 au!
3414 augroup END
3415 augroup! QF_Test
3416endfunc
3417
Bram Moolenaar18141832017-06-25 21:17:25 +02003418func Test_cclose_in_autocmd()
zeertzjq269aa2b2022-11-28 11:36:50 +00003419 " Problem is only triggered if "starting" is zero, so that the OptionSet
Bram Moolenaar18141832017-06-25 21:17:25 +02003420 " event will be triggered.
3421 call test_override('starting', 1)
3422 augroup QF_Test
3423 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003424 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003425 augroup END
3426 copen
3427 augroup QF_Test
3428 au!
3429 augroup END
3430 augroup! QF_Test
3431 call test_override('starting', 0)
3432endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003433
Bram Moolenaar379fb762018-08-30 15:58:28 +02003434" Check that ":file" without an argument is possible even when "curbuf_lock"
3435" is set.
3436func Test_file_from_copen()
3437 " Works without argument.
3438 augroup QF_Test
3439 au!
3440 au FileType qf file
3441 augroup END
3442 copen
3443
3444 augroup QF_Test
3445 au!
3446 augroup END
3447 cclose
3448
3449 " Fails with argument.
3450 augroup QF_Test
3451 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003452 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003453 augroup END
3454 copen
3455 augroup QF_Test
3456 au!
3457 augroup END
3458 cclose
3459
3460 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003461endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003462
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003463func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003464 augroup QF_Test
3465 au!
3466 au FileType qf resize 5
3467 augroup END
3468 try
3469 " This should succeed without any exception. No other buffers are
3470 " involved in the autocmd.
3471 copen
3472 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003473 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003474 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003475 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003476 augroup! QF_Test
3477 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003478endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003479
Bram Moolenaard0fab102022-10-20 16:03:33 +01003480func Test_filetype_autocmd()
3481 " this changes the location list while it is in use to fill a buffer
3482 lexpr ''
3483 lopen
3484 augroup FT_loclist
3485 au FileType * call setloclist(0, [], 'f')
3486 augroup END
3487 silent! lolder
3488 lexpr ''
3489
3490 augroup FT_loclist
3491 au! FileType
3492 augroup END
3493endfunc
3494
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003495func Test_vimgrep_with_textlock()
3496 new
3497
zeertzjqcfe45652022-05-27 17:26:55 +01003498 " Simple way to execute something with "textlock" set.
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003499 " Check that vimgrep without jumping can be executed.
3500 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3501 normal ax
3502 let qflist = getqflist()
3503 call assert_true(len(qflist) > 0)
3504 call assert_match('RunTheTest', qflist[0].text)
3505 call setqflist([], 'r')
3506 au! InsertCharPre
3507
3508 " Check that vimgrepadd without jumping can be executed.
3509 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3510 normal ax
3511 let qflist = getqflist()
3512 call assert_true(len(qflist) > 0)
3513 call assert_match('RunTheTest', qflist[0].text)
3514 call setqflist([], 'r')
3515 au! InsertCharPre
3516
3517 " Check that lvimgrep without jumping can be executed.
3518 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3519 normal ax
3520 let qflist = getloclist(0)
3521 call assert_true(len(qflist) > 0)
3522 call assert_match('RunTheTest', qflist[0].text)
3523 call setloclist(0, [], 'r')
3524 au! InsertCharPre
3525
3526 " Check that lvimgrepadd without jumping can be executed.
3527 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3528 normal ax
3529 let qflist = getloclist(0)
3530 call assert_true(len(qflist) > 0)
3531 call assert_match('RunTheTest', qflist[0].text)
3532 call setloclist(0, [], 'r')
3533 au! InsertCharPre
3534
3535 " trying to jump will give an error
3536 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3537 call assert_fails('normal ax', 'E565:')
3538 au! InsertCharPre
3539
3540 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3541 call assert_fails('normal ax', 'E565:')
3542 au! InsertCharPre
3543
3544 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3545 call assert_fails('normal ax', 'E565:')
3546 au! InsertCharPre
3547
3548 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3549 call assert_fails('normal ax', 'E565:')
3550 au! InsertCharPre
3551
3552 bwipe!
3553endfunc
3554
Bram Moolenaara8788f42017-07-19 17:06:20 +02003555" Tests for the quickfix buffer b:changedtick variable
3556func Xchangedtick_tests(cchar)
3557 call s:setup_commands(a:cchar)
3558
3559 new | only
3560
3561 Xexpr "" | Xexpr "" | Xexpr ""
3562
3563 Xopen
3564 Xolder
3565 Xolder
3566 Xaddexpr "F1:10:Line10"
3567 Xaddexpr "F2:20:Line20"
3568 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3569 call g:Xsetlist([], 'f')
3570 call assert_equal(8, getbufvar('%', 'changedtick'))
3571 Xclose
3572endfunc
3573
3574func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003575 call Xchangedtick_tests('c')
3576 call Xchangedtick_tests('l')
3577endfunc
3578
3579" Tests for parsing an expression using setqflist()
3580func Xsetexpr_tests(cchar)
3581 call s:setup_commands(a:cchar)
3582
3583 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003584 call g:Xsetlist([], ' ', {'lines' : t})
3585 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003586
3587 let l = g:Xgetlist()
3588 call assert_equal(3, len(l))
3589 call assert_equal(20, l[1].lnum)
3590 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003591 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003592 let l = g:Xgetlist()
3593 call assert_equal(1, len(l))
3594 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003595 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3596 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003597
3598 call g:Xsetlist([], 'f')
3599 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003600 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3601 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3602 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3603 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003604 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3605 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003606
3607 " Adding entries using a custom efm
3608 set efm&
3609 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3610 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3611 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3612 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3613 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3614 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3615 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3616 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003617endfunc
3618
3619func Test_setexpr()
3620 call Xsetexpr_tests('c')
3621 call Xsetexpr_tests('l')
3622endfunc
3623
3624" Tests for per quickfix/location list directory stack
3625func Xmultidirstack_tests(cchar)
3626 call s:setup_commands(a:cchar)
3627
3628 call g:Xsetlist([], 'f')
3629 Xexpr "" | Xexpr ""
3630
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003631 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3632 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3633 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3634 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003635
3636 let l1 = g:Xgetlist({'nr':1, 'items':1})
3637 let l2 = g:Xgetlist({'nr':2, 'items':1})
3638 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3639 call assert_equal(3, l1.items[1].lnum)
3640 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3641 call assert_equal(5, l2.items[1].lnum)
3642endfunc
3643
3644func Test_multidirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003645 call mkdir('Xone/a', 'pR')
3646 call mkdir('Xtwo/a', 'pR')
Bram Moolenaarae338332017-08-11 20:25:26 +02003647 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3648 call writefile(lines, 'Xone/a/one.txt')
3649 call writefile(lines, 'Xtwo/a/two.txt')
3650 let save_efm = &efm
3651 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3652
3653 call Xmultidirstack_tests('c')
3654 call Xmultidirstack_tests('l')
3655
3656 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003657endfunc
3658
3659" Tests for per quickfix/location list file stack
3660func Xmultifilestack_tests(cchar)
3661 call s:setup_commands(a:cchar)
3662
3663 call g:Xsetlist([], 'f')
3664 Xexpr "" | Xexpr ""
3665
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003666 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3667 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3668 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3669 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003670
3671 let l1 = g:Xgetlist({'nr':1, 'items':1})
3672 let l2 = g:Xgetlist({'nr':2, 'items':1})
3673 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3674 call assert_equal(3, l1.items[1].lnum)
3675 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3676 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003677
3678 " Test for start of a new error line in the same line where a previous
3679 " error line ends with a file stack.
3680 let efm_val = 'Error\ l%l\ in\ %f,'
3681 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003682 let lines =<< trim END
3683 (one.txt
3684 Error l4 in one.txt
3685 ) (two.txt
3686 Error l6 in two.txt
3687 )
3688 Error l8 in one.txt
3689 END
3690 let l = g:Xgetlist({'lines': lines, 'efm' : efm_val})
Bram Moolenaare333e792018-04-08 13:27:39 +02003691 call assert_equal(3, len(l.items))
3692 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3693 call assert_equal(4, l.items[0].lnum)
3694 call assert_equal('one.txt', l.items[0].text)
3695 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3696 call assert_equal(6, l.items[1].lnum)
3697 call assert_equal('two.txt', l.items[1].text)
3698 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3699 call assert_equal(8, l.items[2].lnum)
3700 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003701endfunc
3702
3703func Test_multifilestack()
3704 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003705 call writefile(lines, 'one.txt', 'D')
3706 call writefile(lines, 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003707 let save_efm = &efm
3708 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3709
3710 call Xmultifilestack_tests('c')
3711 call Xmultifilestack_tests('l')
3712
3713 let &efm = save_efm
Bram Moolenaarae338332017-08-11 20:25:26 +02003714endfunc
3715
3716" Tests for per buffer 'efm' setting
3717func Test_perbuf_efm()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003718 call writefile(["File1-10-Line10"], 'one.txt', 'D')
3719 call writefile(["File2#20#Line20"], 'two.txt', 'D')
Bram Moolenaarae338332017-08-11 20:25:26 +02003720 set efm=%f#%l#%m
3721 new | only
3722 new
3723 setlocal efm=%f-%l-%m
3724 cfile one.txt
3725 wincmd w
3726 caddfile two.txt
3727
3728 let l = getqflist()
3729 call assert_equal(10, l[0].lnum)
3730 call assert_equal('Line20', l[1].text)
3731
3732 set efm&
3733 new | only
Bram Moolenaara8788f42017-07-19 17:06:20 +02003734endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003735
3736" Open multiple help windows using ":lhelpgrep
3737" This test used to crash Vim
3738func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003739 new | only
3740 lhelpgrep window
3741 lopen
3742 e#
3743 lhelpgrep buffer
3744 call assert_equal(3, winnr('$'))
3745 call assert_true(len(getloclist(1)) != 0)
3746 call assert_true(len(getloclist(2)) != 0)
3747 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003748endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003749
3750" Tests for adding new quickfix lists using setqflist()
3751func XaddQf_tests(cchar)
3752 call s:setup_commands(a:cchar)
3753
3754 " Create a new list using ' ' for action
3755 call g:Xsetlist([], 'f')
3756 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3757 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3758 call assert_equal(1, l.nr)
3759 call assert_equal('Test1', l.title)
3760
3761 " Create a new list using ' ' for action and '$' for 'nr'
3762 call g:Xsetlist([], 'f')
3763 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3764 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3765 call assert_equal(1, l.nr)
3766 call assert_equal('Test2', l.title)
3767
3768 " Create a new list using 'a' for action
3769 call g:Xsetlist([], 'f')
3770 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3771 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3772 call assert_equal(1, l.nr)
3773 call assert_equal('Test3', l.title)
3774
3775 " Create a new list using 'a' for action and '$' for 'nr'
3776 call g:Xsetlist([], 'f')
3777 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3778 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3779 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3780 call assert_equal(1, l.nr)
3781 call assert_equal('Test4', l.title)
3782
3783 " Adding a quickfix list should remove all the lists following the current
3784 " list.
3785 Xexpr "" | Xexpr "" | Xexpr ""
3786 silent! 10Xolder
3787 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3788 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3789 call assert_equal(2, l.nr)
3790 call assert_equal('Test5', l.title)
3791
3792 " Add a quickfix list using '$' as the list number.
3793 let lastqf = g:Xgetlist({'nr':'$'}).nr
3794 silent! 99Xolder
3795 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3796 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3797 call assert_equal(lastqf + 1, l.nr)
3798 call assert_equal('Test6', l.title)
3799
3800 " Add a quickfix list using 'nr' set to one more than the quickfix
3801 " list size.
3802 let lastqf = g:Xgetlist({'nr':'$'}).nr
3803 silent! 99Xolder
3804 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3805 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3806 call assert_equal(lastqf + 1, l.nr)
3807 call assert_equal('Test7', l.title)
3808
3809 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3810 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3811 silent! 99Xolder
3812 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3813 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3814 call assert_equal(10, l.nr)
3815 call assert_equal('Test8', l.title)
3816
3817 " Add a quickfix list using 'nr' set to a value greater than 10
3818 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3819
3820 " Try adding a quickfix list with 'nr' set to a value greater than the
3821 " quickfix list size but less than 10.
3822 call g:Xsetlist([], 'f')
3823 Xexpr "" | Xexpr "" | Xexpr ""
3824 silent! 99Xolder
3825 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3826
3827 " Add a quickfix list using 'nr' set to a some string or list
3828 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3829endfunc
3830
3831func Test_add_qf()
3832 call XaddQf_tests('c')
3833 call XaddQf_tests('l')
3834endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003835
3836" Test for getting the quickfix list items from some text without modifying
3837" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003838func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003839 call s:setup_commands(a:cchar)
3840 call g:Xsetlist([], 'f')
3841
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003842 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003843 call assert_equal(2, len(l))
3844 call assert_equal(30, l[1].lnum)
3845
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003846 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3847 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3848 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3849 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003850
Bram Moolenaar36538222017-09-02 19:51:44 +02003851 " Parse text using a custom efm
3852 set efm&
3853 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3854 call assert_equal('Line30', l[0].text)
3855 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3856 call assert_equal('File3:30:Line30', l[0].text)
3857 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3858 call assert_equal({}, l)
3859 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3860 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3861
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003862 " Make sure that the quickfix stack is not modified
3863 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3864endfunc
3865
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003866func Test_get_list_from_lines()
3867 call XgetListFromLines('c')
3868 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003869endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003870
3871" Tests for the quickfix list id
3872func Xqfid_tests(cchar)
3873 call s:setup_commands(a:cchar)
3874
3875 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003876 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003877 Xexpr ''
3878 let start_id = g:Xgetlist({'id' : 0}).id
3879 Xexpr '' | Xexpr ''
3880 Xolder
3881 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3882 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3883 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003884 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003885 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003886 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3887 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003888
3889 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3890 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003891 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003892 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3893 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3894 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3895
3896 let qfid = g:Xgetlist({'id':0, 'nr':0})
3897 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003898 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003899endfunc
3900
3901func Test_qf_id()
3902 call Xqfid_tests('c')
3903 call Xqfid_tests('l')
3904endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003905
3906func Xqfjump_tests(cchar)
3907 call s:setup_commands(a:cchar)
3908
Bram Moolenaardb77cb32022-10-05 21:45:30 +01003909 call writefile(["Line1\tFoo", "Line2"], 'F1', 'D')
3910 call writefile(["Line1\tBar", "Line2"], 'F2', 'D')
3911 call writefile(["Line1\tBaz", "Line2"], 'F3', 'D')
Bram Moolenaar74240d32017-12-10 15:26:15 +01003912
3913 call g:Xsetlist([], 'f')
3914
3915 " Tests for
3916 " Jumping to a line using a pattern
3917 " Jumping to a column greater than the last column in a line
3918 " Jumping to a line greater than the last line in the file
3919 let l = []
3920 for i in range(1, 7)
3921 call add(l, {})
3922 endfor
3923 let l[0].filename='F1'
3924 let l[0].pattern='Line1'
3925 let l[1].filename='F2'
3926 let l[1].pattern='Line1'
3927 let l[2].filename='F3'
3928 let l[2].pattern='Line1'
3929 let l[3].filename='F3'
3930 let l[3].lnum=1
3931 let l[3].col=9
3932 let l[3].vcol=1
3933 let l[4].filename='F3'
3934 let l[4].lnum=99
3935 let l[5].filename='F3'
3936 let l[5].lnum=1
3937 let l[5].col=99
3938 let l[5].vcol=1
3939 let l[6].filename='F3'
3940 let l[6].pattern='abcxyz'
3941
3942 call g:Xsetlist([], ' ', {'items' : l})
3943 Xopen | only
3944 2Xnext
3945 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003946 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003947 Xnext
3948 call assert_equal(7, col('.'))
3949 Xnext
3950 call assert_equal(2, line('.'))
3951 Xnext
3952 call assert_equal(9, col('.'))
3953 2
3954 Xnext
3955 call assert_equal(2, line('.'))
3956
3957 if a:cchar == 'l'
3958 " When jumping to a location list entry in the location list window and
3959 " no usable windows are available, then a new window should be opened.
3960 enew! | new | only
3961 call g:Xsetlist([], 'f')
3962 setlocal buftype=nofile
3963 new
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01003964 let lines =<< trim END
3965 F1:1:1:Line1
3966 F1:2:2:Line2
3967 F2:1:1:Line1
3968 F2:2:2:Line2
3969 F3:1:1:Line1
3970 F3:2:2:Line2
3971 END
3972 call g:Xsetlist([], ' ', {'lines': lines})
Bram Moolenaar74240d32017-12-10 15:26:15 +01003973 Xopen
3974 let winid = win_getid()
3975 wincmd p
3976 close
3977 call win_gotoid(winid)
3978 Xnext
3979 call assert_equal(3, winnr('$'))
3980 call assert_equal(1, winnr())
3981 call assert_equal(2, line('.'))
3982
3983 " When jumping to an entry in the location list window and the window
3984 " associated with the location list is not present and a window containing
3985 " the file is already present, then that window should be used.
3986 close
3987 belowright new
3988 call g:Xsetlist([], 'f')
3989 edit F3
3990 call win_gotoid(winid)
3991 Xlast
3992 call assert_equal(3, winnr())
3993 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3994 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3995 endif
3996
3997 " Cleanup
3998 enew!
3999 new | only
Bram Moolenaar74240d32017-12-10 15:26:15 +01004000endfunc
4001
4002func Test_qfjump()
4003 call Xqfjump_tests('c')
4004 call Xqfjump_tests('l')
4005endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01004006
4007" Tests for the getqflist() and getloclist() functions when the list is not
4008" present or is empty
4009func Xgetlist_empty_tests(cchar)
4010 call s:setup_commands(a:cchar)
4011
4012 " Empty quickfix stack
4013 call g:Xsetlist([], 'f')
4014 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4015 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
4016 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4017 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4018 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
4019 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4020 call assert_equal('', g:Xgetlist({'title' : 0}).title)
4021 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004022 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004023 if a:cchar == 'c'
4024 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004025 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004026 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
4027 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004028 else
4029 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
4030 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004031 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004032 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004033 \ g:Xgetlist({'all' : 0}))
4034 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004035
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004036 " Quickfix window with empty stack
4037 silent! Xopen
4038 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004039 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01004040 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
4041 Xclose
4042
Bram Moolenaara6d48492017-12-12 22:45:31 +01004043 " Empty quickfix list
4044 Xexpr ""
4045 call assert_equal('', g:Xgetlist({'context' : 0}).context)
4046 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
4047 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
4048 call assert_equal([], g:Xgetlist({'items' : 0}).items)
4049 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
4050 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
4051 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
4052 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004053 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01004054
4055 let qfid = g:Xgetlist({'id' : 0}).id
4056 call g:Xsetlist([], 'f')
4057
4058 " Non-existing quickfix identifier
4059 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
4060 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
4061 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
4062 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
4063 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
4064 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
4065 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
4066 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004067 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004068 if a:cchar == 'c'
4069 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4070 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004071 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004072 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
4073 else
4074 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4075 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004076 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4077 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004078 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
4079 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004080
4081 " Non-existing quickfix list number
4082 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
4083 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
4084 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
4085 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
4086 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
4087 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
4088 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
4089 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004090 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004091 if a:cchar == 'c'
4092 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4093 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004094 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
4095 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004096 else
4097 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
4098 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02004099 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
4100 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02004101 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01004102endfunc
4103
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004104func Test_empty_list_quickfixtextfunc()
4105 " This was crashing. Can only reproduce by running it in a separate Vim
4106 " instance.
4107 let lines =<< trim END
4108 func s:Func(o)
4109 cgetexpr '0'
4110 endfunc
4111 cope
4112 let &quickfixtextfunc = 's:Func'
4113 cgetfile [ex
4114 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004115 call writefile(lines, 'Xquickfixtextfunc', 'D')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004116 call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
Bram Moolenaar4f1b0832022-08-29 20:45:16 +01004117endfunc
4118
Bram Moolenaara6d48492017-12-12 22:45:31 +01004119func Test_getqflist()
4120 call Xgetlist_empty_tests('c')
4121 call Xgetlist_empty_tests('l')
4122endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01004123
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01004124func Test_getqflist_invalid_nr()
4125 " The following commands used to crash Vim
4126 cexpr ""
4127 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
4128
4129 " Cleanup
4130 call setqflist([], 'r')
4131endfunc
4132
Bram Moolenaarb254af32017-12-18 19:48:58 +01004133" Tests for the quickfix/location list changedtick
4134func Xqftick_tests(cchar)
4135 call s:setup_commands(a:cchar)
4136
4137 call g:Xsetlist([], 'f')
4138
4139 Xexpr "F1:10:Line10"
4140 let qfid = g:Xgetlist({'id' : 0}).id
4141 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4142 Xaddexpr "F2:20:Line20\nF2:21:Line21"
4143 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4144 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
4145 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
4146 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
4147 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
4148 call g:Xsetlist([], 'a', {'title' : 'New Title'})
4149 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
4150
4151 enew!
4152 call append(0, ["F5:50:L50", "F6:60:L60"])
4153 Xaddbuffer
4154 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
4155 enew!
4156
4157 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
4158 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
4159 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4160 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
4161 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
4162 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4163 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
4164 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4165 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
4166 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
4167 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4168
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004169 call writefile(["F8:80:L80", "F8:81:L81"], "Xone", 'D')
Bram Moolenaarb254af32017-12-18 19:48:58 +01004170 Xfile Xone
4171 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4172 Xaddfile Xone
4173 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
4174
4175 " Test case for updating a non-current quickfix list
4176 call g:Xsetlist([], 'f')
4177 Xexpr "F1:1:L1"
4178 Xexpr "F2:2:L2"
4179 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
4180 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
4181 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
Bram Moolenaarb254af32017-12-18 19:48:58 +01004182endfunc
4183
4184func Test_qf_tick()
4185 call Xqftick_tests('c')
4186 call Xqftick_tests('l')
4187endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01004188
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02004189" Test helpgrep with lang specifier
4190func Xtest_helpgrep_with_lang_specifier(cchar)
4191 call s:setup_commands(a:cchar)
4192 Xhelpgrep Vim@en
4193 call assert_equal('help', &filetype)
4194 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
4195 new | only
4196endfunc
4197
4198func Test_helpgrep_with_lang_specifier()
4199 call Xtest_helpgrep_with_lang_specifier('c')
4200 call Xtest_helpgrep_with_lang_specifier('l')
4201endfunc
4202
Bram Moolenaar12237442017-12-19 12:38:52 +01004203" The following test used to crash Vim.
4204" Open the location list window and close the regular window associated with
4205" the location list. When the garbage collection runs now, it incorrectly
4206" marks the location list context as not in use and frees the context.
4207func Test_ll_window_ctx()
4208 call setloclist(0, [], 'f')
4209 call setloclist(0, [], 'a', {'context' : []})
4210 lopen | only
4211 call test_garbagecollect_now()
4212 echo getloclist(0, {'context' : 1}).context
4213 enew | only
4214endfunc
4215
zeertzjqbe4bd182024-09-14 10:32:31 +02004216" Similar to the problem above, but for user data.
4217func Test_ll_window_user_data()
4218 call setloclist(0, [#{bufnr: bufnr(), user_data: {}}])
4219 lopen
4220 wincmd t
4221 close
4222 call test_garbagecollect_now()
4223 call feedkeys("\<CR>", 'tx')
4224 call test_garbagecollect_now()
4225 %bwipe!
4226endfunc
4227
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004228" The following test used to crash vim
4229func Test_lfile_crash()
4230 sp Xtest
4231 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02004232 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01004233 au! QuickFixCmdPre
4234endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01004235
4236" The following test used to crash vim
4237func Test_lbuffer_crash()
4238 sv Xtest
4239 augroup QF_Test
4240 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004241 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01004242 augroup END
4243 lbuffer
4244 augroup QF_Test
4245 au!
4246 augroup END
4247endfunc
4248
4249" The following test used to crash vim
4250func Test_lexpr_crash()
4251 augroup QF_Test
4252 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004253 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004254 augroup END
4255 lexpr ""
4256 augroup QF_Test
4257 au!
4258 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004259
Bram Moolenaar3c097222017-12-21 20:54:49 +01004260 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004261 augroup QF_Test
4262 au!
4263 au BufNew * call setloclist(0, [], 'f')
4264 augroup END
4265 lexpr 'x:1:x'
4266 augroup QF_Test
4267 au!
4268 augroup END
4269
4270 enew | only
4271 lexpr ''
4272 lopen
4273 augroup QF_Test
4274 au!
4275 au FileType * call setloclist(0, [], 'f')
4276 augroup END
4277 lexpr ''
4278 augroup QF_Test
4279 au!
4280 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004281endfunc
4282
4283" The following test used to crash Vim
4284func Test_lvimgrep_crash()
Austin Chang29822992024-10-03 10:50:05 +02004285 " this leaves a swapfile .test_quickfix.vim.swp around, why?
Bram Moolenaar3c097222017-12-21 20:54:49 +01004286 sv Xtest
4287 augroup QF_Test
4288 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004289 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004290 augroup END
4291 lvimgrep quickfix test_quickfix.vim
4292 augroup QF_Test
4293 au!
4294 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004295
4296 new | only
4297 augroup QF_Test
4298 au!
4299 au BufEnter * call setloclist(0, [], 'r')
4300 augroup END
4301 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4302 augroup QF_Test
4303 au!
4304 augroup END
4305
Bram Moolenaar3c097222017-12-21 20:54:49 +01004306 enew | only
4307endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004308
Bram Moolenaar2573af32020-03-14 17:21:34 +01004309func Test_lvimgrep_crash2()
4310 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004311 call assert_fails('lvimgrep x x', 'E471:')
4312 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004313
4314 au! BufNewFile
4315endfunc
4316
Bram Moolenaarde046542017-12-26 13:53:11 +01004317" Test for the position of the quickfix and location list window
4318func Test_qfwin_pos()
4319 " Open two windows
4320 new | only
4321 new
4322 cexpr ['F1:10:L10']
4323 copen
4324 " Quickfix window should be the bottom most window
4325 call assert_equal(3, winnr())
4326 close
4327 " Open at the very top
4328 wincmd t
4329 topleft copen
4330 call assert_equal(1, winnr())
4331 close
4332 " open left of the current window
4333 wincmd t
4334 below new
4335 leftabove copen
4336 call assert_equal(2, winnr())
4337 close
4338 " open right of the current window
4339 rightbelow copen
4340 call assert_equal(3, winnr())
4341 close
4342endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004343
4344" Tests for quickfix/location lists changed by autocommands when
4345" :vimgrep/:lvimgrep commands are running.
4346func Test_vimgrep_autocmd()
4347 call setqflist([], 'f')
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004348 call writefile(['stars'], 'Xtest1.txt', 'D')
4349 call writefile(['stars'], 'Xtest2.txt', 'D')
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004350
4351 " Test 1:
4352 " When searching for a pattern using :vimgrep, if the quickfix list is
4353 " changed by an autocmd, the results should be added to the correct quickfix
4354 " list.
4355 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4356 silent vimgrep stars Xtest*.txt
4357 call assert_equal(1, getqflist({'nr' : 0}).nr)
4358 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4359 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4360 au! BufRead Xtest2.txt
4361
4362 " Test 2:
4363 " When searching for a pattern using :vimgrep, if the quickfix list is
4364 " freed, then a error should be given.
4365 silent! %bwipe!
4366 call setqflist([], 'f')
4367 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4368 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4369 au! BufRead Xtest2.txt
4370
4371 " Test 3:
4372 " When searching for a pattern using :lvimgrep, if the location list is
4373 " freed, then the command should error out.
4374 silent! %bwipe!
4375 let g:save_winid = win_getid()
4376 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4377 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4378 au! BufRead Xtest2.txt
Austin Chang29822992024-10-03 10:50:05 +02004379 " cleanup the swap files
4380 bw! Xtest2.txt Xtest1.txt
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004381
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004382 call setqflist([], 'f')
4383endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004384
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004385" Test for an autocmd changing the current directory when running vimgrep
4386func Xvimgrep_autocmd_cd(cchar)
4387 call s:setup_commands(a:cchar)
4388
4389 %bwipe
4390 let save_cwd = getcwd()
4391
4392 augroup QF_Test
4393 au!
4394 autocmd BufRead * silent cd %:p:h
4395 augroup END
4396
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004397 10Xvimgrep /vim/ Xgrepdir/**
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004398 let l = g:Xgetlist()
4399 call assert_equal('f1.txt', bufname(l[0].bufnr))
4400 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4401
4402 augroup QF_Test
4403 au!
4404 augroup END
4405
4406 exe 'cd ' . save_cwd
4407endfunc
4408
4409func Test_vimgrep_autocmd_cd()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004410 call mkdir('Xgrepdir/a', 'pR')
4411 call mkdir('Xgrepdir/b', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004412 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xgrepdir/a/f1.txt')
4413 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xgrepdir/b/f2.txt')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004414 call Xvimgrep_autocmd_cd('c')
4415 call Xvimgrep_autocmd_cd('l')
4416 %bwipe
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004417endfunc
4418
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004419" The following test used to crash Vim
4420func Test_lhelpgrep_autocmd()
4421 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004422 augroup QF_Test
4423 au!
4424 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4425 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004426 lhelpgrep buffer
4427 call assert_equal('help', &filetype)
4428 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4429 lhelpgrep tabpage
4430 call assert_equal('help', &filetype)
4431 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004432 augroup QF_Test
4433 au!
4434 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004435
4436 new | only
4437 augroup QF_Test
4438 au!
4439 au BufEnter * call setqflist([], 'f')
4440 augroup END
4441 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004442 " run the test with a help window already open
4443 help
4444 wincmd w
4445 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004446 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004447 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004448 augroup END
4449
4450 new | only
4451 augroup QF_Test
4452 au!
4453 au BufEnter * call setqflist([], 'r')
4454 augroup END
4455 call assert_fails('helpgrep quickfix', 'E925:')
4456 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004457 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004458 augroup END
4459
4460 new | only
4461 augroup QF_Test
4462 au!
4463 au BufEnter * call setloclist(0, [], 'r')
4464 augroup END
4465 call assert_fails('lhelpgrep quickfix', 'E926:')
4466 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004467 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004468 augroup END
4469
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004470 " Replace the contents of a help window location list when it is still in
4471 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004472 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004473 lhelpgrep quickfix
4474 wincmd w
4475 augroup QF_Test
4476 au!
4477 autocmd WinEnter * call setloclist(0, [], 'r')
4478 augroup END
4479 call assert_fails('lhelpgrep win_getid', 'E926:')
4480 augroup QF_Test
4481 au!
4482 augroup END
4483
4484 %bw!
4485endfunc
4486
4487" The following test used to crash Vim
4488func Test_lhelpgrep_autocmd_free_loclist()
4489 %bw!
4490 lhelpgrep quickfix
4491 wincmd w
4492 augroup QF_Test
4493 au!
4494 autocmd WinEnter * call setloclist(0, [], 'f')
4495 augroup END
4496 lhelpgrep win_getid
4497 wincmd w
4498 wincmd w
4499 wincmd w
4500 augroup QF_Test
4501 au!
4502 augroup END
4503 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004504endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004505
4506" Test for shortening/simplifying the file name when opening the
4507" quickfix window or when displaying the quickfix list
4508func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004509 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004510 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004511 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004512 let fname = getcwd() . '/test_quickfix.vim'
4513 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4514 call assert_equal(fname, bufname('test_quickfix.vim'))
4515 " Opening the quickfix window should simplify the file path
4516 cwindow
4517 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4518 cclose
4519 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004520 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004521 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4522 call assert_equal(fname, bufname('test_quickfix.vim'))
4523 " Displaying the quickfix list should simplify the file path
4524 silent! clist
4525 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004526 " Add a few entries for the same file with different paths and check whether
4527 " the buffer name is shortened
4528 %bwipe
4529 call setqflist([], 'f')
4530 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4531 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4532 \ {'filename' : fname, 'lnum' : 30}], ' ')
4533 copen
4534 call assert_equal(['test_quickfix.vim|10| ',
4535 \ 'test_quickfix.vim|20| ',
4536 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4537 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004538endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004539
4540" Quickfix title tests
4541" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4542" Otherwise due to indentation, the title is set with spaces at the beginning
4543" of the command.
4544func Test_qftitle()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004545 call writefile(["F1:1:Line1"], 'Xerr', 'D')
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004546
4547 " :cexpr
4548 exe "cexpr readfile('Xerr')"
4549 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4550
4551 " :cgetexpr
4552 exe "cgetexpr readfile('Xerr')"
4553 call assert_equal(":cgetexpr readfile('Xerr')",
4554 \ getqflist({'title' : 1}).title)
4555
4556 " :caddexpr
4557 call setqflist([], 'f')
4558 exe "caddexpr readfile('Xerr')"
4559 call assert_equal(":caddexpr readfile('Xerr')",
4560 \ getqflist({'title' : 1}).title)
4561
4562 " :cbuffer
4563 new Xerr
4564 exe "cbuffer"
4565 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4566
4567 " :cgetbuffer
4568 edit Xerr
4569 exe "cgetbuffer"
4570 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4571
4572 " :caddbuffer
4573 call setqflist([], 'f')
4574 edit Xerr
4575 exe "caddbuffer"
4576 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4577
4578 " :cfile
4579 exe "cfile Xerr"
4580 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4581
4582 " :cgetfile
4583 exe "cgetfile Xerr"
4584 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4585
4586 " :caddfile
4587 call setqflist([], 'f')
4588 exe "caddfile Xerr"
4589 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4590
4591 " :grep
4592 set grepprg=internal
4593 exe "grep F1 Xerr"
4594 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4595
4596 " :grepadd
4597 call setqflist([], 'f')
4598 exe "grepadd F1 Xerr"
4599 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4600 set grepprg&vim
4601
4602 " :vimgrep
4603 exe "vimgrep F1 Xerr"
4604 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4605
4606 " :vimgrepadd
4607 call setqflist([], 'f')
4608 exe "vimgrepadd F1 Xerr"
4609 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4610
4611 call setqflist(['F1:10:L10'], ' ')
4612 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4613
4614 call setqflist([], 'f')
4615 call setqflist(['F1:10:L10'], 'a')
4616 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4617
4618 call setqflist([], 'f')
4619 call setqflist(['F1:10:L10'], 'r')
4620 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4621
4622 close
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004623
4624 call setqflist([], ' ', {'title' : 'Errors'})
4625 copen
4626 call assert_equal('Errors', w:quickfix_title)
4627 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4628 call assert_equal('Errors', w:quickfix_title)
4629 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004630
4631 " Switching to another quickfix list in one tab page should update the
4632 " quickfix window title and statusline in all the other tab pages also
4633 call setqflist([], 'f')
4634 %bw!
4635 cgetexpr ['file_one:1:1: error in the first quickfix list']
4636 call setqflist([], 'a', {'title': 'first quickfix list'})
4637 cgetexpr ['file_two:2:1: error in the second quickfix list']
4638 call setqflist([], 'a', {'title': 'second quickfix list'})
4639 copen
4640 wincmd t
4641 tabnew two
4642 copen
4643 wincmd t
4644 colder
4645 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4646 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4647 call assert_equal(1, tabpagewinnr(1))
4648 call assert_equal(1, tabpagewinnr(2))
4649 tabnew
4650 call setqflist([], 'a', {'title': 'new quickfix title'})
4651 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4652 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4653 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004654endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004655
4656func Test_lbuffer_with_bwipe()
4657 new
4658 new
4659 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004660 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004661 augroup END
4662 lbuffer
4663 augroup nasty
4664 au!
4665 augroup END
4666endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004667
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004668" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4669" running
4670func Xexpr_acmd_freelist(cchar)
4671 call s:setup_commands(a:cchar)
4672
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004673 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004674 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004675 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004676 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004677 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004678 augroup nasty
4679 au!
4680 augroup END
4681endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004682
4683func Test_cexpr_acmd_freelist()
4684 call Xexpr_acmd_freelist('c')
4685 call Xexpr_acmd_freelist('l')
4686endfunc
4687
4688" Test for commands that create a new quickfix/location list and jump to the
4689" first error automatically.
4690func Xjumpto_first_error_test(cchar)
4691 call s:setup_commands(a:cchar)
4692
4693 call s:create_test_file('Xtestfile1')
4694 call s:create_test_file('Xtestfile2')
4695 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4696
4697 " Test for cexpr/lexpr
4698 enew
4699 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004700 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004701 call assert_equal(2, line('.'))
4702
4703 " Test for cfile/lfile
4704 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004705 call writefile(l, 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004706 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004707 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004708 call assert_equal(2, line('.'))
4709
4710 " Test for cbuffer/lbuffer
4711 edit Xerr
4712 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004713 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004714 call assert_equal(2, line('.'))
4715
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004716 call delete('Xtestfile1')
4717 call delete('Xtestfile2')
4718endfunc
4719
4720func Test_jumpto_first_error()
4721 call Xjumpto_first_error_test('c')
4722 call Xjumpto_first_error_test('l')
4723endfunc
4724
4725" Test for a quickfix autocmd changing the quickfix/location list before
4726" jumping to the first error in the new list.
4727func Xautocmd_changelist(cchar)
4728 call s:setup_commands(a:cchar)
4729
4730 " Test for cfile/lfile
4731 call s:create_test_file('Xtestfile1')
4732 call s:create_test_file('Xtestfile2')
4733 Xexpr 'Xtestfile1:2:Line2'
4734 autocmd QuickFixCmdPost * Xolder
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004735 call writefile(['Xtestfile2:4:Line4'], 'Xerr', 'D')
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004736 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004737 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004738 call assert_equal(4, line('.'))
4739 autocmd! QuickFixCmdPost
4740
4741 " Test for cbuffer/lbuffer
4742 call g:Xsetlist([], 'f')
4743 Xexpr 'Xtestfile1:2:Line2'
4744 autocmd QuickFixCmdPost * Xolder
4745 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4746 edit Xerr
4747 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004748 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004749 call assert_equal(4, line('.'))
4750 autocmd! QuickFixCmdPost
4751
4752 " Test for cexpr/lexpr
4753 call g:Xsetlist([], 'f')
4754 Xexpr 'Xtestfile1:2:Line2'
4755 autocmd QuickFixCmdPost * Xolder
4756 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004757 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004758 call assert_equal(4, line('.'))
4759 autocmd! QuickFixCmdPost
4760
Bram Moolenaar851332e2018-07-03 19:16:00 +02004761 " The grepprg may not be set on non-Unix systems
4762 if has('unix')
4763 " Test for grep/lgrep
4764 call g:Xsetlist([], 'f')
4765 Xexpr 'Xtestfile1:2:Line2'
4766 autocmd QuickFixCmdPost * Xolder
4767 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004768 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004769 call assert_equal(5, line('.'))
4770 autocmd! QuickFixCmdPost
4771 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004772
4773 " Test for vimgrep/lvimgrep
4774 call g:Xsetlist([], 'f')
4775 Xexpr 'Xtestfile1:2:Line2'
4776 autocmd QuickFixCmdPost * Xolder
4777 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004778 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004779 call assert_equal(5, line('.'))
4780 autocmd! QuickFixCmdPost
4781
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004782 " Test for autocommands clearing the quickfix list before jumping to the
4783 " first error. This should not result in an error
4784 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4785 let v:errmsg = ''
4786 " Test for cfile/lfile
4787 Xfile Xerr
4788 call assert_true(v:errmsg !~# 'E42:')
4789 " Test for cbuffer/lbuffer
4790 edit Xerr
4791 Xbuffer
4792 call assert_true(v:errmsg !~# 'E42:')
4793 " Test for cexpr/lexpr
4794 Xexpr 'Xtestfile2:4:Line4'
4795 call assert_true(v:errmsg !~# 'E42:')
4796 " Test for grep/lgrep
4797 " The grepprg may not be set on non-Unix systems
4798 if has('unix')
4799 silent Xgrep Line5 Xtestfile2
4800 call assert_true(v:errmsg !~# 'E42:')
4801 endif
4802 " Test for vimgrep/lvimgrep
4803 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4804 autocmd! QuickFixCmdPost
4805
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004806 call delete('Xtestfile1')
4807 call delete('Xtestfile2')
4808endfunc
4809
4810func Test_autocmd_changelist()
4811 call Xautocmd_changelist('c')
4812 call Xautocmd_changelist('l')
4813endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004814
4815" Tests for the ':filter /pat/ clist' command
4816func Test_filter_clist()
4817 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4818 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4819 \ split(execute('filter /Line 15/ clist'), "\n"))
4820 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4821 \ split(execute('filter /Xfile1/ clist'), "\n"))
4822 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4823
4824 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4825 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4826 call assert_equal([' 2 pqr:pat2: '],
4827 \ split(execute('filter /pqr/ clist'), "\n"))
4828 call assert_equal([' 1 abc:pat1: '],
4829 \ split(execute('filter /pat1/ clist'), "\n"))
4830endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004831
4832" Tests for the "CTRL-W <CR>" command.
4833func Xview_result_split_tests(cchar)
4834 call s:setup_commands(a:cchar)
4835
4836 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4837 call g:Xsetlist([])
4838 Xopen
4839 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004840 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004841 call assert_equal(l:win_count, winnr('$'))
4842 Xclose
4843endfunc
4844
4845func Test_view_result_split()
4846 call Xview_result_split_tests('c')
4847 call Xview_result_split_tests('l')
4848endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004849
4850" Test that :cc sets curswant
4851func Test_curswant()
4852 helpgrep quickfix
4853 normal! llll
4854 1cc
4855 call assert_equal(getcurpos()[4], virtcol('.'))
4856 cclose | helpclose
4857endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004858
4859" Test for opening a file from the quickfix window using CTRL-W <Enter>
4860" doesn't leave an empty buffer around.
4861func Test_splitview()
4862 call s:create_test_file('Xtestfile1')
4863 call s:create_test_file('Xtestfile2')
4864 new | only
4865 let last_bufnr = bufnr('Test_sv_1', 1)
4866 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4867 cgetexpr l
4868 copen
4869 let numbufs = len(getbufinfo())
4870 exe "normal \<C-W>\<CR>"
4871 copen
4872 exe "normal j\<C-W>\<CR>"
4873 " Make sure new empty buffers are not created
4874 call assert_equal(numbufs, len(getbufinfo()))
4875 " Creating a new buffer should use the next available buffer number
4876 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4877 bwipe Test_sv_1
4878 bwipe Test_sv_2
4879 new | only
4880
4881 " When split opening files from location list window, make sure that two
4882 " windows doesn't refer to the same location list
4883 lgetexpr l
4884 let locid = getloclist(0, {'id' : 0}).id
4885 lopen
4886 exe "normal \<C-W>\<CR>"
4887 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4888 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4889 new | only
4890
4891 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004892 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004893 lhelpgrep window
4894 let locid = getloclist(0, {'id' : 0}).id
4895 lwindow
4896 exe "normal j\<C-W>\<CR>"
4897 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4898 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4899 new | only
4900
Bram Moolenaar406cd902020-02-18 21:54:41 +01004901 " Using :split or :vsplit from a quickfix window should behave like a :new
4902 " or a :vnew command
4903 copen
4904 split
4905 call assert_equal(3, winnr('$'))
4906 let l = getwininfo()
4907 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4908 close
4909 copen
4910 vsplit
4911 let l = getwininfo()
4912 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4913 new | only
4914
Bram Moolenaarb2443732018-11-11 22:50:27 +01004915 call delete('Xtestfile1')
4916 call delete('Xtestfile2')
4917endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004918
4919" Test for parsing entries using visual screen column
4920func Test_viscol()
4921 enew
Bram Moolenaardb77cb32022-10-05 21:45:30 +01004922 call writefile(["Col1\tCol2\tCol3"], 'Xfile1', 'D')
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004923 edit Xfile1
4924
4925 " Use byte offset for column number
4926 set efm&
4927 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4928 call assert_equal([5, 8], [col('.'), virtcol('.')])
4929 cnext
4930 call assert_equal([9, 12], [col('.'), virtcol('.')])
4931 cnext
4932 call assert_equal([14, 20], [col('.'), virtcol('.')])
4933
4934 " Use screen column offset for column number
4935 set efm=%f:%l:%v:%m
4936 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4937 call assert_equal([5, 8], [col('.'), virtcol('.')])
4938 cnext
4939 call assert_equal([9, 12], [col('.'), virtcol('.')])
4940 cnext
4941 call assert_equal([14, 20], [col('.'), virtcol('.')])
4942 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4943 call assert_equal([5, 8], [col('.'), virtcol('.')])
4944 cnext
4945 call assert_equal([10, 16], [col('.'), virtcol('.')])
4946 cnext
4947 call assert_equal([14, 20], [col('.'), virtcol('.')])
4948
4949 enew
4950 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4951
4952 " Use byte offset for column number
4953 set efm&
4954 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4955 call assert_equal([8, 10], [col('.'), virtcol('.')])
4956 cnext
4957 call assert_equal([11, 17], [col('.'), virtcol('.')])
4958 cnext
4959 call assert_equal([16, 25], [col('.'), virtcol('.')])
4960
4961 " Use screen column offset for column number
4962 set efm=%f:%l:%v:%m
4963 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4964 call assert_equal([8, 10], [col('.'), virtcol('.')])
4965 cnext
4966 call assert_equal([11, 17], [col('.'), virtcol('.')])
4967 cnext
4968 call assert_equal([16, 25], [col('.'), virtcol('.')])
4969
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004970 " Use screen column number with a multi-line error message
4971 enew
4972 call writefile(["à test"], 'Xfile1')
4973 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4974 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4975 call assert_equal('Xfile1', @%)
4976 call assert_equal([0, 1, 4, 0], getpos('.'))
4977
4978 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4979 " does not break this
4980 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4981 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4982 call assert_equal('Xfile1', @%)
4983 call assert_equal([0, 1, 3, 0], getpos('.'))
4984
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004985 enew | only
4986 set efm&
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004987endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004988
4989" Test for the quickfix window buffer
4990func Xqfbuf_test(cchar)
4991 call s:setup_commands(a:cchar)
4992
4993 " Quickfix buffer should be reused across closing and opening a quickfix
4994 " window
4995 Xexpr "F1:10:Line10"
4996 Xopen
4997 let qfbnum = bufnr('')
4998 Xclose
4999 " Even after the quickfix window is closed, the buffer should be loaded
5000 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005001 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005002 Xopen
5003 " Buffer should be reused when opening the window again
5004 call assert_equal(qfbnum, bufnr(''))
5005 Xclose
5006
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00005007 " When quickfix buffer is wiped out, getqflist() should return 0
5008 %bw!
5009 Xexpr ""
5010 Xopen
5011 bw!
5012 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
5013
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005014 if a:cchar == 'l'
5015 %bwipe
5016 " For a location list, when both the file window and the location list
5017 " window for the list are closed, then the buffer should be freed.
5018 new | only
5019 lexpr "F1:10:Line10"
5020 let wid = win_getid()
5021 lopen
5022 let qfbnum = bufnr('')
5023 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
5024 close
5025 " When the location list window is closed, the buffer name should not
5026 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005027 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005028 call assert_true(bufloaded(qfbnum))
5029
Bram Moolenaard82a81c2019-03-02 07:57:18 +01005030 " After deleting a location list buffer using ":bdelete", opening the
5031 " location list window should mark the buffer as a location list buffer.
5032 exe "bdelete " . qfbnum
5033 lopen
5034 call assert_equal("quickfix", &buftype)
5035 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
5036 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
5037 call assert_false(&swapfile)
5038 lclose
5039
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005040 " When the location list is cleared for the window, the buffer should be
5041 " removed
5042 call setloclist(0, [], 'f')
5043 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01005044 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005045
5046 " When the location list is freed with the location list window open, the
5047 " location list buffer should not be lost. It should be reused when the
5048 " location list is again populated.
5049 lexpr "F1:10:Line10"
5050 lopen
5051 let wid = win_getid()
5052 let qfbnum = bufnr('')
5053 wincmd p
5054 call setloclist(0, [], 'f')
5055 lexpr "F1:10:Line10"
5056 lopen
5057 call assert_equal(wid, win_getid())
5058 call assert_equal(qfbnum, bufnr(''))
5059 lclose
5060
5061 " When the window with the location list is closed, the buffer should be
5062 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005063 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005064 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01005065 endif
5066endfunc
5067
5068func Test_qfbuf()
5069 call Xqfbuf_test('c')
5070 call Xqfbuf_test('l')
5071endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005072
5073" If there is an autocmd to use only one window, then opening the location
5074" list window used to crash Vim.
5075func Test_winonly_autocmd()
5076 call s:create_test_file('Xtest1')
5077 " Autocmd to show only one Vim window at a time
5078 autocmd WinEnter * only
5079 new
5080 " Load the location list
5081 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
5082 let loclistid = getloclist(0, {'id' : 0}).id
5083 " Open the location list window. Only this window will be shown and the file
5084 " window is closed.
5085 lopen
5086 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
5087 " Jump to an entry in the location list and make sure that the cursor is
5088 " positioned correctly.
5089 ll 3
5090 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005091 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01005092 call assert_equal(15, line('.'))
5093 " Cleanup
5094 autocmd! WinEnter
5095 new | only
5096 call delete('Xtest1')
5097endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02005098
5099" Test to make sure that an empty quickfix buffer is not reused for loading
5100" a normal buffer.
5101func Test_empty_qfbuf()
5102 enew | only
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005103 call writefile(["Test"], 'Xfile1', 'D')
Bram Moolenaar39803d82019-04-07 12:04:51 +02005104 call setqflist([], 'f')
5105 copen | only
5106 let qfbuf = bufnr('')
5107 edit Xfile1
5108 call assert_notequal(qfbuf, bufnr(''))
5109 enew
Bram Moolenaar39803d82019-04-07 12:04:51 +02005110endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005111
5112" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005113" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005114func Xtest_below(cchar)
5115 call s:setup_commands(a:cchar)
5116
5117 " No quickfix/location list
5118 call assert_fails('Xbelow', 'E42:')
5119 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005120 call assert_fails('Xbefore', 'E42:')
5121 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005122
5123 " Empty quickfix/location list
5124 call g:Xsetlist([])
5125 call assert_fails('Xbelow', 'E42:')
5126 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005127 call assert_fails('Xbefore', 'E42:')
5128 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005129
5130 call s:create_test_file('X1')
5131 call s:create_test_file('X2')
5132 call s:create_test_file('X3')
5133 call s:create_test_file('X4')
5134
5135 " Invalid entries
5136 edit X1
5137 call g:Xsetlist(["E1", "E2"])
5138 call assert_fails('Xbelow', 'E42:')
5139 call assert_fails('Xabove', 'E42:')
5140 call assert_fails('3Xbelow', 'E42:')
5141 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005142 call assert_fails('Xbefore', 'E42:')
5143 call assert_fails('Xafter', 'E42:')
5144 call assert_fails('3Xbefore', 'E42:')
5145 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005146
5147 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005148 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 +02005149 edit +7 X2
5150 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005151 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005152 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005153 normal 7G
5154 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005155 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005156 call assert_fails('Xbefore', 'E553:')
5157
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005158 normal 2j
5159 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005160 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005161 normal 7G
5162 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005163 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005164
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005165 " Last error in this file
5166 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005167 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005168 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005169 normal gg
5170 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005171 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005172 call assert_fails('Xafter', 'E553:')
5173
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005174 " First error in this file
5175 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005176 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005177 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005178 normal G
5179 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005180 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005181 call assert_fails('Xbefore', 'E553:')
5182
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005183 normal gg
5184 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005185 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005186 normal gg
5187 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005188 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005189
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005190 normal G
5191 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005192 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005193 normal G
5194 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005195 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005196
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005197 edit X4
5198 call assert_fails('Xabove', 'E42:')
5199 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005200 call assert_fails('Xbefore', 'E42:')
5201 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005202 if a:cchar == 'l'
5203 " If a buffer has location list entries from some other window but not
5204 " from the current window, then the commands should fail.
5205 edit X1 | split | call setloclist(0, [], 'f')
5206 call assert_fails('Xabove', 'E776:')
5207 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005208 call assert_fails('Xbefore', 'E776:')
5209 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005210 close
5211 endif
5212
5213 " Test for lines with multiple quickfix entries
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005214 let lines =<< trim END
5215 X1:5:L5
5216 X2:5:1:L5_1
5217 X2:5:2:L5_2
5218 X2:5:3:L5_3
5219 X2:10:1:L10_1
5220 X2:10:2:L10_2
5221 X2:10:3:L10_3
5222 X2:15:1:L15_1
5223 X2:15:2:L15_2
5224 X2:15:3:L15_3
5225 X3:3:L3
5226 END
5227 Xexpr lines
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005228 edit +1 X2
5229 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005230 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005231 normal 1G
5232 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005233 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005234
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005235 normal gg
5236 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005237 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005238 normal gg
5239 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005240 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005241
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005242 normal G
5243 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005244 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005245 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005246 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005247 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005248
5249 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005250 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005251 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005252 normal G
5253 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005254 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005255
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005256 normal 10G
5257 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005258 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005259 normal 10G$
5260 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005261 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005262
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005263 normal 10G
5264 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005265 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005266 normal 9G
5267 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005268 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005269
5270 " Invalid range
5271 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005272 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005273 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005274 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005275 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005276 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005277 endif
5278
5279 call delete('X1')
5280 call delete('X2')
5281 call delete('X3')
5282 call delete('X4')
5283endfunc
5284
5285func Test_cbelow()
5286 call Xtest_below('c')
5287 call Xtest_below('l')
5288endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005289
5290func Test_quickfix_count()
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01005291 let commands =<< trim END
5292 cNext
5293 cNfile
5294 cabove
5295 cbelow
5296 cfirst
5297 clast
5298 cnewer
5299 cnext
5300 cnfile
5301 colder
5302 cprevious
5303 crewind
5304 lNext
5305 lNfile
5306 labove
5307 lbelow
5308 lfirst
5309 llast
5310 lnewer
5311 lnext
5312 lnfile
5313 lolder
5314 lprevious
5315 lrewind
5316 END
Bram Moolenaar25190db2019-05-04 15:05:28 +02005317 for cmd in commands
5318 call assert_fails('-1' .. cmd, 'E16:')
5319 call assert_fails('.' .. cmd, 'E16:')
5320 call assert_fails('%' .. cmd, 'E16:')
5321 call assert_fails('$' .. cmd, 'E16:')
5322 endfor
5323endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005324
5325" Test for aborting quickfix commands using QuickFixCmdPre
5326func Xtest_qfcmd_abort(cchar)
5327 call s:setup_commands(a:cchar)
5328
5329 call g:Xsetlist([], 'f')
5330
5331 " cexpr/lexpr
5332 let e = ''
5333 try
5334 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5335 catch /.*/
5336 let e = v:exception
5337 endtry
5338 call assert_equal('AbortCmd', e)
5339 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5340
5341 " cfile/lfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005342 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1', 'D')
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005343 let e = ''
5344 try
5345 Xfile Xfile1
5346 catch /.*/
5347 let e = v:exception
5348 endtry
5349 call assert_equal('AbortCmd', e)
5350 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005351
5352 " cgetbuffer/lgetbuffer
5353 enew!
5354 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5355 let e = ''
5356 try
5357 Xgetbuffer
5358 catch /.*/
5359 let e = v:exception
5360 endtry
5361 call assert_equal('AbortCmd', e)
5362 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5363 enew!
5364
5365 " vimgrep/lvimgrep
5366 let e = ''
5367 try
5368 Xvimgrep /func/ test_quickfix.vim
5369 catch /.*/
5370 let e = v:exception
5371 endtry
5372 call assert_equal('AbortCmd', e)
5373 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5374
5375 " helpgrep/lhelpgrep
5376 let e = ''
5377 try
5378 Xhelpgrep quickfix
5379 catch /.*/
5380 let e = v:exception
5381 endtry
5382 call assert_equal('AbortCmd', e)
5383 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5384
5385 " grep/lgrep
5386 if has('unix')
5387 let e = ''
5388 try
5389 silent Xgrep func test_quickfix.vim
5390 catch /.*/
5391 let e = v:exception
5392 endtry
5393 call assert_equal('AbortCmd', e)
5394 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5395 endif
5396endfunc
5397
5398func Test_qfcmd_abort()
5399 augroup QF_Test
5400 au!
5401 autocmd QuickFixCmdPre * throw "AbortCmd"
5402 augroup END
5403
5404 call Xtest_qfcmd_abort('c')
5405 call Xtest_qfcmd_abort('l')
5406
5407 augroup QF_Test
5408 au!
5409 augroup END
5410endfunc
5411
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005412" Test for using a file in one of the parent directories.
5413func Test_search_in_dirstack()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005414 call mkdir('Xtestdir/a/b/c', 'pR')
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005415 let save_cwd = getcwd()
5416 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5417 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5418 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5419 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5420
5421 let lines = "Entering dir Xtestdir\n" .
5422 \ "Entering dir a\n" .
5423 \ "Entering dir b\n" .
5424 \ "Xfile2:2:X2_L2\n" .
5425 \ "Leaving dir a\n" .
5426 \ "Xfile1:2:X1_L2\n" .
5427 \ "Xfile3:1:X3_L1\n" .
5428 \ "Entering dir c\n" .
5429 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005430 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005431 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005432 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005433 call assert_equal(11, getqflist({'size' : 0}).size)
5434 call assert_equal(4, getqflist({'idx' : 0}).idx)
5435 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005436 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005437 cnext
5438 call assert_equal(6, getqflist({'idx' : 0}).idx)
5439 call assert_equal('X1_L2', getline('.'))
5440 cnext
5441 call assert_equal(7, getqflist({'idx' : 0}).idx)
5442 call assert_equal(1, line('$'))
5443 call assert_equal('', getline(1))
5444 cnext
5445 call assert_equal(9, getqflist({'idx' : 0}).idx)
5446 call assert_equal(1, line('$'))
5447 call assert_equal('', getline(1))
5448
5449 set efm&
5450 exe 'cd ' . save_cwd
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005451endfunc
5452
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005453" Test for :cquit
5454func Test_cquit()
5455 " Exit Vim with a non-zero value
5456 if RunVim([], ["cquit 7"], '')
5457 call assert_equal(7, v:shell_error)
5458 endif
5459
5460 if RunVim([], ["50cquit"], '')
5461 call assert_equal(50, v:shell_error)
5462 endif
5463
5464 " Exit Vim with default value
5465 if RunVim([], ["cquit"], '')
5466 call assert_equal(1, v:shell_error)
5467 endif
5468
5469 " Exit Vim with zero value
5470 if RunVim([], ["cquit 0"], '')
5471 call assert_equal(0, v:shell_error)
5472 endif
5473
5474 " Exit Vim with negative value
5475 call assert_fails('-3cquit', 'E16:')
5476endfunc
5477
Bram Moolenaar858ba062020-05-31 23:11:59 +02005478" Test for getting a specific item from a quickfix list
5479func Xtest_getqflist_by_idx(cchar)
5480 call s:setup_commands(a:cchar)
5481 " Empty list
5482 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5483 Xexpr ['F1:10:L10', 'F1:20:L20']
5484 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5485 call assert_equal(bufnr('F1'), l[0].bufnr)
5486 call assert_equal(20, l[0].lnum)
5487 call assert_equal('L20', l[0].text)
5488 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5489 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005490 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005491 %bwipe!
5492endfunc
5493
5494func Test_getqflist_by_idx()
5495 call Xtest_getqflist_by_idx('c')
5496 call Xtest_getqflist_by_idx('l')
5497endfunc
5498
5499" Test for the 'quickfixtextfunc' setting
5500func Tqfexpr(info)
5501 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005502 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005503 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005504 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005505 endif
5506
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005507 let l = []
5508 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5509 let e = qfl[idx]
5510 let s = ''
5511 if e.bufnr != 0
5512 let bname = bufname(e.bufnr)
5513 let s ..= fnamemodify(bname, ':.')
5514 endif
5515 let s ..= '-'
5516 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5517 let s ..= e.text
5518 call add(l, s)
5519 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005520
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005521 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005522endfunc
5523
5524func Xtest_qftextfunc(cchar)
5525 call s:setup_commands(a:cchar)
5526
5527 set efm=%f:%l:%c:%m
5528 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005529 call assert_equal('Tqfexpr', &quickfixtextfunc)
5530 call assert_equal('',
5531 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005532 call g:Xsetlist([
5533 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5534 \ 'end_col': 7, 'text': 'green'},
5535 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5536 \ 'end_col': 8, 'text': 'blue'},
5537 \ ])
5538
Bram Moolenaar858ba062020-05-31 23:11:59 +02005539 Xwindow
5540 call assert_equal('F1-L10C2-green', getline(1))
5541 call assert_equal('F1-L20C4-blue', getline(2))
5542 Xclose
5543 set quickfixtextfunc&vim
5544 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005545 call assert_equal('F1|10 col 2-7| green', getline(1))
5546 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005547 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005548
5549 set efm=%f:%l:%c:%m
5550 set quickfixtextfunc=Tqfexpr
5551 " Update the list with only the cwindow
5552 Xwindow
5553 only
5554 call g:Xsetlist([
5555 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5556 \ 'end_col': 7, 'text': 'red'}
5557 \ ])
5558 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5559 new
5560 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005561 set efm&
5562 set quickfixtextfunc&
5563
5564 " Test for per list 'quickfixtextfunc' setting
5565 func PerQfText(info)
5566 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005567 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005568 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005569 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005570 endif
5571 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005572 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005573 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005574 let l = []
5575 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5576 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5577 endfor
5578 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005579 endfunc
5580 set quickfixtextfunc=Tqfexpr
5581 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5582 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5583 Xwindow
5584 call assert_equal('Line 10, Col 2', getline(1))
5585 call assert_equal('Line 20, Col 4', getline(2))
5586 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005587 call assert_equal(function('PerQfText'),
5588 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005589 " Add entries to the list when the quickfix buffer is hidden
5590 Xaddexpr ['F1:30:6:red']
5591 Xwindow
5592 call assert_equal('Line 30, Col 6', getline(3))
5593 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005594 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005595 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005596 set quickfixtextfunc&
5597 delfunc PerQfText
5598
5599 " Non-existing function
5600 set quickfixtextfunc=Tabc
5601 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5602 call assert_fails("Xwindow", 'E117:')
5603 Xclose
5604 set quickfixtextfunc&
5605
5606 " set option to a non-function
5607 set quickfixtextfunc=[10,\ 20]
5608 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5609 call assert_fails("Xwindow", 'E117:')
5610 Xclose
5611 set quickfixtextfunc&
5612
5613 " set option to a function with different set of arguments
5614 func Xqftext(a, b, c)
5615 return a:a .. a:b .. a:c
5616 endfunc
5617 set quickfixtextfunc=Xqftext
5618 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5619 call assert_fails("Xwindow", 'E119:')
5620 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005621
5622 " set option to a function that returns a list with non-strings
5623 func Xqftext2(d)
5624 return ['one', [], 'two']
5625 endfunc
5626 set quickfixtextfunc=Xqftext2
5627 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5628 \ 'E730:')
5629 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005630 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5631 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005632 Xclose
5633
Bram Moolenaar858ba062020-05-31 23:11:59 +02005634 set quickfixtextfunc&
5635 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005636 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005637
5638 " set the global option to a lambda function
5639 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5640 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5641 Xwindow
5642 call assert_equal(['green', 'blue'], getline(1, '$'))
5643 Xclose
5644 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)
5645 set quickfixtextfunc&
5646
5647 " use a lambda function that returns an empty list
5648 set quickfixtextfunc={d\ ->\ []}
5649 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5650 Xwindow
5651 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5652 \ getline(1, '$'))
5653 Xclose
5654 set quickfixtextfunc&
5655
5656 " use a lambda function that returns a list with empty strings
5657 set quickfixtextfunc={d\ ->\ ['',\ '']}
5658 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5659 Xwindow
5660 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5661 \ getline(1, '$'))
5662 Xclose
5663 set quickfixtextfunc&
5664
5665 " set the per-quickfix list text function to a lambda function
5666 call g:Xsetlist([], ' ',
5667 \ {'quickfixtextfunc' :
5668 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5669 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5670 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5671 Xwindow
5672 call assert_equal('Line 10, Col 2', getline(1))
5673 call assert_equal('Line 20, Col 4', getline(2))
5674 Xclose
5675 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5676 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005677endfunc
5678
5679func Test_qftextfunc()
5680 call Xtest_qftextfunc('c')
5681 call Xtest_qftextfunc('l')
5682endfunc
5683
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005684func Test_qftextfunc_callback()
5685 let lines =<< trim END
5686 set efm=%f:%l:%c:%m
5687
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005688 #" Test for using a function name
5689 LET &qftf = 'g:Tqfexpr'
5690 cexpr "F0:0:0:L0"
5691 copen
5692 call assert_equal('F0-L0C0-L0', getline(1))
5693 cclose
5694
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005695 #" Test for using a function()
5696 set qftf=function('g:Tqfexpr')
5697 cexpr "F1:1:1:L1"
5698 copen
5699 call assert_equal('F1-L1C1-L1', getline(1))
5700 cclose
5701
5702 #" Using a funcref variable to set 'quickfixtextfunc'
5703 VAR Fn = function('g:Tqfexpr')
5704 LET &qftf = Fn
5705 cexpr "F2:2:2:L2"
5706 copen
5707 call assert_equal('F2-L2C2-L2', getline(1))
5708 cclose
5709
5710 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5711 LET Fn = function('g:Tqfexpr')
5712 LET &qftf = string(Fn)
5713 cexpr "F3:3:3:L3"
5714 copen
5715 call assert_equal('F3-L3C3-L3', getline(1))
5716 cclose
5717
5718 #" Test for using a funcref()
5719 set qftf=funcref('g:Tqfexpr')
5720 cexpr "F4:4:4:L4"
5721 copen
5722 call assert_equal('F4-L4C4-L4', getline(1))
5723 cclose
5724
5725 #" Using a funcref variable to set 'quickfixtextfunc'
5726 LET Fn = funcref('g:Tqfexpr')
5727 LET &qftf = Fn
5728 cexpr "F5:5:5:L5"
5729 copen
5730 call assert_equal('F5-L5C5-L5', getline(1))
5731 cclose
5732
5733 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5734 LET Fn = funcref('g:Tqfexpr')
5735 LET &qftf = string(Fn)
5736 cexpr "F5:5:5:L5"
5737 copen
5738 call assert_equal('F5-L5C5-L5', getline(1))
5739 cclose
5740
5741 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005742 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005743 LET optval = substitute(optval, ' ', '\\ ', 'g')
5744 exe "set qftf=" .. optval
5745 cexpr "F6:6:6:L6"
5746 copen
5747 call assert_equal('F6-L6C6-L6', getline(1))
5748 cclose
5749
5750 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005751 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005752 cexpr "F7:7:7:L7"
5753 copen
5754 call assert_equal('F7-L7C7-L7', getline(1))
5755 cclose
5756
5757 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005758 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005759 cexpr "F8:8:8:L8"
5760 copen
5761 call assert_equal('F8-L8C8-L8', getline(1))
5762 cclose
5763
5764 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005765 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005766 LET &qftf = Lambda
5767 cexpr "F9:9:9:L9"
5768 copen
5769 call assert_equal('F9-L9C9-L9', getline(1))
5770 cclose
5771
5772 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005773 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005774 LET &qftf = string(Lambda)
5775 cexpr "F9:9:9:L9"
5776 copen
5777 call assert_equal('F9-L9C9-L9', getline(1))
5778 cclose
5779 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005780 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005781
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005782 " Test for using a script-local function name
5783 func s:TqfFunc2(info)
5784 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5785 return ''
5786 endfunc
5787 let g:TqfFunc2Args = []
5788 set quickfixtextfunc=s:TqfFunc2
5789 cexpr "F10:10:10:L10"
5790 cclose
5791 call assert_equal([1, 1], g:TqfFunc2Args)
5792
5793 let &quickfixtextfunc = 's:TqfFunc2'
5794 cexpr "F11:11:11:L11"
5795 cclose
5796 call assert_equal([1, 1], g:TqfFunc2Args)
5797 delfunc s:TqfFunc2
5798
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005799 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5800 func SetQftfFunc()
5801 let params = {'qftf': function('g:DictQftfFunc')}
5802 let &quickfixtextfunc = params.qftf
5803 endfunc
5804 func g:DictQftfFunc(_) dict
5805 endfunc
5806 call SetQftfFunc()
5807 new
5808 call SetQftfFunc()
5809 bw
5810 call test_garbagecollect_now()
5811 new
5812 set qftf=
5813 wincmd w
5814 set qftf=
5815 :%bw!
5816
5817 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5818 " to cause a crash.
5819 let &qftf = ''
5820 func SetLocalQftfFunc()
5821 let params = {'qftf': function('g:DictQftfFunc')}
5822 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5823 endfunc
5824 call SetLocalQftfFunc()
5825 call test_garbagecollect_now()
5826 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5827 delfunc g:DictQftfFunc
5828 delfunc SetQftfFunc
5829 delfunc SetLocalQftfFunc
5830 set efm&
5831endfunc
5832
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005833" Test for updating a location list for some other window and check that
5834" 'qftextfunc' uses the correct location list.
5835func Test_qftextfunc_other_loclist()
5836 %bw!
5837 call setloclist(0, [], 'f')
5838
5839 " create a window and a location list for it and open the location list
5840 " window
5841 lexpr ['F1:10:12:one', 'F1:20:14:two']
5842 let w1_id = win_getid()
5843 call setloclist(0, [], ' ',
5844 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5845 \ 'quickfixtextfunc':
5846 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5847 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5848 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5849 lwindow
5850 let w2_id = win_getid()
5851
5852 " create another window and a location list for it and open the location
5853 " list window
5854 topleft new
5855 let w3_id = win_getid()
5856 call setloclist(0, [], ' ',
5857 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5858 \ 'quickfixtextfunc':
5859 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5860 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5861 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5862 lwindow
5863 let w4_id = win_getid()
5864
5865 topleft new
5866 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5867 let w5_id = win_getid()
5868
5869 " change the location list for some other window
5870 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5871 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5872 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5873 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5874 \ getbufline(winbufnr(w2_id), 1, '$'))
5875 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5876 \ getbufline(winbufnr(w4_id), 1, '$'))
5877 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5878 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5879 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5880 \ getbufline(winbufnr(w2_id), 1, '$'))
5881 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5882 \ getbufline(winbufnr(w4_id), 1, '$'))
5883
5884 call win_gotoid(w5_id)
5885 lwindow
5886 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5887 \ getline(1, '$'))
5888 %bw!
5889endfunc
5890
Bram Moolenaarec98e932020-06-08 19:35:59 +02005891" Running :lhelpgrep command more than once in a help window, doesn't jump to
5892" the help topic
5893func Test_lhelpgrep_from_help_window()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005894 call mkdir('Xtestdir/doc', 'pR')
Bram Moolenaarec98e932020-06-08 19:35:59 +02005895 call writefile(['window'], 'Xtestdir/doc/a.txt')
5896 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5897 let save_rtp = &rtp
5898 let &rtp = 'Xtestdir'
5899 lhelpgrep window
5900 lhelpgrep buffer
5901 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5902 lhelpgrep window
5903 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5904 let &rtp = save_rtp
Bram Moolenaarec98e932020-06-08 19:35:59 +02005905 new | only!
5906endfunc
5907
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005908" Test for the crash fixed by 7.3.715
5909func Test_setloclist_crash()
5910 %bw!
5911 let g:BufNum = bufnr()
5912 augroup QF_Test
5913 au!
5914 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5915 augroup END
5916
5917 try
5918 lvimgrep /.*/ *.mak
5919 catch /E926:/
5920 endtry
5921 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5922 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5923
5924 augroup QF_Test
5925 au!
5926 augroup END
5927 unlet g:BufNum
5928 %bw!
5929endfunc
5930
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005931" Test for adding an invalid entry with the quickfix window open and making
5932" sure that the window contents are not changed
5933func Test_add_invalid_entry_with_qf_window()
5934 call setqflist([], 'f')
5935 cexpr "Xfile1:10:aa"
5936 copen
5937 call setqflist(['bb'], 'a')
5938 call assert_equal(1, line('$'))
5939 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005940 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5941
5942 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5943 call assert_equal(1 , line('$'))
5944 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5945 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5946
5947 call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5948 call assert_equal(1 , line('$'))
5949 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5950 call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5951
5952 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5953 call assert_equal(1 , line('$'))
5954 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5955 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())
5956
5957 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')
5958 call assert_equal(1 , line('$'))
5959 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5960 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5961
5962 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5963 call assert_equal(1 , line('$'))
5964 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5965 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())
5966
5967 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')
5968 call assert_equal(1 , line('$'))
5969 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5970 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())
5971
5972 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')
5973 call assert_equal(1 , line('$'))
5974 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5975 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 +01005976 cclose
5977endfunc
5978
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005979" Test for very weird problem: autocommand causes a failure, resulting opening
5980" the quickfix window to fail. This still splits the window, but otherwise
5981" should not mess up buffers.
5982func Test_quickfix_window_fails_to_open()
5983 CheckScreendump
5984
5985 let lines =<< trim END
5986 anything
5987 try
5988 anything
5989 endtry
5990 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01005991 call writefile(lines, 'XquickfixFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005992
5993 let lines =<< trim END
5994 split XquickfixFails
5995 silent vimgrep anything %
5996 normal o
5997 au BufLeave * ++once source XquickfixFails
5998 " This will trigger the autocommand, which causes an error, what follows
5999 " is aborted but the window was already split.
6000 silent! cwindow
6001 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006002 call writefile(lines, 'XtestWinFails', 'D')
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006003 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
6004 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
6005
6006 " clean up
6007 call term_sendkeys(buf, ":bwipe!\<CR>")
6008 call term_wait(buf)
6009 call StopVimInTerminal(buf)
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01006010endfunc
6011
Bram Moolenaar2d870f82020-12-05 13:41:01 +01006012" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01006013" is changed.
6014func Xqfbuf_update(cchar)
6015 call s:setup_commands(a:cchar)
6016
6017 Xexpr "F1:1:line1"
6018 Xopen
6019 call assert_equal(['F1|1| line1'], getline(1, '$'))
6020 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6021
6022 " Test setqflist() using the 'lines' key in 'what'
6023 " add a new entry
6024 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
6025 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
6026 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6027 " replace all the entries with a single entry
6028 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
6029 call assert_equal(['F3|3| line3'], getline(1, '$'))
6030 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6031 " remove all the entries
6032 call g:Xsetlist([], 'r', {'lines' : []})
6033 call assert_equal([''], getline(1, '$'))
6034 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6035 " add a new list
6036 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
6037 call assert_equal(['F4|4| line4'], getline(1, '$'))
6038 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6039
6040 " Test setqflist() using the 'items' key in 'what'
6041 " add a new entry
6042 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
6043 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
6044 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
6045 " replace all the entries with a single entry
6046 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
6047 call assert_equal(['F6|6| line6'], getline(1, '$'))
6048 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
6049 " remove all the entries
6050 call g:Xsetlist([], 'r', {'items' : []})
6051 call assert_equal([''], getline(1, '$'))
6052 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
6053 " add a new list
6054 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
6055 call assert_equal(['F7|7| line7'], getline(1, '$'))
6056 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6057
6058 call g:Xsetlist([], ' ', {})
6059 call assert_equal([''], getline(1, '$'))
6060 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
6061
6062 Xclose
6063endfunc
6064
6065func Test_qfbuf_update()
6066 call Xqfbuf_update('c')
6067 call Xqfbuf_update('l')
6068endfunc
6069
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006070func Test_vimgrep_noswapfile()
6071 set noswapfile
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006072 call writefile(['one', 'two', 'three'], 'Xgreppie', 'D')
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006073 vimgrep two Xgreppie
6074 call assert_equal('two', getline('.'))
6075
Bram Moolenaar8c801b32021-03-05 20:58:22 +01006076 set swapfile
6077endfunc
6078
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006079" Test for the :vimgrep 'f' flag (fuzzy match)
6080func Xvimgrep_fuzzy_match(cchar)
6081 call s:setup_commands(a:cchar)
6082
6083 Xvimgrep /three one/f Xfile*
6084 let l = g:Xgetlist()
6085 call assert_equal(2, len(l))
6086 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6087 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6088 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6089 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6090
6091 Xvimgrep /the/f Xfile*
6092 let l = g:Xgetlist()
6093 call assert_equal(3, len(l))
6094 call assert_equal(['Xfile1', 1, 9, 'one two three'],
6095 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6096 call assert_equal(['Xfile2', 2, 1, 'three one two'],
6097 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6098 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
6099 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6100
6101 Xvimgrep /aaa/fg Xfile*
6102 let l = g:Xgetlist()
6103 call assert_equal(4, len(l))
6104 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
6105 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
6106 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
6107 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
6108 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
6109 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
6110 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
6111 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
6112
6113 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
6114endfunc
6115
6116func Test_vimgrep_fuzzy_match()
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006117 call writefile(['one two three', 'aaaaaa'], 'Xfile1', 'D')
6118 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2', 'D')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006119 call Xvimgrep_fuzzy_match('c')
6120 call Xvimgrep_fuzzy_match('l')
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02006121endfunc
6122
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006123func Test_locationlist_open_in_newtab()
6124 call s:create_test_file('Xqftestfile1')
6125 call s:create_test_file('Xqftestfile2')
6126 call s:create_test_file('Xqftestfile3')
6127
6128 %bwipe!
6129
Yegappan Lakshmanan4a7724a2022-04-11 15:11:39 +01006130 let lines =<< trim END
6131 Xqftestfile1:5:Line5
6132 Xqftestfile2:10:Line10
6133 Xqftestfile3:16:Line16
6134 END
6135 lgetexpr lines
Wei-Chung Wen1557b162021-07-15 13:13:39 +02006136
6137 silent! llast
6138 call assert_equal(1, tabpagenr('$'))
6139 call assert_equal('Xqftestfile3', bufname())
6140
6141 set switchbuf=newtab
6142
6143 silent! lfirst
6144 call assert_equal(2, tabpagenr('$'))
6145 call assert_equal('Xqftestfile1', bufname())
6146
6147 silent! lnext
6148 call assert_equal(3, tabpagenr('$'))
6149 call assert_equal('Xqftestfile2', bufname())
6150
6151 call delete('Xqftestfile1')
6152 call delete('Xqftestfile2')
6153 call delete('Xqftestfile3')
6154 set switchbuf&vim
6155
6156 %bwipe!
6157endfunc
6158
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02006159" Test for win_gettype() in quickfix and location list windows
6160func Test_win_gettype()
6161 copen
6162 call assert_equal("quickfix", win_gettype())
6163 let wid = win_getid()
6164 wincmd p
6165 call assert_equal("quickfix", win_gettype(wid))
6166 cclose
6167 lexpr ''
6168 lopen
6169 call assert_equal("loclist", win_gettype())
6170 let wid = win_getid()
6171 wincmd p
6172 call assert_equal("loclist", win_gettype(wid))
6173 lclose
6174endfunc
6175
Christian Brabandt0b226f62021-12-01 10:54:24 +00006176fun Test_vimgrep_nomatch()
6177 call XexprTests('c')
6178 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
6179 copen
6180 if has("win32")
6181 call assert_fails('vimgrep foo *.zzz', 'E479:')
6182 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'}]
6183 else
6184 call assert_fails('vimgrep foo *.zzz', 'E480:')
6185 let expected = []
6186 endif
6187 call assert_equal(expected, getqflist())
6188 cclose
6189endfunc
6190
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00006191" Test for opening the quickfix window in two tab pages and then closing one
6192" of the quickfix windows. This should not make the quickfix buffer unlisted.
6193" (github issue #9300).
6194func Test_two_qf_windows()
6195 cexpr "F1:1:line1"
6196 copen
6197 tabnew
6198 copen
6199 call assert_true(&buflisted)
6200 cclose
6201 tabfirst
6202 call assert_true(&buflisted)
6203 let bnum = bufnr()
6204 cclose
6205 " if all the quickfix windows are closed, then buffer should be unlisted.
6206 call assert_false(buflisted(bnum))
6207 %bw!
6208
6209 " Repeat the test for a location list
6210 lexpr "F2:2:line2"
6211 lopen
6212 let bnum = bufnr()
6213 tabnew
6214 exe "buffer" bnum
6215 tabfirst
6216 lclose
6217 tablast
6218 call assert_true(buflisted(bnum))
6219 tabclose
6220 lopen
6221 call assert_true(buflisted(bnum))
6222 lclose
6223 call assert_false(buflisted(bnum))
6224 %bw!
6225endfunc
6226
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006227" Weird sequence of commands that caused entering a wiped-out buffer
6228func Test_lopen_bwipe()
6229 func R()
6230 silent! tab lopen
6231 e x
6232 silent! lfile
6233 endfunc
6234
6235 cal R()
6236 cal R()
6237 cal R()
6238 bw!
6239 delfunc R
6240endfunc
6241
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006242" Another sequence of commands that caused all buffers to be wiped out
6243func Test_lopen_bwipe_all()
6244 let lines =<< trim END
6245 func R()
6246 silent! tab lopen
6247 e foo
6248 silent! lfile
6249 endfunc
6250 cal R()
6251 exe "norm \<C-W>\<C-V>0"
6252 cal R()
6253 bwipe
6254
6255 call writefile(['done'], 'Xresult')
6256 qall!
6257 END
Bram Moolenaardb77cb32022-10-05 21:45:30 +01006258 call writefile(lines, 'Xscript', 'D')
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006259 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6260 call assert_equal(['done'], readfile('Xresult'))
6261 endif
6262
Bram Moolenaare3537ae2022-02-08 15:05:20 +00006263 call delete('Xresult')
6264endfunc
6265
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006266" Test for calling setqflist() function recursively
6267func Test_recursive_setqflist()
6268 augroup QF_Test
6269 au!
6270 autocmd BufWinEnter quickfix call setqflist([], 'r')
6271 augroup END
6272
6273 copen
6274 call assert_fails("call setqflist([], 'a')", 'E952:')
6275
6276 augroup QF_Test
6277 au!
6278 augroup END
6279 %bw!
6280endfunc
6281
6282" Test for failure to create a new window when selecting a file from the
6283" quickfix window
6284func Test_cwindow_newwin_fails()
6285 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6286 cwindow
6287 only
6288 let qf_wid = win_getid()
6289 " create the maximum number of scratch windows
6290 let hor_win_count = (&lines - 1)/2
6291 let hor_split_count = hor_win_count - 1
6292 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6293 call win_gotoid(qf_wid)
6294 call assert_fails('exe "normal \<CR>"', 'E36:')
6295 %bw!
6296endfunc
6297
6298" Test for updating the location list when only the location list window is
6299" present and the corresponding file window is closed.
6300func Test_loclist_update_with_llwin_only()
6301 %bw!
6302 new
6303 wincmd w
6304 lexpr ["Xfile1:1:Line1"]
6305 lopen
6306 wincmd p
6307 close
6308 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6309 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6310 %bw!
6311endfunc
6312
6313" Test for getting the quickfix list after a buffer with an error is wiped out
6314func Test_getqflist_wiped_out_buffer()
6315 %bw!
6316 cexpr ["Xtest1:34:Wiped out"]
6317 let bnum = bufnr('Xtest1')
6318 call assert_equal(bnum, getqflist()[0].bufnr)
6319 bw Xtest1
6320 call assert_equal(0, getqflist()[0].bufnr)
6321 %bw!
6322endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006323
Yegappan Lakshmanan454ce672022-03-24 11:22:13 +00006324" Test for the status message that is displayed when opening a new quickfix
6325" list
6326func Test_qflist_statusmsg()
6327 cexpr "1\n2"
6328 cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
6329 call assert_equal('(4 of 4): msg', v:statusmsg)
6330 call setqflist([], 'f')
6331 %bw!
6332
6333 " When creating a new quickfix list, if an autocmd changes the quickfix list
6334 " in the stack, then an error message should be displayed.
6335 augroup QF_Test
6336 au!
6337 au BufEnter test_quickfix.vim colder
6338 augroup END
6339 cexpr "1\n2"
6340 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6341 call setqflist([], 'f')
6342 augroup QF_Test
6343 au!
6344 augroup END
6345 %bw!
6346
6347 augroup QF_Test
6348 au!
6349 au BufEnter test_quickfix.vim caddexpr "4"
6350 augroup END
6351 call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
6352 call setqflist([], 'f')
6353 augroup QF_Test
6354 au!
6355 augroup END
6356 %bw!
6357endfunc
6358
Bram Moolenaard6c67622022-08-24 20:07:22 +01006359func Test_quickfixtextfunc_recursive()
6360 func s:QFTfunc(o)
6361 cgete '0'
6362 endfunc
6363 copen
6364 let &quickfixtextfunc = 's:QFTfunc'
6365 cex ""
6366
6367 let &quickfixtextfunc = ''
6368 cclose
6369endfunc
6370
Yegappan Lakshmanan6d24a512022-08-27 20:59:57 +01006371" Test for replacing the location list from an autocmd. This used to cause a
6372" read from freed memory.
6373func Test_loclist_replace_autocmd()
6374 %bw!
6375 call setloclist(0, [], 'f')
6376 let s:bufnr = bufnr()
6377 cal setloclist(0, [{'0': 0, '': ''}])
6378 au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
6379 lopen
6380 try
6381 exe "norm j\<CR>"
6382 catch
6383 endtry
6384 lnext
6385 %bw!
6386 call setloclist(0, [], 'f')
6387endfunc
Bram Moolenaard6c67622022-08-24 20:07:22 +01006388
Yegappan Lakshmananf8412c92022-10-13 11:59:22 +01006389" Test for a very long error line and a very long information line
6390func Test_very_long_error_line()
6391 let msg = repeat('abcdefghijklmn', 146)
6392 let emsg = 'Xlonglines.c:1:' . msg
6393 call writefile([msg, emsg], 'Xerror', 'D')
6394 cfile Xerror
6395 cwindow
6396 call assert_equal($'|| {msg}', getline(1))
6397 call assert_equal($'Xlonglines.c|1| {msg}', getline(2))
6398 cclose
6399
6400 let l = execute('clist!')->split("\n")
6401 call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l)
6402
6403 let l = execute('cc')->split("\n")
6404 call assert_equal([$'(2 of 2): {msg}'], l)
6405
6406 call setqflist([], 'f')
6407endfunc
6408
6409" In the quickfix window, spaces at the beginning of an informational line
6410" should not be removed but should be removed from an error line.
6411func Test_info_line_with_space()
6412 cexpr ["a.c:20:12: error: expected ';' before ':' token",
6413 \ ' 20 | Afunc():', '', ' | ^']
6414 copen
6415 call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token",
6416 \ '|| 20 | Afunc():', '|| ',
6417 \ '|| | ^'], getline(1, '$'))
6418 cclose
6419
6420 let l = execute('clist!')->split("\n")
6421 call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token",
6422 \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l)
6423
6424 call setqflist([], 'f')
6425endfunc
6426
Bram Moolenaarc96b7f52022-12-02 15:58:38 +00006427func s:QfTf(_)
6428endfunc
6429
6430func Test_setqflist_cb_arg()
6431 " This was changing the callback name in the dictionary.
6432 let d = #{quickfixtextfunc: 's:QfTf'}
6433 call setqflist([], 'a', d)
6434 call assert_equal('s:QfTf', d.quickfixtextfunc)
6435
6436 call setqflist([], 'f')
6437endfunc
6438
zeertzjqa40c0bc2023-05-27 14:10:08 +01006439" Test that setqflist() should not prevent :stopinsert from working
6440func Test_setqflist_stopinsert()
6441 new
6442 call setqflist([], 'f')
6443 copen
6444 cclose
6445 func StopInsert()
6446 stopinsert
6447 call setqflist([{'text': 'foo'}])
6448 return ''
6449 endfunc
6450
6451 call setline(1, 'abc')
6452 call cursor(1, 1)
6453 call feedkeys("i\<C-R>=StopInsert()\<CR>$", 'tnix')
6454 call assert_equal('foo', getqflist()[0].text)
6455 call assert_equal([0, 1, 3, 0, v:maxcol], getcurpos())
6456 call assert_equal(['abc'], getline(1, '$'))
6457
6458 delfunc StopInsert
6459 call setqflist([], 'f')
6460 bwipe!
6461endfunc
Bram Moolenaard0fab102022-10-20 16:03:33 +01006462
Shane Harper5bf04282023-06-07 19:09:57 +01006463func Test_quickfix_buffer_contents()
6464 call setqflist([{'filename':'filename', 'pattern':'pattern', 'text':'text'}])
6465 copen
6466 call assert_equal(['filename|pattern| text'], getline(1, '$')) " The assert failed with Vim v9.0.0736; '| text' did not appear after the pattern.
6467 call setqflist([], 'f')
6468endfunc
6469
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006470func XquickfixUpdateTests(cchar)
6471 call s:setup_commands(a:cchar)
6472
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006473 " Setup: populate a couple buffers
6474 new
6475 call setline(1, range(1, 5))
6476 let b1 = bufnr()
6477 new
6478 call setline(1, range(1, 3))
6479 let b2 = bufnr()
6480 " Setup: set a quickfix list.
6481 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 +02006482 call g:Xsetlist(items)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006483
6484 " Open the quickfix list, select the third entry.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006485 Xopen
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006486 exe "normal jj\<CR>"
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006487 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006488
6489 " Update the quickfix list. Make sure the third entry is still selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006490 call g:Xsetlist([], 'u', { 'items': items })
6491 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006492
6493 " Update the quickfix list again, but this time with missing line number
6494 " information. Confirm that we keep the current buffer selected.
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006495 call g:Xsetlist([{'bufnr': b1}, {'bufnr': b2}], 'u')
6496 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
6497
6498 Xclose
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006499
6500 " Cleanup the buffers we allocated during this test.
6501 %bwipe!
Yegappan Lakshmanan6a1deaf2024-10-15 20:26:45 +02006502endfunc
6503
6504" Test for updating a quickfix list using the "u" flag in setqflist()
6505func Test_quickfix_update()
6506 call XquickfixUpdateTests('c')
6507 call XquickfixUpdateTests('l')
Jeremy Fleischman27fbf6e2024-10-14 20:46:27 +02006508endfunc
6509
6510func Test_quickfix_update_with_missing_coordinate_info()
6511 new
6512 call setline(1, range(1, 5))
6513 let b1 = bufnr()
6514
6515 new
6516 call setline(1, range(1, 3))
6517 let b2 = bufnr()
6518
6519 new
6520 call setline(1, range(1, 2))
6521 let b3 = bufnr()
6522
6523 " Setup: set a quickfix list with no coordinate information at all.
6524 call setqflist([{}, {}])
6525
6526 " Open the quickfix list, select the second entry.
6527 copen
6528 exe "normal j\<CR>"
6529 call assert_equal(2, getqflist({'idx' : 0}).idx)
6530
6531 " Update the quickfix list. As the previously selected entry has no
6532 " coordinate information, we expect the first entry to now be selected.
6533 call setqflist([{'bufnr': b1}, {'bufnr': b2}, {'bufnr': b3}], 'u')
6534 call assert_equal(1, getqflist({'idx' : 0}).idx)
6535
6536 " Select the second entry in the quickfix list.
6537 copen
6538 exe "normal j\<CR>"
6539 call assert_equal(2, getqflist({'idx' : 0}).idx)
6540
6541 " Update the quickfix list again. The currently selected entry does not have
6542 " a line number, but we should keep the file selected.
6543 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 3}, {'bufnr': b3}], 'u')
6544 call assert_equal(2, getqflist({'idx' : 0}).idx)
6545
6546 " Update the quickfix list again. The currently selected entry (bufnr=b2, lnum=3)
6547 " is no longer present. We should pick the nearest entry.
6548 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 1}, {'bufnr': b2, 'lnum': 4}], 'u')
6549 call assert_equal(3, getqflist({'idx' : 0}).idx)
6550
6551 " Set the quickfix list again, with a specific column number. The currently selected entry doesn't have a
6552 " column number, but they share a line number.
6553 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 5}, {'bufnr': b2, 'lnum': 4, 'col': 6}], 'u')
6554 call assert_equal(2, getqflist({'idx' : 0}).idx)
6555
6556 " Set the quickfix list again. The currently selected column number (6) is
6557 " no longer present. We should select the nearest column number.
6558 call setqflist([{'bufnr': b1}, {'bufnr': b2, 'lnum': 4, 'col': 2}, {'bufnr': b2, 'lnum': 4, 'col': 4}], 'u')
6559 call assert_equal(3, getqflist({'idx' : 0}).idx)
6560
6561 " Now set the quickfix list, but without columns. We should still pick the
6562 " same line.
6563 call setqflist([{'bufnr': b2, 'lnum': 3}, {'bufnr': b2, 'lnum': 4}, {'bufnr': b2, 'lnum': 4}], 'u')
6564 call assert_equal(2, getqflist({'idx' : 0}).idx)
6565
6566 " Cleanup the buffers we allocated during this test.
6567 %bwipe!
6568endfunc
6569
Yegappan Lakshmananb7318002023-10-25 20:50:28 +02006570" Test for "%b" in "errorformat"
6571func Test_efm_format_b()
6572 call setqflist([], 'f')
6573 new
6574 call setline(1, ['1: abc', '1: def', '1: ghi'])
6575 let b1 = bufnr()
6576 new
6577 call setline(1, ['2: abc', '2: def', '2: ghi'])
6578 let b2 = bufnr()
6579 new
6580 call setline(1, ['3: abc', '3: def', '3: ghi'])
6581 let b3 = bufnr()
6582 new
6583 let lines =<< trim eval END
6584 {b1}:1:1
6585 {b2}:2:2
6586 {b3}:3:3
6587 END
6588 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c'})
6589 cfirst
6590 call assert_equal([b1, 1, 1], [bufnr(), line('.'), col('.')])
6591 cnext
6592 call assert_equal([b2, 2, 2], [bufnr(), line('.'), col('.')])
6593 cnext
6594 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6595 enew!
6596
6597 " Use a non-existing buffer
6598 let lines =<< trim eval END
6599 9991:1:1:m1
6600 9992:2:2:m2
6601 {b3}:3:3:m3
6602 END
6603 call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c:%m'})
6604 cfirst | cnext
6605 call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
6606 " Lines with non-existing buffer numbers should be used as non-error lines
6607 call assert_equal([
6608 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6609 \ module: '', type: '', end_col: 0, col: 0, text: '9991:1:1:m1'},
6610 \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
6611 \ module: '', type: '', end_col: 0, col: 0, text: '9992:2:2:m2'},
6612 \ #{lnum: 3, bufnr: b3, end_lnum: 0, pattern: '', valid: 1, vcol: 0,
6613 \ nr: -1, module: '', type: '', end_col: 0, col: 3, text: 'm3'}],
6614 \ getqflist())
6615 %bw!
6616 call setqflist([], 'f')
6617endfunc
6618
Christian Brabandt652c8212024-04-29 20:36:49 +02006619func XbufferTests_range(cchar)
6620 call s:setup_commands(a:cchar)
6621
6622 enew!
6623 let lines =<< trim END
6624 Xtestfile7:700:10:Line 700
6625 Xtestfile8:800:15:Line 800
6626 END
6627 silent! call setline(1, lines)
6628 norm! Vy
6629 " Note: We cannot use :Xbuffer here,
6630 " it doesn't properly fail, so we need to
6631 " test using the raw c/l commands.
6632 " (also further down)
6633 if (a:cchar == 'c')
6634 exe "'<,'>cbuffer!"
6635 else
6636 exe "'<,'>lbuffer!"
6637 endif
6638 let l = g:Xgetlist()
6639 call assert_true(len(l) == 1 &&
6640 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700')
6641
6642 enew!
6643 let lines =<< trim END
6644 Xtestfile9:900:55:Line 900
6645 Xtestfile10:950:66:Line 950
6646 END
6647 silent! call setline(1, lines)
6648 if (a:cchar == 'c')
6649 1cgetbuffer
6650 else
6651 1lgetbuffer
6652 endif
6653 let l = g:Xgetlist()
6654 call assert_true(len(l) == 1 &&
6655 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900')
6656
6657 enew!
6658 let lines =<< trim END
6659 Xtestfile11:700:20:Line 700
6660 Xtestfile12:750:25:Line 750
6661 END
6662 silent! call setline(1, lines)
6663 if (a:cchar == 'c')
6664 1,1caddbuffer
6665 else
6666 1,1laddbuffer
6667 endif
6668 let l = g:Xgetlist()
6669 call assert_true(len(l) == 2 &&
6670 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
6671 \ l[1].lnum == 700 && l[1].col == 20 && l[1].text ==# 'Line 700')
6672 enew!
6673
6674 " Check for invalid range
6675 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
6676 " commands. So directly call the commands.
6677 if (a:cchar == 'c')
6678 call assert_fails('900,999caddbuffer', 'E16:')
6679 else
6680 call assert_fails('900,999laddbuffer', 'E16:')
6681 endif
6682endfunc
6683
6684func Test_cbuffer_range()
6685 call XbufferTests_range('c')
6686 call XbufferTests_range('l')
6687endfunc
6688
zeertzjq5df3cb22024-10-07 21:05:06 +02006689" Test for displaying fname passed from setqflist() when the names include
6690" hard links to prevent seemingly duplicate entries.
Austin Chang29822992024-10-03 10:50:05 +02006691func Xtest_hardlink_fname(cchar)
6692 call s:setup_commands(a:cchar)
6693 %bwipe
6694 " Create a sample source file
6695 let lines =<< trim END
6696 void sample() {}
6697 int main() { sample(); return 0; }
6698 END
6699 call writefile(lines, 'test_qf_hardlink1.c', 'D')
6700 defer delete('test_qf_hardlink1.c')
6701 defer delete('test_qf_hardlink2.c')
6702 call system('ln test_qf_hardlink1.c test_qf_hardlink2.c')
6703 if v:shell_error
6704 throw 'Skipped: ln throws error on this platform'
6705 endif
6706 call g:Xsetlist([], 'f')
6707 " Make a qflist that contains the file and it's hard link
6708 " like how LSP plugins set response into qflist
6709 call g:Xsetlist([{'filename' : 'test_qf_hardlink1.c', 'lnum' : 1},
6710 \ {'filename' : 'test_qf_hardlink2.c', 'lnum' : 1}], ' ')
6711 Xopen
6712 " Ensure that two entries are displayed with different name
6713 " so that they aren't seen as duplication.
6714 call assert_equal(['test_qf_hardlink1.c|1| ',
6715 \ 'test_qf_hardlink2.c|1| '], getline(1, '$'))
6716 Xclose
6717endfunc
6718
6719func Test_hardlink_fname()
6720 CheckUnix
6721 CheckExecutable ln
6722 call Xtest_hardlink_fname('c')
6723 call Xtest_hardlink_fname('l')
6724endfunc
6725
64-bitman88d41ab2025-04-06 17:20:39 +02006726" Test for checking if correct number of tests are deleted
6727" and current list stays the same after setting Xhistory
6728" to a smaller number. Do roughly the same for growing the stack.
6729func Xtest_resize_list_stack(cchar)
6730 call s:setup_commands(a:cchar)
6731 Xsethist 100
6732
6733 for i in range(1, 100)
6734 Xexpr string(i)
6735 endfor
6736 Xopen
6737 call assert_equal(g:Xgetlist({'nr': '$'}).nr, 100)
6738 call assert_equal("|| 100", getline(1))
6739 Xsethist 8
6740 call assert_equal("|| 100", getline(1))
6741 Xolder 5
6742 call assert_equal("|| 95", getline(1))
6743 Xsethist 6
6744 call assert_equal("|| 95", getline(1))
6745 Xsethist 1
6746 call assert_equal("|| 100", getline(1))
6747
6748 " grow array again
6749 Xsethist 100
6750 for i in range(1, 99)
6751 Xexpr string(i)
6752 endfor
6753 call assert_equal("|| 99", getline(1))
6754 Xolder 99
6755 call assert_equal("|| 100", getline(1))
6756
6757 Xsethistdefault
6758endfunc
6759
6760func Test_resize_list_stack()
6761 call Xtest_resize_list_stack('c')
6762 call Xtest_resize_list_stack('l')
6763endfunc
6764
6765" Test to check if order of lists is from
6766" oldest at the bottom to newest at the top
6767func Xtest_Xhistory_check_order(cchar)
6768
6769 Xsethist 100
6770
6771 for i in range(1, 100)
6772 Xexpr string(i)
6773 endfor
6774
6775 Xopen
6776 for i in range(100, 1, -1)
6777 let l:ret = assert_equal("|| " .. i, getline(1))
6778
6779 if ret == 1 || i == 1
6780 break
6781 endif
6782 Xolder
6783 endfor
6784
6785 for i in range(1, 50)
6786 Xexpr string(i)
6787 endfor
6788
6789 for i in range(50, 1, -1)
6790 let l:ret = assert_equal("|| " .. i, getline(1))
6791
6792 if ret == 1 || i == 50
6793 break
6794 endif
6795 Xolder
6796 endfor
6797
6798 for i in range(50, 1, -1)
6799 let l:ret = assert_equal("|| " .. i, getline(1))
6800
6801 if ret == 1 || i == 50
6802 break
6803 endif
6804 Xolder
6805 endfor
6806
6807 Xsethistdefault
6808endfunc
6809
6810func Test_set_history_to_check_order()
6811 call Xtest_Xhistory_check_order('c')
6812 call Xtest_Xhistory_check_order('l')
6813endfunc
6814
6815" Check if 'lhistory' is the same between the location list window
6816" and associated normal window
6817func Test_win_and_loc_synced()
6818 new
6819 set lhistory=2
6820 lexpr "Text"
6821 lopen
6822
6823 " check if lhistory is synced when modified inside the
6824 " location list window
6825 setlocal lhistory=1
6826 wincmd k
6827 call assert_equal(&lhistory, 1)
6828
6829 " check if lhistory is synced when modified inside the
6830 " normal window
6831 setlocal lhistory=10
6832 lopen
6833 call assert_equal(&lhistory, 10)
6834
6835 wincmd k
6836 lclose
6837 wincmd q
6838
6839 set lhistory&
6840endfunc
6841
6842" Test if setting the lhistory of one window doesn't affect the other
6843func Test_two_win_are_independent_of_history()
6844 setlocal lhistory=10
6845 new
6846 setlocal lhistory=20
6847 wincmd w
6848 call assert_equal(&lhistory, 10)
6849 wincmd w
6850 wincmd q
6851
6852 set lhistory&
6853endfunc
6854
6855" Test if lhistory is copied over to a new window
6856func Test_lhistory_copied_over()
6857 setlocal lhistory=3
6858 split
6859 call assert_equal(&lhistory, 3)
6860 wincmd q
6861
6862 set lhistory&
6863endfunc
6864
6865" Test if error occurs when given invalid history number
6866func Xtest_invalid_history_num(cchar)
6867 call s:setup_commands(a:cchar)
6868
6869 call assert_fails('Xsethist -10000', "E1542:")
6870 call assert_fails('Xsethist 10000', "E1543:")
6871 Xsethistdefault
6872endfunc
6873
6874func Test_invalid_history_num()
6875 call Xtest_invalid_history_num('c')
6876 call Xtest_invalid_history_num('l')
6877endfunc
6878
6879" Test if chistory and lhistory don't affect each other
6880func Test_chi_and_lhi_are_independent()
6881 set chistory=100
6882 set lhistory=100
6883
6884 set chistory=10
6885 call assert_equal(&lhistory, 100)
6886
6887 set lhistory=1
6888 call assert_equal(&chistory, 10)
6889
6890 set chistory&
6891 set lhistory&
6892endfunc
6893
Christian Brabandtce80c592025-03-28 19:13:32 +01006894func Test_quickfix_close_buffer_crash()
6895 new
6896 lexpr 'test' | lopen
6897 wincmd k
6898 lclose
6899 wincmd q
6900endfunc
6901
Sean Dewarb4074ea2025-05-10 14:30:36 +02006902func Test_vimgrep_dummy_buffer_crash()
6903 augroup DummyCrash
6904 autocmd!
6905 " Make the dummy buffer non-current, but still open in a window.
6906 autocmd BufReadCmd * ++once let s:dummy_buf = bufnr()
6907 \| split | wincmd p | enew
6908
6909 " Autocmds from cleaning up the dummy buffer in this case should be blocked.
6910 autocmd BufWipeout *
6911 \ call assert_notequal(s:dummy_buf, str2nr(expand('<abuf>')))
6912 augroup END
6913
6914 silent! vimgrep /./ .
6915 redraw! " Window to freed dummy buffer used to remain; heap UAF.
6916 call assert_equal([], win_findbuf(s:dummy_buf))
6917 call assert_equal(0, bufexists(s:dummy_buf))
6918
6919 unlet! s:dummy_buf
6920 autocmd! DummyCrash
6921 %bw!
6922endfunc
6923
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006924" vim: shiftwidth=2 sts=2 expandtab