blob: 283e943794fd337b2afac5737ed11f1d2375c30c [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
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00004source vim9.vim
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020046 let g:Xgetlist = function('getqflist')
47 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020048 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020049 else
50 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
51 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020052 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020053 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020054 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010055 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020057 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xclose <mods>lclose <args>
59 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
60 command! -nargs=* Xgetfile <mods>lgetfile <args>
61 command! -nargs=* Xaddfile <mods>laddfile <args>
62 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
63 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
64 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
65 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020066 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
67 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020068 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
69 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020070 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020071 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020072 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020073 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010074 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020075 command! -nargs=* Xgrep <mods> lgrep <args>
76 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
77 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010078 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020079 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
80 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020081 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
82 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020083 let g:Xgetlist = function('getloclist', [0])
84 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020085 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020086 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010087endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088
Bram Moolenaarda59dd52016-01-05 21:59:58 +010089" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010090func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020091 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010092
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020093 if a:cchar == 'l'
94 call assert_fails('llist', 'E776:')
95 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +010096 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020097 Xgetexpr []
98 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +010099 call assert_true(v:errmsg ==# 'E42: No Errors')
100
101 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200102 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100103 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100104 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100105
106 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100107 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100108 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
109 \ ' 4 Xtestfile2:2 col 2: Line2',
110 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
111
112 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100113 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100114 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
115 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100116 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100117
118 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100119 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100120 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
121 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
122
Bram Moolenaaree85df32017-03-19 14:19:50 +0100123 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100124 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
125
Bram Moolenaaree85df32017-03-19 14:19:50 +0100126 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100127 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
128
Bram Moolenaaree85df32017-03-19 14:19:50 +0100129 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100130 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
131 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100132
133 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100134 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100135 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
136 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100137
thinca6864efa2021-06-19 20:45:20 +0200138 " Ranged entries
139 call g:Xsetlist([{'lnum':10,'text':'Line1'},
140 \ {'lnum':20,'col':10,'text':'Line2'},
141 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
142 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
143 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
144 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
145 let l = split(execute('Xlist', ""), "\n")
146 call assert_equal([' 1:10: Line1',
147 \ ' 2:20 col 10: Line2',
148 \ ' 3:30 col 15-20: Line3',
149 \ ' 4:40-45: Line4',
150 \ ' 5:50-55 col 15: Line5',
151 \ ' 6:60-65 col 25-35: Line6'], l)
152
Bram Moolenaaree85df32017-03-19 14:19:50 +0100153 " Different types of errors
154 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
155 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
156 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
157 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
158 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
159 let l = split(execute('Xlist', ""), "\n")
160 call assert_equal([' 1:10 col 5 warning 11: Warning',
161 \ ' 2:20 col 10 error 22: Error',
162 \ ' 3:30 col 15 info 33: Info',
163 \ ' 4:40 col 20 x 44: Other',
164 \ ' 5:50 col 25 55: one'], l)
165
Bram Moolenaard76ce852018-05-01 15:02:04 +0200166 " Test for module names, one needs to explicitly set `'valid':v:true` so
167 call g:Xsetlist([
168 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
169 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
170 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
171 let l = split(execute('Xlist', ""), "\n")
172 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
173 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
174 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
175
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100176 " For help entries in the quickfix list, only the filename without directory
177 " should be displayed
178 Xhelpgrep setqflist()
179 let l = split(execute('Xlist 1', ''), "\n")
180 call assert_match('^ 1 [^\\/]\{-}:', l[0])
181
Bram Moolenaaree85df32017-03-19 14:19:50 +0100182 " Error cases
183 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100184endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100185
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100186func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100187 call XlistTests('c')
188 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100189endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100190
191" Tests for the :colder, :cnewer, :lolder and :lnewer commands
192" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100193" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100194func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200195 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100196
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200197 if a:cchar == 'l'
198 " No location list for the current window
199 call assert_fails('lolder', 'E776:')
200 call assert_fails('lnewer', 'E776:')
201 endif
202
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200203 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200204 call g:Xsetlist(list)
205
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100206 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200207 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100208 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
209
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200210 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100211 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
212
213 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200214 Xgetexpr ['Xtestfile1:1:3:Line1']
215 Xgetexpr ['Xtestfile2:2:2:Line2']
216 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100217
218 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200219 Xolder
220 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100221 call assert_equal('Line2', l[0].text)
222
223 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200224 Xnewer
225 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100226 call assert_equal('Line3', l[0].text)
227
228 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200229 Xolder 2
230 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100231 call assert_equal('Line1', l[0].text)
232
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200233 Xnewer 2
234 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100235 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100236endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100238func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100239 call XageTests('c')
240 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100241endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100242
243" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
244" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100245func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200246 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100247
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200248 " Opening the location list window without any errors should fail
249 if a:cchar == 'l'
250 call assert_fails('lopen', 'E776:')
251 endif
252
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200254 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100255
256 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200257 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100258 call assert_true(winnr('$') == 1)
259
260 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200261 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
262 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100263
264 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200265 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100266 call assert_true(winnr('$') == 2 && winnr() == 2 &&
267 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200268 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
270 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200271 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100272 call assert_true(winnr('$') == 1)
273
274 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200275 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200278 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100279 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200280 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100281
282 " Opening the window again, should move the cursor to that window
283 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200284 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100285 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200286 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100287 \ getline('.') ==# '|| non-error 1')
288
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100289 " :cnext in quickfix window should move to the next entry
290 Xnext
291 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100292
293 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200294 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100295 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200296
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100297 " Specifying the width should adjust the width for a vertically split
298 " quickfix window.
299 vert Xopen
300 call assert_equal(10, winwidth(0))
301 vert Xopen 12
302 call assert_equal(12, winwidth(0))
303 Xclose
304
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200305 " Horizontally or vertically splitting the quickfix window should create a
306 " normal window/buffer
307 Xopen
308 wincmd s
309 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
310 call assert_equal(0, getwininfo(win_getid())[0].loclist)
311 call assert_notequal('quickfix', &buftype)
312 close
313 Xopen
314 wincmd v
315 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
316 call assert_equal(0, getwininfo(win_getid())[0].loclist)
317 call assert_notequal('quickfix', &buftype)
318 close
319 Xopen
320 Xclose
321
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200322 if a:cchar == 'c'
323 " Opening the quickfix window in multiple tab pages should reuse the
324 " quickfix buffer
325 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
326 \ 'Xtestfile3:3:1:Line3']
327 Xopen
328 let qfbufnum = bufnr('%')
329 tabnew
330 Xopen
331 call assert_equal(qfbufnum, bufnr('%'))
332 new | only | tabonly
333 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100334endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100335
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100336func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100337 call XwindowTests('c')
338 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100339endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100340
Bram Moolenaar36d50222019-05-02 20:17:40 +0200341func Test_copenHeight()
342 copen
343 wincmd H
344 let height = winheight(0)
345 copen 10
346 call assert_equal(height, winheight(0))
347 quit
348endfunc
349
Bram Moolenaar1142a312019-10-16 14:51:39 +0200350func Test_copenHeight_tabline()
351 set tabline=foo showtabline=2
352 copen
353 wincmd H
354 let height = winheight(0)
355 copen 10
356 call assert_equal(height, winheight(0))
357 quit
358 set tabline& showtabline&
359endfunc
360
361
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100362" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
363" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100364func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200365 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100366
367 call writefile(['Xtestfile1:700:10:Line 700',
368 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
369
370 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 Xfile Xqftestfile1
372 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373 call assert_true(len(l) == 2 &&
374 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
375 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
376
Bram Moolenaar049cba92016-06-26 14:38:04 +0200377 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200378 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200379
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100380 " Run cfile/lfile from a modified buffer
381 enew!
382 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200383 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100384 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
385
386 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200387 Xaddfile Xqftestfile1
388 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100389 call assert_true(len(l) == 3 &&
390 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
391
392 call writefile(['Xtestfile1:222:77:Line 222',
393 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
394
395 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200396 Xgetfile Xqftestfile1
397 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100398 call assert_true(len(l) == 2 &&
399 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
400 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
401
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100402 " Test for a file with a long line and without a newline at the end
403 let text = repeat('x', 1024)
404 let t = 'a.txt:18:' . text
405 call writefile([t], 'Xqftestfile1', 'b')
406 silent! Xfile Xqftestfile1
407 call assert_equal(text, g:Xgetlist()[0].text)
408
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100409 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100410endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100412func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100413 call XfileTests('c')
414 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100415endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100416
417" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
418" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100419func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200420 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100421
422 enew!
423 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
424 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200425 Xbuffer!
426 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100427 call assert_true(len(l) == 2 &&
428 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
429 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
430
431 enew!
432 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
433 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200434 Xgetbuffer
435 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100436 call assert_true(len(l) == 2 &&
437 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
438 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
439
440 enew!
441 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
442 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200443 Xaddbuffer
444 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100445 call assert_true(len(l) == 4 &&
446 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
447 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
448 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200449 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100450
Bram Moolenaaree85df32017-03-19 14:19:50 +0100451 " Check for invalid buffer
452 call assert_fails('Xbuffer 199', 'E474:')
453
454 " Check for unloaded buffer
455 edit Xtestfile1
456 let bnr = bufnr('%')
457 enew!
458 call assert_fails('Xbuffer ' . bnr, 'E681:')
459
460 " Check for invalid range
461 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
462 " commands. So directly call the commands.
463 if (a:cchar == 'c')
464 call assert_fails('900,999cbuffer', 'E16:')
465 else
466 call assert_fails('900,999lbuffer', 'E16:')
467 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100468endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100469
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100470func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100471 call XbufferTests('c')
472 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100473endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100474
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100475func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200476 call s:setup_commands(a:cchar)
477
478 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100479endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200480
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100481func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200482 call XexprTests('c')
483 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100484endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200485
486" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100487func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200488 call s:setup_commands(a:cchar)
489
Bram Moolenaar74240d32017-12-10 15:26:15 +0100490 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200491 " Jumping to first or next location list entry without any error should
492 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100493 if a:cchar == 'c'
494 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100495 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100496 else
497 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100498 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200499 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100500 call assert_fails('Xnext', err)
501 call assert_fails('Xprev', err)
502 call assert_fails('Xnfile', err)
503 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100504 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200505
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100506 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100507 call assert_fails(cmd, 'E42:')
508
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200509 call s:create_test_file('Xqftestfile1')
510 call s:create_test_file('Xqftestfile2')
511
512 Xgetexpr ['Xqftestfile1:5:Line5',
513 \ 'Xqftestfile1:6:Line6',
514 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200515 \ 'Xqftestfile2:11:Line11',
516 \ 'RegularLine1',
517 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200518
519 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100520 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200521 call assert_fails('Xprev', 'E553:')
522 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200523 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200524 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525 call assert_equal(10, line('.'))
526 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200527 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100529 5Xcc
530 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
531 2Xcc
532 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100533 if a:cchar == 'c'
534 cc
535 else
536 ll
537 endif
538 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100539 10Xcc
540 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200541 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200542 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200543 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200544 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200545 call assert_fails('Xnext', 'E553:')
546 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100547 " To process the range using quickfix list entries, directly use the
548 " quickfix commands (don't use the user defined commands)
549 if a:cchar == 'c'
550 $cc
551 else
552 $ll
553 endif
554 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200555 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200556 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200557 call assert_equal(5, line('.'))
558
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200559 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200560 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200561 call assert_equal(11, line('.'))
562 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200563 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200564 call assert_equal(5, line('.'))
565
Bram Moolenaar74240d32017-12-10 15:26:15 +0100566 " Jumping to an error from the error window using cc command
567 Xgetexpr ['Xqftestfile1:5:Line5',
568 \ 'Xqftestfile1:6:Line6',
569 \ 'Xqftestfile2:10:Line10',
570 \ 'Xqftestfile2:11:Line11']
571 Xopen
572 10Xcc
573 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200574 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100575 Xopen
576 call cursor(2, 1)
577 if a:cchar == 'c'
578 .cc
579 else
580 .ll
581 endif
582 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200583 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100584
585 " Jumping to an error from the error window (when only the error window is
586 " present)
587 Xopen | only
588 Xlast 1
589 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200590 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100591
Bram Moolenaaree85df32017-03-19 14:19:50 +0100592 Xexpr ""
593 call assert_fails('Xnext', 'E42:')
594
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200595 call delete('Xqftestfile1')
596 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200597
598 " Should be able to use next/prev with invalid entries
599 Xexpr ""
600 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
601 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100602 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200603 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
604 Xlast
605 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
606 Xfirst
607 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
608 2Xnext
609 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100610endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200611
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100612func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200613 call Xtest_browse('c')
614 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100615endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200616
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100617func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200618 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100619 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100620
Bram Moolenaarce90e362019-09-08 18:58:44 +0200621 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100622 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100623
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200624 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100625 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100626
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200627 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100628 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100629
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200630 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100631 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100632
633endfunc
634
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100635func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200636 call s:setup_commands(a:cchar)
637 Xhelpgrep quickfix
638 Xopen
639 if a:cchar == 'c'
640 let title_text = ':helpgrep quickfix'
641 else
642 let title_text = ':lhelpgrep quickfix'
643 endif
644 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200645
646 " Jumping to a help topic should open the help window
647 only
648 Xnext
649 call assert_true(&buftype == 'help')
650 call assert_true(winnr('$') == 2)
651 " Jumping to the next match should reuse the help window
652 Xnext
653 call assert_true(&buftype == 'help')
654 call assert_true(winnr() == 1)
655 call assert_true(winnr('$') == 2)
656 " Jumping to the next match from the quickfix window should reuse the help
657 " window
658 Xopen
659 Xnext
660 call assert_true(&buftype == 'help')
661 call assert_true(winnr() == 1)
662 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200663 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200664
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100665 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200666 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100667
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100668 " When the current window is vertically split, jumping to a help match
669 " should open the help window at the top.
670 only | enew
671 let w1 = win_getid()
672 vert new
673 let w2 = win_getid()
674 Xnext
675 let w3 = win_getid()
676 call assert_true(&buftype == 'help')
677 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100678 " See jump_to_help_window() for details
679 let w2_width = winwidth(w2)
680 if w2_width != &columns && w2_width < 80
681 call assert_equal(['col', [['leaf', w3],
682 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
683 else
684 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
685 \ ['leaf', w1]]] , winlayout())
686 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100687
688 new | only
689 set buftype=help
690 set modified
691 call assert_fails('Xnext', 'E37:')
692 set nomodified
693 new | only
694
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200695 if a:cchar == 'l'
696 " When a help window is present, running :lhelpgrep should reuse the
697 " help window and not the current window
698 new | only
699 call g:Xsetlist([], 'f')
700 help index.txt
701 wincmd w
702 lhelpgrep quickfix
703 call assert_equal(1, winnr())
704 call assert_notequal([], getloclist(1))
705 call assert_equal([], getloclist(2))
706 endif
707
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200708 new | only
709
Bram Moolenaaree85df32017-03-19 14:19:50 +0100710 " Search for non existing help string
711 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200712 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200713 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100714endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200715
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100716func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200717 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200718 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200719 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100720endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100721
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100722def Test_helpgrep_vim9_restore_cpo()
723 assert_equal('aABceFs', &cpo)
724
725 var rtp_save = &rtp
726 var dir = 'Xruntime/after'
727 &rtp ..= ',' .. dir
728 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100729 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100730 filetype plugin on
731 silent helpgrep grail
732 cwindow
733 silent helpgrep grail
734
735 assert_equal('aABceFs', &cpo)
736 delete(dir, 'rf')
737 &rtp = rtp_save
738 cclose
739 helpclose
740enddef
741
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200742def Test_vim9_cexpr()
743 var text = 'somefile:95:error'
744 cexpr text
745 var l = getqflist()
746 assert_equal(1, l->len())
747 assert_equal(95, l[0].lnum)
748 assert_equal('error', l[0].text)
749
750 text = 'somefile:77:warning'
751 caddexpr text
752 l = getqflist()
753 assert_equal(2, l->len())
754 assert_equal(77, l[1].lnum)
755 assert_equal('warning', l[1].text)
756enddef
757
Bram Moolenaar6920c722016-01-22 22:44:10 +0100758func Test_errortitle()
759 augroup QfBufWinEnter
760 au!
761 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
762 augroup END
763 copen
764 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'')'}]
765 call setqflist(a)
766 call assert_equal(':setqflist()', g:a)
767 augroup QfBufWinEnter
768 au!
769 augroup END
770 augroup! QfBufWinEnter
771endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100772
Bram Moolenaar5584df62016-03-18 21:00:51 +0100773func Test_vimgreptitle()
774 augroup QfBufWinEnter
775 au!
776 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
777 augroup END
778 try
779 vimgrep /pattern/j file
780 catch /E480/
781 endtry
782 copen
783 call assert_equal(': vimgrep /pattern/j file', g:a)
784 augroup QfBufWinEnter
785 au!
786 augroup END
787 augroup! QfBufWinEnter
788endfunc
789
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100790func Test_bufwinenter_once()
791 augroup QfBufWinEnter
792 au!
793 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
794 augroup END
795 let g:got_afile = ''
796 copen
797 call assert_equal('got quickfix', g:got_afile)
798
799 cclose
800 unlet g:got_afile
801 augroup QfBufWinEnter
802 au!
803 augroup END
804 augroup! QfBufWinEnter
805endfunc
806
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100807func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200808 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100809
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200810 Xgetexpr ['file:1:1:message']
811 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100812 if a:cchar == 'c'
813 call setqflist(l, 'r')
814 else
815 call setloclist(0, l, 'r')
816 endif
817
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200818 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100819 if a:cchar == 'c'
820 let title = ':setqflist()'
821 else
822 let title = ':setloclist()'
823 endif
824 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200825 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100826endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100827
828" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100829func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200830 call XqfTitleTests('c')
831 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100832endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100833
834" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100835func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100836 let save_efm = &efm
837 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
838 cgetexpr ['WWWW', 'EEEE', 'CCCC']
839 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
840 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
841 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
842 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
843 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
844 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
845 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
846 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
847 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100848endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100849
850" This will test for problems in quickfix:
851" A. incorrectly copying location lists which caused the location list to show
852" a different name than the file that was actually being displayed.
853" B. not reusing the window for which the location list window is opened but
854" instead creating new windows.
855" C. make sure that the location list window is not reused instead of the
856" window it belongs to.
857"
858" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100859func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100860 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
861 let word = substitute(base, '\v(.*)\..*', '\1', '')
862
863 setl modifiable
864 setl noreadonly
865 setl noswapfile
866 setl bufhidden=delete
867 %del _
868 " For problem 2:
869 " 'buftype' has to be set to reproduce the constant opening of new windows
870 setl buftype=nofile
871
872 call setline(1, word)
873
874 setl nomodified
875 setl nomodifiable
876 setl readonly
877 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100878endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100879
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100880func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200881 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100882
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200883 augroup testgroup
884 au!
885 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
886 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100887
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200888 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100889
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200890 let qflist = []
891 for word in words
892 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
893 " NOTE: problem 1:
894 " intentionally not setting 'lnum' so that the quickfix entries are not
895 " valid
896 eval qflist->setloclist(0, ' ')
897 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100898
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200899 " Test A
900 lrewind
901 enew
902 lopen
903 4lnext
904 vert split
905 wincmd L
906 lopen
907 wincmd p
908 lnext
909 let fileName = expand("%")
910 wincmd p
911 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
912 let fileName = substitute(fileName, '\\', '/', 'g')
913 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
914 call assert_equal("test://bar.txt", fileName)
915 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100916
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200917 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100918
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200919 " Test B:
920 lrewind
921 lopen
922 2
923 exe "normal \<CR>"
924 wincmd p
925 3
926 exe "normal \<CR>"
927 wincmd p
928 4
929 exe "normal \<CR>"
930 call assert_equal(2, winnr('$'))
931 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100932
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200933 " Test C:
934 lrewind
935 lopen
936 " Let's move the location list window to the top to check whether it (the
937 " first window found) will be reused when we try to open new windows:
938 wincmd K
939 2
940 exe "normal \<CR>"
941 wincmd p
942 3
943 exe "normal \<CR>"
944 wincmd p
945 4
946 exe "normal \<CR>"
947 1wincmd w
948 call assert_equal('quickfix', &buftype)
949 2wincmd w
950 let bufferName = expand("%")
951 let bufferName = substitute(bufferName, '\\', '/', 'g')
952 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100953
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200954 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100955
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200956 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100957endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100958
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100959func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200960 augroup testgroup
961 au!
962 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
963 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100964
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200965 func! R(n)
966 quit
967 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100968
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200969 new
970 let q = []
971 call add(q, {'filename': 'test_curwin.txt' })
972 call setloclist(0, q)
973 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100974
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200975 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100976endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100977
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100978func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200979 call writefile(['loclistfoo'], 'loclistfoo')
980 call writefile(['loclistbar'], 'loclistbar')
981 set switchbuf=usetab
982
983 edit loclistfoo
984 tabedit loclistbar
985 silent lgrep loclistfoo loclist*
986 call assert_equal(1, tabpagenr())
987
988 enew | only | tabonly
989 set switchbuf&vim
990 call delete('loclistfoo')
991 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100992endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200993
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100994" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100995func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200996 " The 'errorformat' setting is different on non-Unix systems.
997 " This test works only on Unix-like systems.
998 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100999
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001000 let l =<< trim [DATA]
1001 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1002 "Xtestfile", line 6 col 19; this is an error
1003 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1004 Xtestfile:9: parse error before `asd'
1005 make: *** [vim] Error 1
1006 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001007
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001008 2 returned
1009 "Xtestfile", line 11 col 1; this is an error
1010 "Xtestfile", line 12 col 2; this is another error
1011 "Xtestfile", line 14:10; this is an error in column 10
1012 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1013 "Xtestfile", linenr 16: yet another problem
1014 Error in "Xtestfile" at line 17:
1015 x should be a dot
1016 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1017 ^
1018 Error in "Xtestfile" at line 18:
1019 x should be a dot
1020 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1021 .............^
1022 Error in "Xtestfile" at line 19:
1023 x should be a dot
1024 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1025 --------------^
1026 Error in "Xtestfile" at line 20:
1027 x should be a dot
1028 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1029 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001030
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001031 Does anyone know what is the problem and how to correction it?
1032 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1033 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1034 [DATA]
1035
1036 call writefile(l, 'Xerrorfile1')
1037 call writefile(l[:-2], 'Xerrorfile2')
1038
1039 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001040 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1041 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1042 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1043 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1044 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1045 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1046 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1047 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1048 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1049 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1051 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1052 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1055 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1056 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1060 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1061[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001062 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001063
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001064 let save_efm = &efm
1065 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1066 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001067
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001068 exe 'cf Xerrorfile2'
1069 clast
1070 copen
1071 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1072 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001073
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001074 exe 'cf Xerrorfile1'
1075 call assert_equal([4, 12], [line('.'), col('.')])
1076 cn
1077 call assert_equal([6, 19], [line('.'), col('.')])
1078 cn
1079 call assert_equal([9, 2], [line('.'), col('.')])
1080 cn
1081 call assert_equal([10, 2], [line('.'), col('.')])
1082 cn
1083 call assert_equal([11, 1], [line('.'), col('.')])
1084 cn
1085 call assert_equal([12, 2], [line('.'), col('.')])
1086 cn
1087 call assert_equal([14, 10], [line('.'), col('.')])
1088 cn
1089 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1090 cn
1091 call assert_equal([16, 2], [line('.'), col('.')])
1092 cn
1093 call assert_equal([17, 6], [line('.'), col('.')])
1094 cn
1095 call assert_equal([18, 7], [line('.'), col('.')])
1096 cn
1097 call assert_equal([19, 8], [line('.'), col('.')])
1098 cn
1099 call assert_equal([20, 9], [line('.'), col('.')])
1100 clast
1101 cprev
1102 cprev
1103 wincmd w
1104 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1105 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001106
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001107 let &efm = save_efm
1108 call delete('Xerrorfile1')
1109 call delete('Xerrorfile2')
1110 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001111endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001112
Bram Moolenaarab47c612016-06-14 22:02:26 +02001113" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001114func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001115 call s:setup_commands(a:cchar)
1116
Bram Moolenaarab47c612016-06-14 22:02:26 +02001117 let save_efm=&efm
1118 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1119
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001120 let lines = ["Entering dir 'dir1/a'",
1121 \ 'habits2.txt:1:Nine Healthy Habits',
1122 \ "Entering dir 'b'",
1123 \ 'habits3.txt:2:0 Hours of television',
1124 \ 'habits2.txt:7:5 Small meals',
1125 \ "Entering dir 'dir1/c'",
1126 \ 'habits4.txt:3:1 Hour of exercise',
1127 \ "Leaving dir 'dir1/c'",
1128 \ "Leaving dir 'dir1/a'",
1129 \ 'habits1.txt:4:2 Liters of water',
1130 \ "Entering dir 'dir2'",
1131 \ 'habits5.txt:5:3 Cups of hot green tea',
1132 \ "Leaving dir 'dir2'"
1133 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001134
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001135 Xexpr ""
1136 for l in lines
1137 Xaddexpr l
1138 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001139
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001140 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001141
1142 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1143 call assert_equal(1, qf[1].lnum)
1144 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1145 call assert_equal(2, qf[3].lnum)
1146 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1147 call assert_equal(7, qf[4].lnum)
1148 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1149 call assert_equal(3, qf[6].lnum)
1150 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1151 call assert_equal(4, qf[9].lnum)
1152 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1153 call assert_equal(5, qf[11].lnum)
1154
1155 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001156endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001157
1158" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001159func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001160 " Create the directory stack and files
1161 call mkdir('dir1')
1162 call mkdir('dir1/a')
1163 call mkdir('dir1/a/b')
1164 call mkdir('dir1/c')
1165 call mkdir('dir2')
1166
1167 let lines = ["Nine Healthy Habits",
1168 \ "0 Hours of television",
1169 \ "1 Hour of exercise",
1170 \ "2 Liters of water",
1171 \ "3 Cups of hot green tea",
1172 \ "4 Short mental breaks",
1173 \ "5 Small meals",
1174 \ "6 AM wake up time",
1175 \ "7 Minutes of laughter",
1176 \ "8 Hours of sleep (at least)",
1177 \ "9 PM end of the day and off to bed"
1178 \ ]
1179 call writefile(lines, 'habits1.txt')
1180 call writefile(lines, 'dir1/a/habits2.txt')
1181 call writefile(lines, 'dir1/a/b/habits3.txt')
1182 call writefile(lines, 'dir1/c/habits4.txt')
1183 call writefile(lines, 'dir2/habits5.txt')
1184
1185 call s:dir_stack_tests('c')
1186 call s:dir_stack_tests('l')
1187
1188 call delete('dir1', 'rf')
1189 call delete('dir2', 'rf')
1190 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001191endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001192
Bram Moolenaar9b457942016-10-09 16:10:05 +02001193" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001194func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001195 call s:setup_commands(a:cchar)
1196
1197 let save_efm = &efm
1198
1199 let &efm =
1200 \ '%Eerror %m %l,' .
1201 \ '%-Wignored %m %l,' .
1202 \ '%+Cmore ignored %m %l,' .
1203 \ '%Zignored end'
1204 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1205 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1206 call assert_equal([['resync', 1, 4, 'E']], l)
1207
1208 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001209endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001210
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001211func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001212 call Xefm_ignore_continuations('c')
1213 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001214endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001215
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001216" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001217func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001218 call s:setup_commands(a:cchar)
1219
Bram Moolenaar049cba92016-06-26 14:38:04 +02001220 let save_efm = &efm
1221
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001222 set efm=%f:%l:%m,%f:%f:%l:%m
1223 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1224
1225 set efm=%f:%l:%m,%f:%l:%r:%m
1226 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1227
1228 set efm=%f:%l:%m,%O:%f:%l:%m
1229 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1230
1231 set efm=%f:%l:%m,%f:%l:%*[^a-z
1232 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1233
1234 set efm=%f:%l:%m,%f:%l:%*c
1235 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1236
1237 set efm=%f:%l:%m,%L%M%N
1238 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1239
1240 set efm=%f:%l:%m,%f:%l:%m:%R
1241 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1242
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001243 " Invalid regular expression
1244 set efm=%\\%%k
1245 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1246
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001247 set efm=
1248 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1249
1250 set efm=%DEntering\ dir\ abc,%f:%l:%m
1251 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1252
1253 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001254endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001255
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001256func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001257 call Xinvalid_efm_Tests('c')
1258 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001259endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001260
1261" TODO:
1262" Add tests for the following formats in 'errorformat'
1263" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001264func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001265 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001266
1267 " Test for %s format in efm
1268 set efm=%f:%s
1269 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001270 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001271 call assert_equal('^\VLine search text\$', l[0].pattern)
1272 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001273
Bram Moolenaaree85df32017-03-19 14:19:50 +01001274 let l = split(execute('clist', ''), "\n")
1275 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1276
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001277 " Test for a long line
1278 cexpr 'Xtestfile:' . repeat('a', 1026)
1279 let l = getqflist()
1280 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1281
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001282 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001283 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001284 [Xtestfile1]
1285 (1,17) error: ';' missing
1286 (21,2) warning: variable 'z' not defined
1287 (67,3) error: end of file found before string ended
1288 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001289
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001290 [Xtestfile2]
1291 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001292
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001293 [Xtestfile3]
1294 NEW compiler v1.1
1295 (2,2) warning: variable 'x' not defined
1296 (67,3) warning: 's' already defined
1297 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001298 [DATA]
1299
Bram Moolenaaree85df32017-03-19 14:19:50 +01001300 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001301 " To exercise the push/pop file functionality in quickfix, the test files
1302 " need to be created.
1303 call writefile(['Line1'], 'Xtestfile1')
1304 call writefile(['Line2'], 'Xtestfile2')
1305 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001306 cexpr ""
1307 for l in lines
1308 caddexpr l
1309 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001310 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001311 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001312 call assert_equal(21, l[2].lnum)
1313 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001314 call assert_equal('w', l[2].type)
1315 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001316 call delete('Xtestfile1')
1317 call delete('Xtestfile2')
1318 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001319
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001320 " Test for %P, %Q with non-existing files
1321 cexpr lines
1322 let l = getqflist()
1323 call assert_equal(14, len(l))
1324 call assert_equal('[Xtestfile1]', l[0].text)
1325 call assert_equal('[Xtestfile2]', l[6].text)
1326 call assert_equal('[Xtestfile3]', l[9].text)
1327
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001328 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001329 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001330 Error 275
1331 line 42
1332 column 3
1333 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001334 [DATA]
1335
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001336 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1337 cgetexpr lines
1338 let l = getqflist()
1339 call assert_equal(275, l[0].nr)
1340 call assert_equal(42, l[0].lnum)
1341 call assert_equal(3, l[0].col)
1342 call assert_equal('E', l[0].type)
1343 call assert_equal("\n' ' expected after '--'", l[0].text)
1344
1345 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001346 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001347 Error in line 147 of foo.c:
1348 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001349 [DATA]
1350
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001351 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1352 cgetexpr lines
1353 let l = getqflist()
1354 call assert_equal(147, l[0].lnum)
1355 call assert_equal('E', l[0].type)
1356 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001357
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001358 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001359 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001360 ==============================================================
1361 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1362 --------------------------------------------------------------
1363 Traceback (most recent call last):
1364 File "unittests/dbfacadeTest.py", line 89, in testFoo
1365 self.assertEquals(34, dtid)
1366 File "/usr/lib/python2.2/unittest.py", line 286, in
1367 failUnlessEqual
1368 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001369 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001370
1371 --------------------------------------------------------------
1372 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001373 [DATA]
1374
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001375 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001376 cgetexpr lines
1377 let l = getqflist()
1378 call assert_equal(8, len(l))
1379 call assert_equal(89, l[4].lnum)
1380 call assert_equal(1, l[4].valid)
1381 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001382 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001383
Bram Moolenaard76ce852018-05-01 15:02:04 +02001384 " Test for %o
1385 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001386 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1387 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001388 let l = getqflist()
1389 call assert_equal(1, len(l), string(l))
1390 call assert_equal('Language.PureScript.Types', l[0].module)
1391 copen
1392 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1393 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001394 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001395 cclose
1396 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001397 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001398
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001399 " Test for a long module name
1400 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1401 let l = getqflist()
1402 call assert_equal(repeat('m', 1024), l[0].module)
1403 call assert_equal(15, l[0].lnum)
1404 call assert_equal('message', l[0].text)
1405
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001406 " The following sequence of commands used to crash Vim
1407 set efm=%W%m
1408 cgetexpr ['msg1']
1409 let l = getqflist()
1410 call assert_equal(1, len(l), string(l))
1411 call assert_equal('msg1', l[0].text)
1412 set efm=%C%m
1413 lexpr 'msg2'
1414 let l = getloclist(0)
1415 call assert_equal(1, len(l), string(l))
1416 call assert_equal('msg2', l[0].text)
1417 lopen
1418 call setqflist([], 'r')
1419 caddbuf
1420 let l = getqflist()
1421 call assert_equal(1, len(l), string(l))
1422 call assert_equal('|| msg2', l[0].text)
1423
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001424 " When matching error lines, case should be ignored. Test for this.
1425 set noignorecase
1426 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1427 call assert_equal(10, l.items[0].lnum)
1428 call assert_equal('Line 20', l.items[0].text)
1429 set ignorecase&
1430
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001431 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001432 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001433endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001434
Bram Moolenaare9283662020-06-07 14:10:47 +02001435" Test for '%t' (error type) field in 'efm'
1436func Test_efm_error_type()
1437 let save_efm = &efm
1438
1439 " error type
1440 set efm=%f:%l:%t:%m
1441 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1442 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1443 let output = split(execute('clist'), "\n")
1444 call assert_equal([
1445 \ ' 1 Xfile1:10 error: msg1',
1446 \ ' 2 Xfile1:20 warning: msg2',
1447 \ ' 3 Xfile1:30 info: msg3',
1448 \ ' 4 Xfile1:40 note: msg4',
1449 \ ' 5 Xfile1:50 R: msg5'], output)
1450
1451 " error type and a error number
1452 set efm=%f:%l:%t:%n:%m
1453 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1454 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1455 let output = split(execute('clist'), "\n")
1456 call assert_equal([
1457 \ ' 1 Xfile1:10 error 2: msg1',
1458 \ ' 2 Xfile1:20 warning 4: msg2',
1459 \ ' 3 Xfile1:30 info 6: msg3',
1460 \ ' 4 Xfile1:40 note 8: msg4',
1461 \ ' 5 Xfile1:50 R 3: msg5'], output)
1462 let &efm = save_efm
1463endfunc
1464
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001465func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001466 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001467 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001468 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001469 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001470 colder
1471 cgetexpr []
1472 endfunc
1473 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001474 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001475 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001476 lolder
1477 lgetexpr []
1478 endfunc
1479 endif
1480
1481 augroup testgroup
1482 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001483 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001484 augroup END
1485
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001486 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001487 let words = [ "a", "b" ]
1488 let qflist = []
1489 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001490 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001491 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001492 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001493 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001494
1495 augroup! testgroup
1496endfunc
1497
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001498func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001499 call XquickfixChangedByAutocmd('c')
1500 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001501endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001502
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001503func Test_setloclist_in_autocommand()
1504 call writefile(['test1', 'test2'], 'Xfile')
1505 edit Xfile
1506 let s:bufnr = bufnr()
1507 call setloclist(1,
1508 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1509 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1510
1511 augroup Test_LocList
1512 au!
1513 autocmd BufEnter * call setloclist(1,
1514 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1515 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1516 augroup END
1517
1518 lopen
1519 call assert_fails('exe "normal j\<CR>"', 'E926:')
1520
1521 augroup Test_LocList
1522 au!
1523 augroup END
1524 call delete('Xfile')
1525endfunc
1526
Bram Moolenaar8b201792016-03-25 15:01:10 +01001527func Test_caddbuffer_to_empty()
1528 helpgr quickfix
1529 call setqflist([], 'r')
1530 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001531 try
1532 cn
1533 catch
1534 " number of matches is unknown
1535 call assert_true(v:exception =~ 'E553:')
1536 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001537 quit!
1538endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001539
1540func Test_cgetexpr_works()
1541 " this must not crash Vim
1542 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001543 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001544endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001545
1546" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001547func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001548 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001549
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001550 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001551 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001552 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001553 call assert_equal(2, len(l))
1554 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001555 call assert_equal(3, l[1].end_lnum)
1556 call assert_equal(4, l[1].col)
1557 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001558
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 Xnext
1560 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1561 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001562 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001563 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001564 call assert_equal(3, line('.'))
1565
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001566 " Appending entries to the list should not change the cursor position
1567 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001568 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001569 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001570 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001571 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1572 call assert_equal(1, line('.'))
1573 close
1574
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001575 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001576 \ {'bufnr': a:bnum, 'lnum': 4},
1577 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001578 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001579 call assert_equal(3, len(l))
1580 call assert_equal(5, l[2].lnum)
1581
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001582 call g:Xsetlist([])
1583 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001584 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001585
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001586 " Tests for setting the 'valid' flag
1587 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1588 Xwindow
1589 call assert_equal(1, winnr('$'))
1590 let l = g:Xgetlist()
1591 call g:Xsetlist(l)
1592 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001593 " Adding a non-valid entry should not mark the list as having valid entries
1594 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1595 Xwindow
1596 call assert_equal(1, winnr('$'))
1597
1598 " :cnext/:cprev should still work even with invalid entries in the list
1599 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1600 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1601 call g:Xsetlist(l)
1602 Xnext
1603 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1604 Xprev
1605 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1606 " :cnext/:cprev should still work after appending invalid entries to an
1607 " empty list
1608 call g:Xsetlist([])
1609 call g:Xsetlist(l, 'a')
1610 Xnext
1611 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1612 Xprev
1613 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1614
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001615 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1616 Xwindow
1617 call assert_equal(2, winnr('$'))
1618 Xclose
1619 let save_efm = &efm
1620 set efm=%m
1621 Xgetexpr 'TestMessage'
1622 let l = g:Xgetlist()
1623 call g:Xsetlist(l)
1624 call assert_equal(1, g:Xgetlist()[0].valid)
1625 let &efm = save_efm
1626
Bram Moolenaaree85df32017-03-19 14:19:50 +01001627 " Error cases:
1628 " Refer to a non-existing buffer and pass a non-dictionary type
1629 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1630 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1631 call g:Xsetlist([[1, 2,3]])
1632 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001633 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001634endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001635
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001636func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001637 new Xtestfile | only
1638 let bnum = bufnr('%')
1639 call setline(1, range(1,5))
1640
1641 call SetXlistTests('c', bnum)
1642 call SetXlistTests('l', bnum)
1643
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001644 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001645 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001646endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001647
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001648func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001649 call s:setup_commands(a:cchar)
1650
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001651 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001652 let @/ = 'Test_'
1653 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001654 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001655 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001656 Xvimgrep empty test_quickfix.vim
1657 call assert_true(len(g:Xgetlist()) > 0)
1658 Xvimgrep matches test_quickfix.vim
1659 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001660 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001661 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001662 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001663 call g:Xsetlist([], 'r')
1664 call assert_true(len(g:Xgetlist()) == 0)
1665 Xolder
1666 call assert_equal(testlen, len(g:Xgetlist()))
1667 Xnewer
1668 Xnewer
1669 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001670endfunc
1671
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001672func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001673 call Xlist_empty_middle('c')
1674 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001675endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001676
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001677func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001678 call s:setup_commands(a:cchar)
1679
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001680 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001681 Xvimgrep one test_quickfix.vim
1682 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001683 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001684 Xvimgrep two test_quickfix.vim
1685 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001686 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001687 Xvimgrep three test_quickfix.vim
1688 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001689 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001690 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001691 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001692 call g:Xsetlist([], 'r')
1693 call assert_true(len(g:Xgetlist()) == 0)
1694 Xnewer
1695 call assert_equal(twolen, len(g:Xgetlist()))
1696 Xnewer
1697 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001698endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001699
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001700func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001701 call Xlist_empty_older('c')
1702 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001703endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001704
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001705func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001706 call s:setup_commands(a:cchar)
1707
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001708 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1709 \ {'filename': 'fnameB', 'text': 'B'}]
1710 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1711 \ {'filename': 'fnameD', 'text': 'D'},
1712 \ {'filename': 'fnameE', 'text': 'E'}]
1713
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001714 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001715 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001716 silent! Xnewer 99
1717 call g:Xsetlist(list1)
1718 call g:Xsetlist(list2)
1719 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001720 call assert_equal(3, len(li))
1721 call assert_equal('C', li[0]['text'])
1722 call assert_equal('D', li[1]['text'])
1723 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001724 silent! Xolder
1725 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001726 call assert_equal(2, len(li))
1727 call assert_equal('A', li[0]['text'])
1728 call assert_equal('B', li[1]['text'])
1729
1730 " {action} is specified ' '.
1731 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001732 silent! Xnewer 99
1733 call g:Xsetlist(list1)
1734 call g:Xsetlist(list2, ' ')
1735 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001736 call assert_equal(3, len(li))
1737 call assert_equal('C', li[0]['text'])
1738 call assert_equal('D', li[1]['text'])
1739 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001740 silent! Xolder
1741 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001742 call assert_equal(2, len(li))
1743 call assert_equal('A', li[0]['text'])
1744 call assert_equal('B', li[1]['text'])
1745
1746 " {action} is specified 'a'.
1747 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001748 silent! Xnewer 99
1749 call g:Xsetlist(list1)
1750 call g:Xsetlist(list2, 'a')
1751 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001752 call assert_equal(5, len(li))
1753 call assert_equal('A', li[0]['text'])
1754 call assert_equal('B', li[1]['text'])
1755 call assert_equal('C', li[2]['text'])
1756 call assert_equal('D', li[3]['text'])
1757 call assert_equal('E', li[4]['text'])
1758
1759 " {action} is specified 'r'.
1760 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001761 silent! Xnewer 99
1762 call g:Xsetlist(list1)
1763 call g:Xsetlist(list2, 'r')
1764 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001765 call assert_equal(3, len(li))
1766 call assert_equal('C', li[0]['text'])
1767 call assert_equal('D', li[1]['text'])
1768 call assert_equal('E', li[2]['text'])
1769
1770 " Test for wrong value.
1771 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001772 call assert_fails("call g:Xsetlist(0)", 'E714:')
1773 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1774 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1775 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1776 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001777endfunc
1778
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001779func Test_setqflist_invalid_nr()
1780 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001781 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001782endfunc
1783
Bram Moolenaar99234f22020-02-10 22:56:54 +01001784func Test_setqflist_user_sets_buftype()
1785 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1786 set buftype=quickfix
1787 call setqflist([], 'a')
1788 enew
1789endfunc
1790
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001791func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001792 call XquickfixSetListWithAct('c')
1793 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001794endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001795
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001796func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001797 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001798
Bram Moolenaar049cba92016-06-26 14:38:04 +02001799 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001800 call assert_equal(1, l[0].lnum)
1801 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001802 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001803 call assert_equal(2, l[1].lnum)
1804 call assert_equal(1, l[1].col)
1805 call assert_equal(4070, len(l[1].text))
1806 call assert_equal(3, l[2].lnum)
1807 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001808 call assert_equal(4070, len(l[2].text))
1809 call assert_equal(4, l[3].lnum)
1810 call assert_equal(1, l[3].col)
1811 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001812
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001813 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001814endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001815
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001816func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001817 call s:setup_commands(a:cchar)
1818
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001819 let testfile = 'samples/quickfix.txt'
1820
1821 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001822 exe 'Xgetfile' testfile
1823 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001824
1825 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001826 Xexpr readfile(testfile)
1827 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001828
1829 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001830 Xexpr join(readfile(testfile), "\n")
1831 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001832
1833 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001834 exe 'edit' testfile
1835 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001836 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001837endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001838
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001839func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001840 call s:long_lines_tests('c')
1841 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001842endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001843
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001844func Test_cgetfile_on_long_lines()
1845 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1846 " are read at a time.
1847 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1848 let lines = [
1849 \ '/tmp/file1:1:1:aaa',
1850 \ '/tmp/file2:1:1:%s',
1851 \ '/tmp/file3:1:1:bbb',
1852 \ '/tmp/file4:1:1:ccc',
1853 \ ]
1854 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1855 call writefile(lines, 'Xcqetfile.txt')
1856 cgetfile Xcqetfile.txt
1857 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1858 endfor
1859 call delete('Xcqetfile.txt')
1860endfunc
1861
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001862func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001863 let l = []
1864 for i in range(1, 20)
1865 call add(l, 'Line' . i)
1866 endfor
1867 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001868endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001869
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001870func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001871 call s:create_test_file('Xqftestfile1')
1872 call s:create_test_file('Xqftestfile2')
1873 call s:create_test_file('Xqftestfile3')
1874
1875 new | only
1876 edit Xqftestfile1
1877 let file1_winid = win_getid()
1878 new Xqftestfile2
1879 let file2_winid = win_getid()
1880 cgetexpr ['Xqftestfile1:5:Line5',
1881 \ 'Xqftestfile1:6:Line6',
1882 \ 'Xqftestfile2:10:Line10',
1883 \ 'Xqftestfile2:11:Line11',
1884 \ 'Xqftestfile3:15:Line15',
1885 \ 'Xqftestfile3:16:Line16']
1886
1887 new
1888 let winid = win_getid()
1889 cfirst | cnext
1890 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001891 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001892 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001893 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001894 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001895
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001896 " Test for 'switchbuf' set to search for files in windows in the current
1897 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001898 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001899 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 cfirst | cnext
1901 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001902 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001903 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001904 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001905 call assert_equal(file2_winid, win_getid())
1906
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001907 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1908 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001909 enew | only
1910 set switchbuf=usetab
1911 tabedit Xqftestfile1
1912 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001913 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001914 tabfirst
1915 cfirst | cnext
1916 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001917 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001918 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001919 6cnext
1920 call assert_equal(4, tabpagenr())
1921 2cpfile
1922 call assert_equal(2, tabpagenr())
1923 2cnfile
1924 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001925 tabfirst | tabonly | enew
1926
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001927 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001928 set switchbuf=split
1929 cfirst | cnext
1930 call assert_equal(1, winnr('$'))
1931 cnext | cnext
1932 call assert_equal(2, winnr('$'))
1933 cnext | cnext
1934 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001935
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001936 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001937 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001938 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001939 cfirst | cnext
1940 call assert_equal(1, tabpagenr('$'))
1941 cnext | cnext
1942 call assert_equal(2, tabpagenr('$'))
1943 cnext | cnext
1944 call assert_equal(3, tabpagenr('$'))
1945 tabfirst | enew | tabonly | only
1946
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001947 set switchbuf=uselast
1948 split
1949 let last_winid = win_getid()
1950 copen
1951 exe "normal 1G\<CR>"
1952 call assert_equal(last_winid, win_getid())
1953 enew | only
1954
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001955 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1956 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001957 set switchbuf=
1958 edit Xqftestfile1
1959 let file1_winid = win_getid()
1960 new Xqftestfile2
1961 let file2_winid = win_getid()
1962 copen
1963 exe "normal 1G\<CR>"
1964 call assert_equal(file1_winid, win_getid())
1965 copen
1966 exe "normal 3G\<CR>"
1967 call assert_equal(file2_winid, win_getid())
1968 copen | only
1969 exe "normal 5G\<CR>"
1970 call assert_equal(2, winnr('$'))
1971 call assert_equal(1, bufwinnr('Xqftestfile3'))
1972
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001973 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001974 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001975 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001976 set switchbuf=usetab
1977 tabedit Xqftestfile1
1978 tabedit Xqftestfile2
1979 tabedit Xqftestfile3
1980 tabfirst
1981 copen | only
1982 clast
1983 call assert_equal(4, tabpagenr())
1984 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001985
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001986 " Jumping to a file that is not present in any of the tabpages and the
1987 " current tabpage doesn't have any usable windows, should open it in a new
1988 " window in the current tabpage.
1989 copen | only
1990 cfirst
1991 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001992 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001993
1994 " If opening a file changes 'switchbuf', then the new value should be
1995 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001996 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001997 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1998 enew | only
1999 set switchbuf&vim
2000 cexpr "Xqftestfile1:1:10"
2001 call assert_equal('split', &switchbuf)
2002 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2003 enew | only
2004 set switchbuf=useopen
2005 cexpr "Xqftestfile1:1:10"
2006 call assert_equal('usetab', &switchbuf)
2007 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2008 enew | only
2009 set switchbuf=useopen
2010 cexpr "Xqftestfile1:1:10"
2011 call assert_equal('', &switchbuf)
2012
Bram Moolenaar049cba92016-06-26 14:38:04 +02002013 call delete('Xqftestfile1')
2014 call delete('Xqftestfile2')
2015 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002016 set switchbuf&vim
2017
2018 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002019endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002020
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002021func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002022 call s:setup_commands(a:cchar)
2023
2024 enew | only
2025
Bram Moolenaarc1542742016-07-20 21:44:37 +02002026 let fname = 'Xqftestfile' . a:cchar
2027 call s:create_test_file(fname)
2028 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002029
Bram Moolenaarc1542742016-07-20 21:44:37 +02002030 Xgetexpr [fname . ':5:Line5',
2031 \ fname . ':10:Line10',
2032 \ fname . ':15:Line15',
2033 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002034
2035 6,14delete
2036 call append(6, ['Buffer', 'Window'])
2037
2038 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002039 call assert_equal(5, l[0].lnum)
2040 call assert_equal(6, l[2].lnum)
2041 call assert_equal(13, l[3].lnum)
2042
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002043 " If a file doesn't have any quickfix entries, then deleting lines in the
2044 " file should not update the quickfix list
2045 call g:Xsetlist([], 'f')
2046 1,2delete
2047 call assert_equal([], g:Xgetlist())
2048
Bram Moolenaar049cba92016-06-26 14:38:04 +02002049 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002050 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002051endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002052
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002053func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002054 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002055 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002056 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002057 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002058endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002059
2060" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002061func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002062 call s:setup_commands(a:cchar)
2063
2064 " The following lines are used for the grep test. Don't remove.
2065 " Grep_Test_Text: Match 1
2066 " Grep_Test_Text: Match 2
2067 " GrepAdd_Test_Text: Match 1
2068 " GrepAdd_Test_Text: Match 2
2069 enew! | only
2070 set makeef&vim
2071 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002072 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002073 Xopen
2074 call assert_true(w:quickfix_title =~ '^:grep')
2075 Xclose
2076 enew
2077 set makeef=Temp_File_##
2078 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002079 call assert_true(len(g:Xgetlist()) == 9)
2080
2081 " Try with 'grepprg' set to 'internal'
2082 set grepprg=internal
2083 silent Xgrep Grep_Test_Text: test_quickfix.vim
2084 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2085 call assert_true(len(g:Xgetlist()) == 9)
2086 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002087
2088 call writefile(['Vim'], 'XtestTempFile')
2089 set makeef=XtestTempFile
2090 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002091 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002092 call assert_false(filereadable('XtestTempFile'))
2093 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002094endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002095
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002096func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002097 " The grepprg may not be set on non-Unix systems
2098 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002099
2100 call s:test_xgrep('c')
2101 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002102endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002103
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002104func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002105 " Use one 'errorformat' for two windows. Add an expression to each of them,
2106 " make sure they each keep their own state.
2107 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2108 call mkdir('Xone/a', 'p')
2109 call mkdir('Xtwo/a', 'p')
2110 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2111 call writefile(lines, 'Xone/a/one.txt')
2112 call writefile(lines, 'Xtwo/a/two.txt')
2113
2114 new one
2115 let one_id = win_getid()
2116 lexpr ""
2117 new two
2118 let two_id = win_getid()
2119 lexpr ""
2120
2121 laddexpr "Entering dir 'Xtwo/a'"
2122 call win_gotoid(one_id)
2123 laddexpr "Entering dir 'Xone/a'"
2124 call win_gotoid(two_id)
2125 laddexpr 'two.txt:5:two two two'
2126 call win_gotoid(one_id)
2127 laddexpr 'one.txt:3:one one one'
2128
2129 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002130 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2131 call assert_equal(3, loc_one[1].lnum)
2132
2133 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002134 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2135 call assert_equal(5, loc_two[1].lnum)
2136
2137 call win_gotoid(one_id)
2138 bwipe!
2139 call win_gotoid(two_id)
2140 bwipe!
2141 call delete('Xone', 'rf')
2142 call delete('Xtwo', 'rf')
2143endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002144
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002145func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002146 call s:setup_commands(a:cchar)
2147
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002148 " Calling lbottom without any errors should fail
2149 if a:cchar == 'l'
2150 call assert_fails('lbottom', 'E776:')
2151 endif
2152
Bram Moolenaar875feea2017-06-11 16:07:51 +02002153 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002154 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002155 let wid = win_getid()
2156 call assert_equal(1, line('.'))
2157 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002158 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002159 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002160 call win_gotoid(wid)
2161 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002162 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002163endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002164
2165" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002166func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002167 call XbottomTests('c')
2168 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002169endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002170
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002171func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002172 call s:setup_commands(a:cchar)
2173
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002174 " clear all lists after the first one, then replace the first one.
2175 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002176 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002177 let entry = {'filename': 'foo', 'lnum': 42}
2178 call g:Xsetlist([entry], 'r')
2179 call g:Xsetlist([entry, entry])
2180 call g:Xsetlist([entry, entry, entry])
2181 let res = split(execute(a:cchar . 'hist'), "\n")
2182 call assert_equal(3, len(res))
2183 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2184 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2185 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2186 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002187
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002188 " Test for changing the quickfix lists
2189 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2190 exe '1' . a:cchar . 'hist'
2191 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2192 exe '3' . a:cchar . 'hist'
2193 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2194 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2195 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2196
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002197 call g:Xsetlist([], 'f')
2198 let l = split(execute(a:cchar . 'hist'), "\n")
2199 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002200 if a:cchar == 'c'
2201 call assert_fails('4chist', 'E16:')
2202 else
2203 call assert_fails('4lhist', 'E776:')
2204 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002205
2206 " An empty list should still show the stack history
2207 call g:Xsetlist([])
2208 let res = split(execute(a:cchar . 'hist'), "\n")
2209 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2210
2211 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002212endfunc
2213
2214func Test_history()
2215 call HistoryTest('c')
2216 call HistoryTest('l')
2217endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002218
2219func Test_duplicate_buf()
2220 " make sure we can get the highest buffer number
2221 edit DoesNotExist
2222 edit DoesNotExist2
2223 let last_buffer = bufnr("$")
2224
2225 " make sure only one buffer is created
2226 call writefile(['this one', 'that one'], 'Xgrepthis')
2227 vimgrep one Xgrepthis
2228 vimgrep one Xgrepthis
2229 call assert_equal(last_buffer + 1, bufnr("$"))
2230
2231 call delete('Xgrepthis')
2232endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002233
2234" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002235func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002236 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002237
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002238 " Error cases
2239 call assert_fails('call g:Xgetlist(99)', 'E715:')
2240 call assert_fails('call g:Xsetlist(99)', 'E714:')
2241 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002242
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002243 " Set and get the title
2244 call g:Xsetlist([])
2245 Xopen
2246 wincmd p
2247 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2248 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2249 call assert_equal(0, s)
2250 let d = g:Xgetlist({"title":1})
2251 call assert_equal('Sample', d.title)
2252 " Try setting title to a non-string value
2253 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2254 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2255
2256 Xopen
2257 call assert_equal('Sample', w:quickfix_title)
2258 Xclose
2259
2260 " Tests for action argument
2261 silent! Xolder 999
2262 let qfnr = g:Xgetlist({'all':1}).nr
2263 call g:Xsetlist([], 'r', {'title' : 'N1'})
2264 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2265 call g:Xsetlist([], ' ', {'title' : 'N2'})
2266 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2267
2268 let res = g:Xgetlist({'nr': 0})
2269 call assert_equal(qfnr + 1, res.nr)
2270 call assert_equal(['nr'], keys(res))
2271
2272 call g:Xsetlist([], ' ', {'title' : 'N3'})
2273 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2274
2275 " Changing the title of an earlier quickfix list
2276 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2277 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2278
2279 " Changing the title of an invalid quickfix list
2280 call assert_equal(-1, g:Xsetlist([], ' ',
2281 \ {'title' : 'SomeTitle', 'nr' : 99}))
2282 call assert_equal(-1, g:Xsetlist([], ' ',
2283 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2284
2285 if a:cchar == 'c'
2286 copen
2287 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2288 cclose
2289 endif
2290
2291 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002292 call assert_fails('call g:Xgetlist([])', 'E715:')
2293 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002294 let s = g:Xsetlist([], 'a', {'abc':1})
2295 call assert_equal(-1, s)
2296
2297 call assert_equal({}, g:Xgetlist({'abc':1}))
2298 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2299 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2300
2301 if a:cchar == 'l'
2302 call assert_equal({}, getloclist(99, {'title': 1}))
2303 endif
2304
2305 " Context related tests
2306 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2307 call assert_equal(0, s)
2308 call test_garbagecollect_now()
2309 let d = g:Xgetlist({'context':1})
2310 call assert_equal([1,2,3], d.context)
2311 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2312 let d = g:Xgetlist({'context':1})
2313 call assert_equal({'color':'green'}, d.context)
2314 call g:Xsetlist([], 'a', {'context':"Context info"})
2315 let d = g:Xgetlist({'context':1})
2316 call assert_equal("Context info", d.context)
2317 call g:Xsetlist([], 'a', {'context':246})
2318 let d = g:Xgetlist({'context':1})
2319 call assert_equal(246, d.context)
2320 " set other Vim data types as context
2321 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2322 if has('channel')
2323 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2324 endif
2325 if has('job')
2326 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2327 endif
2328 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2329 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2330 call g:Xsetlist([], 'a', {'context' : ''})
2331 call test_garbagecollect_now()
2332 if a:cchar == 'l'
2333 " Test for copying context across two different location lists
2334 new | only
2335 let w1_id = win_getid()
2336 let l = [1]
2337 call setloclist(0, [], 'a', {'context':l})
2338 new
2339 let w2_id = win_getid()
2340 call add(l, 2)
2341 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2342 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2343 unlet! l
2344 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2345 only
2346 call setloclist(0, [], 'f')
2347 call assert_equal('', getloclist(0, {'context':1}).context)
2348 endif
2349
2350 " Test for changing the context of previous quickfix lists
2351 call g:Xsetlist([], 'f')
2352 Xexpr "One"
2353 Xexpr "Two"
2354 Xexpr "Three"
2355 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2356 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2357 " Also, check for setting the context using quickfix list number zero.
2358 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2359 call test_garbagecollect_now()
2360 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2361 call assert_equal([1], l.context)
2362 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2363 call assert_equal([2], l.context)
2364 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2365 call assert_equal([3], l.context)
2366
2367 " Test for changing the context through reference and for garbage
2368 " collection of quickfix context
2369 let l = ["red"]
2370 call g:Xsetlist([], ' ', {'context' : l})
2371 call add(l, "blue")
2372 let x = g:Xgetlist({'context' : 1})
2373 call add(x.context, "green")
2374 call assert_equal(["red", "blue", "green"], l)
2375 call assert_equal(["red", "blue", "green"], x.context)
2376 unlet l
2377 call test_garbagecollect_now()
2378 let m = g:Xgetlist({'context' : 1})
2379 call assert_equal(["red", "blue", "green"], m.context)
2380
2381 " Test for setting/getting items
2382 Xexpr ""
2383 let qfprev = g:Xgetlist({'nr':0})
2384 let s = g:Xsetlist([], ' ', {'title':'Green',
2385 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2386 call assert_equal(0, s)
2387 let qfcur = g:Xgetlist({'nr':0})
2388 call assert_true(qfcur.nr == qfprev.nr + 1)
2389 let l = g:Xgetlist({'items':1})
2390 call assert_equal('F1', bufname(l.items[0].bufnr))
2391 call assert_equal(10, l.items[0].lnum)
2392 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2393 \ {'filename':'F2', 'lnum':30}]})
2394 let l = g:Xgetlist({'items':1})
2395 call assert_equal('F2', bufname(l.items[2].bufnr))
2396 call assert_equal(30, l.items[2].lnum)
2397 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2398 let l = g:Xgetlist({'items':1})
2399 call assert_equal('F3', bufname(l.items[0].bufnr))
2400 call assert_equal(40, l.items[0].lnum)
2401 call g:Xsetlist([], 'r', {'items' : []})
2402 let l = g:Xgetlist({'items':1})
2403 call assert_equal(0, len(l.items))
2404
2405 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2406 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2407 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2408 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2409
2410 " Test for getting id of window associated with a location list window
2411 if a:cchar == 'l'
2412 only
2413 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2414 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002415 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002416 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2417 wincmd w
2418 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2419 only
2420 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002421
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002422 " The following used to crash Vim with address sanitizer
2423 call g:Xsetlist([], 'f')
2424 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2425 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002426
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002427 " Try setting the items using a string
2428 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002429
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002430 " Save and restore the quickfix stack
2431 call g:Xsetlist([], 'f')
2432 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2433 Xexpr "File1:10:Line1"
2434 Xexpr "File2:20:Line2"
2435 Xexpr "File3:30:Line3"
2436 let last_qf = g:Xgetlist({'nr':'$'}).nr
2437 call assert_equal(3, last_qf)
2438 let qstack = []
2439 for i in range(1, last_qf)
2440 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2441 endfor
2442 call g:Xsetlist([], 'f')
2443 for i in range(len(qstack))
2444 call g:Xsetlist([], ' ', qstack[i])
2445 endfor
2446 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2447 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2448 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2449 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2450 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002451
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002452 " Swap two quickfix lists
2453 Xexpr "File1:10:Line10"
2454 Xexpr "File2:20:Line20"
2455 Xexpr "File3:30:Line30"
2456 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2457 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2458 let l1=g:Xgetlist({'nr':1,'all':1})
2459 let l2=g:Xgetlist({'nr':2,'all':1})
2460 let save_id = l1.id
2461 let l1.id=l2.id
2462 let l2.id=save_id
2463 call g:Xsetlist([], 'r', l1)
2464 call g:Xsetlist([], 'r', l2)
2465 let newl1=g:Xgetlist({'nr':1,'all':1})
2466 let newl2=g:Xgetlist({'nr':2,'all':1})
2467 call assert_equal('Fruits', newl1.title)
2468 call assert_equal(['Fruits'], newl1.context)
2469 call assert_equal('Line20', newl1.items[0].text)
2470 call assert_equal('Colors', newl2.title)
2471 call assert_equal(['Colors'], newl2.context)
2472 call assert_equal('Line10', newl2.items[0].text)
2473 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002474
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002475 " Cannot specify both a non-empty list argument and a dict argument
2476 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002477endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002478
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002479func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002480 call Xproperty_tests('c')
2481 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002482endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002483
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002484" Test for setting the current index in the location/quickfix list
2485func Xtest_setqfidx(cchar)
2486 call s:setup_commands(a:cchar)
2487
2488 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2489 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2490 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2491
2492 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2493 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2494 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2495 Xolder 2
2496 Xopen
2497 call assert_equal(3, line('.'))
2498 Xnewer
2499 call assert_equal(2, line('.'))
2500 Xnewer
2501 call assert_equal(2, line('.'))
2502 " Update the current index with the quickfix window open
2503 wincmd w
2504 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2505 Xopen
2506 call assert_equal(3, line('.'))
2507 Xclose
2508
2509 " Set the current index to the last entry
2510 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2511 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2512 " A large value should set the index to the last index
2513 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2514 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2515 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2516 " Invalid index values
2517 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2518 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2519 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2520 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2521 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2522 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2523 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2524
2525 call g:Xsetlist([], 'f')
2526 new | only
2527endfunc
2528
2529func Test_setqfidx()
2530 call Xtest_setqfidx('c')
2531 call Xtest_setqfidx('l')
2532endfunc
2533
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002534" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002535func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002536 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002537endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002538
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002539func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002540 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2541 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2542
2543 let g:acmds = []
2544 cexpr "F1:10:Line 10"
2545 caddexpr "F1:20:Line 20"
2546 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002547 cexpr ""
2548 caddexpr ""
2549 cgetexpr ""
2550 silent! cexpr non_existing_func()
2551 silent! caddexpr non_existing_func()
2552 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002553 let l = ['precexpr',
2554 \ 'postcexpr',
2555 \ 'precaddexpr',
2556 \ 'postcaddexpr',
2557 \ 'precgetexpr',
2558 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002559 \ 'precexpr',
2560 \ 'postcexpr',
2561 \ 'precaddexpr',
2562 \ 'postcaddexpr',
2563 \ 'precgetexpr',
2564 \ 'postcgetexpr',
2565 \ 'precexpr',
2566 \ 'precaddexpr',
2567 \ 'precgetexpr']
2568 call assert_equal(l, g:acmds)
2569
2570 let g:acmds = []
2571 enew! | call append(0, "F2:10:Line 10")
2572 cbuffer!
2573 enew! | call append(0, "F2:20:Line 20")
2574 cgetbuffer
2575 enew! | call append(0, "F2:30:Line 30")
2576 caddbuffer
2577 new
2578 let bnum = bufnr('%')
2579 bunload
2580 exe 'silent! cbuffer! ' . bnum
2581 exe 'silent! cgetbuffer ' . bnum
2582 exe 'silent! caddbuffer ' . bnum
2583 enew!
2584 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002585 \ 'postcbuffer',
2586 \ 'precgetbuffer',
2587 \ 'postcgetbuffer',
2588 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002589 \ 'postcaddbuffer',
2590 \ 'precbuffer',
2591 \ 'precgetbuffer',
2592 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002593 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002594
2595 call writefile(['Xtest:1:Line1'], 'Xtest')
2596 call writefile([], 'Xempty')
2597 let g:acmds = []
2598 cfile Xtest
2599 caddfile Xtest
2600 cgetfile Xtest
2601 cfile Xempty
2602 caddfile Xempty
2603 cgetfile Xempty
2604 silent! cfile do_not_exist
2605 silent! caddfile do_not_exist
2606 silent! cgetfile do_not_exist
2607 let l = ['precfile',
2608 \ 'postcfile',
2609 \ 'precaddfile',
2610 \ 'postcaddfile',
2611 \ 'precgetfile',
2612 \ 'postcgetfile',
2613 \ 'precfile',
2614 \ 'postcfile',
2615 \ 'precaddfile',
2616 \ 'postcaddfile',
2617 \ 'precgetfile',
2618 \ 'postcgetfile',
2619 \ 'precfile',
2620 \ 'postcfile',
2621 \ 'precaddfile',
2622 \ 'postcaddfile',
2623 \ 'precgetfile',
2624 \ 'postcgetfile']
2625 call assert_equal(l, g:acmds)
2626
2627 let g:acmds = []
2628 helpgrep quickfix
2629 silent! helpgrep non_existing_help_topic
2630 vimgrep test Xtest
2631 vimgrepadd test Xtest
2632 silent! vimgrep non_existing_test Xtest
2633 silent! vimgrepadd non_existing_test Xtest
2634 set makeprg=
2635 silent! make
2636 set makeprg&
2637 let l = ['prehelpgrep',
2638 \ 'posthelpgrep',
2639 \ 'prehelpgrep',
2640 \ 'posthelpgrep',
2641 \ 'previmgrep',
2642 \ 'postvimgrep',
2643 \ 'previmgrepadd',
2644 \ 'postvimgrepadd',
2645 \ 'previmgrep',
2646 \ 'postvimgrep',
2647 \ 'previmgrepadd',
2648 \ 'postvimgrepadd',
2649 \ 'premake',
2650 \ 'postmake']
2651 call assert_equal(l, g:acmds)
2652
2653 if has('unix')
2654 " Run this test only on Unix-like systems. The grepprg may not be set on
2655 " non-Unix systems.
2656 " The following lines are used for the grep test. Don't remove.
2657 " Grep_Autocmd_Text: Match 1
2658 " GrepAdd_Autocmd_Text: Match 2
2659 let g:acmds = []
2660 silent grep Grep_Autocmd_Text test_quickfix.vim
2661 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2662 silent grep abc123def Xtest
2663 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002664 set grepprg=internal
2665 silent grep Grep_Autocmd_Text test_quickfix.vim
2666 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2667 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2668 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2669 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002670 let l = ['pregrep',
2671 \ 'postgrep',
2672 \ 'pregrepadd',
2673 \ 'postgrepadd',
2674 \ 'pregrep',
2675 \ 'postgrep',
2676 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002677 \ 'postgrepadd',
2678 \ 'pregrep',
2679 \ 'postgrep',
2680 \ 'pregrepadd',
2681 \ 'postgrepadd',
2682 \ 'prelgrep',
2683 \ 'postlgrep',
2684 \ 'prelgrepadd',
2685 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002686 call assert_equal(l, g:acmds)
2687 endif
2688
2689 call delete('Xtest')
2690 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002691 au! QuickFixCmdPre
2692 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002693endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002694
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002695func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002696 set efm=%m
2697 lgetexpr '?'
2698
2699 try
2700 call DoesNotExit()
2701 catch
2702 lgetexpr '1'
2703 finally
2704 lgetexpr '1'
2705 endtry
2706
2707 call assert_equal('1', getloclist(0)[0].text)
2708
2709 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002710endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002711
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002712func Test_caddbuffer_wrong()
2713 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002714 let save_efm = &efm
2715 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2716 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2717 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002718 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002719 bwipe!
2720endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002721
2722func Test_caddexpr_wrong()
2723 " This used to cause a memory access in freed memory.
2724 cbuffer
2725 cbuffer
2726 copen
2727 let save_efm = &efm
2728 set efm=%
2729 call assert_fails('caddexpr ""', 'E376:')
2730 let &efm = save_efm
2731endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002732
2733func Test_dirstack_cleanup()
2734 " This used to cause a memory access in freed memory.
2735 let save_efm = &efm
2736 lexpr '0'
2737 lopen
2738 fun X(c)
2739 let save_efm=&efm
2740 set efm=%D%f
2741 if a:c == 'c'
2742 caddexpr '::'
2743 else
2744 laddexpr ':0:0'
2745 endif
2746 let &efm=save_efm
2747 endfun
2748 call X('c')
2749 call X('l')
2750 call setqflist([], 'r')
2751 caddbuffer
2752 let &efm = save_efm
2753endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002754
2755" Tests for jumping to entries from the location list window and quickfix
2756" window
2757func Test_cwindow_jump()
2758 set efm=%f%%%l%%%m
2759 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2760 lopen | only
2761 lfirst
2762 call assert_true(winnr('$') == 2)
2763 call assert_true(winnr() == 1)
2764 " Location list for the new window should be set
2765 call assert_true(getloclist(0)[2].text == 'Line 30')
2766
2767 " Open a scratch buffer
2768 " Open a new window and create a location list
2769 " Open the location list window and close the other window
2770 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002771 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002772 " should not be used.
2773 enew | only
2774 set buftype=nofile
2775 below new
2776 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2777 lopen
2778 2wincmd c
2779 lnext
2780 call assert_true(winnr('$') == 3)
2781 call assert_true(winnr() == 2)
2782
2783 " Open two windows with two different location lists
2784 " Open the location list window and close the previous window
2785 " Jump to an entry in the location list window
2786 " Should open the file in the first window and not set the location list.
2787 enew | only
2788 lgetexpr ["F1%5%Line 5"]
2789 below new
2790 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2791 lopen
2792 2wincmd c
2793 lnext
2794 call assert_true(winnr() == 1)
2795 call assert_true(getloclist(0)[0].text == 'Line 5')
2796
2797 enew | only
2798 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2799 copen
2800 cnext
2801 call assert_true(winnr('$') == 2)
2802 call assert_true(winnr() == 1)
2803
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002804 " open the quickfix buffer in two windows and jump to an entry. Should open
2805 " the file in the first quickfix window.
2806 enew | only
2807 copen
2808 let bnum = bufnr('')
2809 exe 'sbuffer ' . bnum
2810 wincmd b
2811 cfirst
2812 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002813 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002814 enew | only
2815 exe 'sb' bnum
2816 exe 'botright sb' bnum
2817 wincmd t
2818 clast
2819 call assert_equal(2, winnr())
2820 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2821 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2822
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002823 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002824 " window by wrapping around the window list.
2825 enew | only
2826 call setloclist(0, [], 'f')
2827 new | new
2828 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2829 lopen
2830 1close
2831 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2832 lnext
2833 call assert_equal(3, winnr())
2834 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2835
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002836 enew | only
2837 set efm&vim
2838endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002839
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002840func Test_cwindow_highlight()
2841 CheckScreendump
2842
2843 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002844 call setline(1, ['some', 'text', 'with', 'matches'])
2845 write XCwindow
2846 vimgrep e XCwindow
2847 redraw
2848 cwindow 4
2849 END
2850 call writefile(lines, 'XtestCwindow')
2851 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2852 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2853
2854 call term_sendkeys(buf, ":cnext\<CR>")
2855 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2856
2857 " clean up
2858 call StopVimInTerminal(buf)
2859 call delete('XtestCwindow')
2860 call delete('XCwindow')
2861endfunc
2862
Bram Moolenaaree85df32017-03-19 14:19:50 +01002863func XvimgrepTests(cchar)
2864 call s:setup_commands(a:cchar)
2865
2866 call writefile(['Editor:VIM vim',
2867 \ 'Editor:Emacs EmAcS',
2868 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002869 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002870
2871 " Error cases
2872 call assert_fails('Xvimgrep /abc *', 'E682:')
2873
2874 let @/=''
2875 call assert_fails('Xvimgrep // *', 'E35:')
2876
2877 call assert_fails('Xvimgrep abc', 'E683:')
2878 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2879 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2880
2881 Xexpr ""
2882 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002883 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002884 let l = g:Xgetlist()
2885 call assert_equal(2, len(l))
2886 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2887
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002888 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002889 let l = g:Xgetlist()
2890 call assert_equal(2, len(l))
2891 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002892 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002893 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002894 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002895
2896 1Xvimgrep ?Editor? Xtestfile*
2897 let l = g:Xgetlist()
2898 call assert_equal(1, len(l))
2899 call assert_equal('Editor:VIM vim', l[0].text)
2900
2901 edit +3 Xtestfile2
2902 Xvimgrep +\cemacs+j Xtestfile1
2903 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002904 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002905 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2906
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002907 " Test for unloading a buffer after vimgrep searched the buffer
2908 %bwipe
2909 Xvimgrep /Editor/j Xtestfile*
2910 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2911 call assert_equal([], getbufinfo('Xtestfile2'))
2912
Bram Moolenaaree85df32017-03-19 14:19:50 +01002913 call delete('Xtestfile1')
2914 call delete('Xtestfile2')
2915endfunc
2916
2917" Tests for the :vimgrep command
2918func Test_vimgrep()
2919 call XvimgrepTests('c')
2920 call XvimgrepTests('l')
2921endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002922
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002923func Test_vimgrep_wildcards_expanded_once()
2924 new X[id-01] file.txt
2925 call setline(1, 'some text to search for')
2926 vimgrep text %
2927 bwipe!
2928endfunc
2929
Bram Moolenaar1c299432018-10-28 14:36:09 +01002930" Test for incsearch highlighting of the :vimgrep pattern
2931" This test used to cause "E315: ml_get: invalid lnum" errors.
2932func Test_vimgrep_incsearch()
2933 enew
2934 set incsearch
2935 call test_override("char_avail", 1)
2936
2937 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2938 let l = getqflist()
2939 call assert_equal(2, len(l))
2940
2941 call test_override("ALL", 0)
2942 set noincsearch
2943endfunc
2944
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002945" Test vimgrep with the last search pattern not set
2946func Test_vimgrep_with_no_last_search_pat()
2947 let lines =<< trim [SCRIPT]
2948 call assert_fails('vimgrep // *', 'E35:')
2949 call writefile(v:errors, 'Xresult')
2950 qall!
2951 [SCRIPT]
2952 call writefile(lines, 'Xscript')
2953 if RunVim([], [], '--clean -S Xscript')
2954 call assert_equal([], readfile('Xresult'))
2955 endif
2956 call delete('Xscript')
2957 call delete('Xresult')
2958endfunc
2959
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002960" Test vimgrep without swap file
2961func Test_vimgrep_without_swap_file()
2962 let lines =<< trim [SCRIPT]
2963 vimgrep grep test_c*
2964 call writefile(['done'], 'Xresult')
2965 qall!
2966 [SCRIPT]
2967 call writefile(lines, 'Xscript')
2968 if RunVim([], [], '--clean -n -S Xscript Xscript')
2969 call assert_equal(['done'], readfile('Xresult'))
2970 endif
2971 call delete('Xscript')
2972 call delete('Xresult')
2973endfunc
2974
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002975func Test_vimgrep_existing_swapfile()
2976 call writefile(['match apple with apple'], 'Xapple')
2977 call writefile(['swapfile'], '.Xapple.swp')
2978 let g:foundSwap = 0
2979 let g:ignoreSwapExists = 1
2980 augroup grep
2981 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2982 augroup END
2983 vimgrep apple Xapple
2984 call assert_equal(1, g:foundSwap)
2985 call assert_match('.Xapple.swo', swapname(''))
2986
2987 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002988 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002989 augroup grep
2990 au! SwapExists
2991 augroup END
2992 unlet g:ignoreSwapExists
2993endfunc
2994
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002995func XfreeTests(cchar)
2996 call s:setup_commands(a:cchar)
2997
2998 enew | only
2999
3000 " Deleting the quickfix stack should work even When the current list is
3001 " somewhere in the middle of the stack
3002 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3003 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3004 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3005 Xolder
3006 call g:Xsetlist([], 'f')
3007 call assert_equal(0, len(g:Xgetlist()))
3008
3009 " After deleting the stack, adding a new list should create a stack with a
3010 " single list.
3011 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3012 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3013
3014 " Deleting the stack from a quickfix window should update/clear the
3015 " quickfix/location list window.
3016 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3017 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3018 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3019 Xolder
3020 Xwindow
3021 call g:Xsetlist([], 'f')
3022 call assert_equal(2, winnr('$'))
3023 call assert_equal(1, line('$'))
3024 Xclose
3025
3026 " Deleting the stack from a non-quickfix window should update/clear the
3027 " quickfix/location list window.
3028 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3029 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3030 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3031 Xolder
3032 Xwindow
3033 wincmd p
3034 call g:Xsetlist([], 'f')
3035 call assert_equal(0, len(g:Xgetlist()))
3036 wincmd p
3037 call assert_equal(2, winnr('$'))
3038 call assert_equal(1, line('$'))
3039
3040 " After deleting the location list stack, if the location list window is
3041 " opened, then a new location list should be created. So opening the
3042 " location list window again should not create a new window.
3043 if a:cchar == 'l'
3044 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3045 wincmd p
3046 lopen
3047 call assert_equal(2, winnr('$'))
3048 endif
3049 Xclose
3050endfunc
3051
Bram Moolenaar74240d32017-12-10 15:26:15 +01003052" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003053func Test_qf_free()
3054 call XfreeTests('c')
3055 call XfreeTests('l')
3056endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003057
3058" Test for buffer overflow when parsing lines and adding new entries to
3059" the quickfix list.
3060func Test_bufoverflow()
3061 set efm=%f:%l:%m
3062 cgetexpr ['File1:100:' . repeat('x', 1025)]
3063
3064 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3065 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3066
3067 set efm=%DEntering\ directory\ %f,%f:%l:%m
3068 cgetexpr ['Entering directory ' . repeat('a', 1006),
3069 \ 'File1:10:Hello World']
3070 set efm&vim
3071endfunc
3072
Bram Moolenaar875feea2017-06-11 16:07:51 +02003073" Tests for getting the quickfix stack size
3074func XsizeTests(cchar)
3075 call s:setup_commands(a:cchar)
3076
3077 call g:Xsetlist([], 'f')
3078 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003079 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3080 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003081
3082 Xexpr "File1:10:Line1"
3083 Xexpr "File2:20:Line2"
3084 Xexpr "File3:30:Line3"
3085 Xolder | Xolder
3086 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3087 call g:Xsetlist([], 'f')
3088
3089 Xexpr "File1:10:Line1"
3090 Xexpr "File2:20:Line2"
3091 Xexpr "File3:30:Line3"
3092 Xolder | Xolder
3093 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3094 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3095endfunc
3096
3097func Test_Qf_Size()
3098 call XsizeTests('c')
3099 call XsizeTests('l')
3100endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003101
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003102func Test_cclose_from_copen()
3103 augroup QF_Test
3104 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003105 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003106 augroup END
3107 copen
3108 augroup QF_Test
3109 au!
3110 augroup END
3111 augroup! QF_Test
3112endfunc
3113
Bram Moolenaar18141832017-06-25 21:17:25 +02003114func Test_cclose_in_autocmd()
3115 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3116 " event will be triggered.
3117 call test_override('starting', 1)
3118 augroup QF_Test
3119 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003120 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003121 augroup END
3122 copen
3123 augroup QF_Test
3124 au!
3125 augroup END
3126 augroup! QF_Test
3127 call test_override('starting', 0)
3128endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003129
Bram Moolenaar379fb762018-08-30 15:58:28 +02003130" Check that ":file" without an argument is possible even when "curbuf_lock"
3131" is set.
3132func Test_file_from_copen()
3133 " Works without argument.
3134 augroup QF_Test
3135 au!
3136 au FileType qf file
3137 augroup END
3138 copen
3139
3140 augroup QF_Test
3141 au!
3142 augroup END
3143 cclose
3144
3145 " Fails with argument.
3146 augroup QF_Test
3147 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003148 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003149 augroup END
3150 copen
3151 augroup QF_Test
3152 au!
3153 augroup END
3154 cclose
3155
3156 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003157endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003158
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003159func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003160 augroup QF_Test
3161 au!
3162 au FileType qf resize 5
3163 augroup END
3164 try
3165 " This should succeed without any exception. No other buffers are
3166 " involved in the autocmd.
3167 copen
3168 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003169 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003170 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003171 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003172 augroup! QF_Test
3173 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003174endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003175
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003176func Test_vimgrep_with_textlock()
3177 new
3178
3179 " Simple way to execute something with "textwinlock" set.
3180 " Check that vimgrep without jumping can be executed.
3181 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3182 normal ax
3183 let qflist = getqflist()
3184 call assert_true(len(qflist) > 0)
3185 call assert_match('RunTheTest', qflist[0].text)
3186 call setqflist([], 'r')
3187 au! InsertCharPre
3188
3189 " Check that vimgrepadd without jumping can be executed.
3190 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3191 normal ax
3192 let qflist = getqflist()
3193 call assert_true(len(qflist) > 0)
3194 call assert_match('RunTheTest', qflist[0].text)
3195 call setqflist([], 'r')
3196 au! InsertCharPre
3197
3198 " Check that lvimgrep without jumping can be executed.
3199 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3200 normal ax
3201 let qflist = getloclist(0)
3202 call assert_true(len(qflist) > 0)
3203 call assert_match('RunTheTest', qflist[0].text)
3204 call setloclist(0, [], 'r')
3205 au! InsertCharPre
3206
3207 " Check that lvimgrepadd without jumping can be executed.
3208 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3209 normal ax
3210 let qflist = getloclist(0)
3211 call assert_true(len(qflist) > 0)
3212 call assert_match('RunTheTest', qflist[0].text)
3213 call setloclist(0, [], 'r')
3214 au! InsertCharPre
3215
3216 " trying to jump will give an error
3217 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3218 call assert_fails('normal ax', 'E565:')
3219 au! InsertCharPre
3220
3221 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3222 call assert_fails('normal ax', 'E565:')
3223 au! InsertCharPre
3224
3225 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3226 call assert_fails('normal ax', 'E565:')
3227 au! InsertCharPre
3228
3229 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3230 call assert_fails('normal ax', 'E565:')
3231 au! InsertCharPre
3232
3233 bwipe!
3234endfunc
3235
Bram Moolenaara8788f42017-07-19 17:06:20 +02003236" Tests for the quickfix buffer b:changedtick variable
3237func Xchangedtick_tests(cchar)
3238 call s:setup_commands(a:cchar)
3239
3240 new | only
3241
3242 Xexpr "" | Xexpr "" | Xexpr ""
3243
3244 Xopen
3245 Xolder
3246 Xolder
3247 Xaddexpr "F1:10:Line10"
3248 Xaddexpr "F2:20:Line20"
3249 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3250 call g:Xsetlist([], 'f')
3251 call assert_equal(8, getbufvar('%', 'changedtick'))
3252 Xclose
3253endfunc
3254
3255func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003256 call Xchangedtick_tests('c')
3257 call Xchangedtick_tests('l')
3258endfunc
3259
3260" Tests for parsing an expression using setqflist()
3261func Xsetexpr_tests(cchar)
3262 call s:setup_commands(a:cchar)
3263
3264 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003265 call g:Xsetlist([], ' ', {'lines' : t})
3266 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003267
3268 let l = g:Xgetlist()
3269 call assert_equal(3, len(l))
3270 call assert_equal(20, l[1].lnum)
3271 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003272 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003273 let l = g:Xgetlist()
3274 call assert_equal(1, len(l))
3275 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003276 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3277 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003278
3279 call g:Xsetlist([], 'f')
3280 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003281 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3282 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3283 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3284 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003285 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3286 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003287
3288 " Adding entries using a custom efm
3289 set efm&
3290 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3291 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3292 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3293 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3294 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3295 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3296 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3297 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003298endfunc
3299
3300func Test_setexpr()
3301 call Xsetexpr_tests('c')
3302 call Xsetexpr_tests('l')
3303endfunc
3304
3305" Tests for per quickfix/location list directory stack
3306func Xmultidirstack_tests(cchar)
3307 call s:setup_commands(a:cchar)
3308
3309 call g:Xsetlist([], 'f')
3310 Xexpr "" | Xexpr ""
3311
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003312 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3313 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3314 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3315 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003316
3317 let l1 = g:Xgetlist({'nr':1, 'items':1})
3318 let l2 = g:Xgetlist({'nr':2, 'items':1})
3319 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3320 call assert_equal(3, l1.items[1].lnum)
3321 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3322 call assert_equal(5, l2.items[1].lnum)
3323endfunc
3324
3325func Test_multidirstack()
3326 call mkdir('Xone/a', 'p')
3327 call mkdir('Xtwo/a', 'p')
3328 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3329 call writefile(lines, 'Xone/a/one.txt')
3330 call writefile(lines, 'Xtwo/a/two.txt')
3331 let save_efm = &efm
3332 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3333
3334 call Xmultidirstack_tests('c')
3335 call Xmultidirstack_tests('l')
3336
3337 let &efm = save_efm
3338 call delete('Xone', 'rf')
3339 call delete('Xtwo', 'rf')
3340endfunc
3341
3342" Tests for per quickfix/location list file stack
3343func Xmultifilestack_tests(cchar)
3344 call s:setup_commands(a:cchar)
3345
3346 call g:Xsetlist([], 'f')
3347 Xexpr "" | Xexpr ""
3348
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003349 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3350 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3351 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3352 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003353
3354 let l1 = g:Xgetlist({'nr':1, 'items':1})
3355 let l2 = g:Xgetlist({'nr':2, 'items':1})
3356 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3357 call assert_equal(3, l1.items[1].lnum)
3358 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3359 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003360
3361 " Test for start of a new error line in the same line where a previous
3362 " error line ends with a file stack.
3363 let efm_val = 'Error\ l%l\ in\ %f,'
3364 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3365 let l = g:Xgetlist({'lines' : [
3366 \ '(one.txt',
3367 \ 'Error l4 in one.txt',
3368 \ ') (two.txt',
3369 \ 'Error l6 in two.txt',
3370 \ ')',
3371 \ 'Error l8 in one.txt'
3372 \ ], 'efm' : efm_val})
3373 call assert_equal(3, len(l.items))
3374 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3375 call assert_equal(4, l.items[0].lnum)
3376 call assert_equal('one.txt', l.items[0].text)
3377 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3378 call assert_equal(6, l.items[1].lnum)
3379 call assert_equal('two.txt', l.items[1].text)
3380 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3381 call assert_equal(8, l.items[2].lnum)
3382 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003383endfunc
3384
3385func Test_multifilestack()
3386 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3387 call writefile(lines, 'one.txt')
3388 call writefile(lines, 'two.txt')
3389 let save_efm = &efm
3390 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3391
3392 call Xmultifilestack_tests('c')
3393 call Xmultifilestack_tests('l')
3394
3395 let &efm = save_efm
3396 call delete('one.txt')
3397 call delete('two.txt')
3398endfunc
3399
3400" Tests for per buffer 'efm' setting
3401func Test_perbuf_efm()
3402 call writefile(["File1-10-Line10"], 'one.txt')
3403 call writefile(["File2#20#Line20"], 'two.txt')
3404 set efm=%f#%l#%m
3405 new | only
3406 new
3407 setlocal efm=%f-%l-%m
3408 cfile one.txt
3409 wincmd w
3410 caddfile two.txt
3411
3412 let l = getqflist()
3413 call assert_equal(10, l[0].lnum)
3414 call assert_equal('Line20', l[1].text)
3415
3416 set efm&
3417 new | only
3418 call delete('one.txt')
3419 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003420endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003421
3422" Open multiple help windows using ":lhelpgrep
3423" This test used to crash Vim
3424func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003425 new | only
3426 lhelpgrep window
3427 lopen
3428 e#
3429 lhelpgrep buffer
3430 call assert_equal(3, winnr('$'))
3431 call assert_true(len(getloclist(1)) != 0)
3432 call assert_true(len(getloclist(2)) != 0)
3433 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003434endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003435
3436" Tests for adding new quickfix lists using setqflist()
3437func XaddQf_tests(cchar)
3438 call s:setup_commands(a:cchar)
3439
3440 " Create a new list using ' ' for action
3441 call g:Xsetlist([], 'f')
3442 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3443 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3444 call assert_equal(1, l.nr)
3445 call assert_equal('Test1', l.title)
3446
3447 " Create a new list using ' ' for action and '$' for 'nr'
3448 call g:Xsetlist([], 'f')
3449 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3450 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3451 call assert_equal(1, l.nr)
3452 call assert_equal('Test2', l.title)
3453
3454 " Create a new list using 'a' for action
3455 call g:Xsetlist([], 'f')
3456 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3457 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3458 call assert_equal(1, l.nr)
3459 call assert_equal('Test3', l.title)
3460
3461 " Create a new list using 'a' for action and '$' for 'nr'
3462 call g:Xsetlist([], 'f')
3463 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3464 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3465 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3466 call assert_equal(1, l.nr)
3467 call assert_equal('Test4', l.title)
3468
3469 " Adding a quickfix list should remove all the lists following the current
3470 " list.
3471 Xexpr "" | Xexpr "" | Xexpr ""
3472 silent! 10Xolder
3473 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3474 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3475 call assert_equal(2, l.nr)
3476 call assert_equal('Test5', l.title)
3477
3478 " Add a quickfix list using '$' as the list number.
3479 let lastqf = g:Xgetlist({'nr':'$'}).nr
3480 silent! 99Xolder
3481 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3482 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3483 call assert_equal(lastqf + 1, l.nr)
3484 call assert_equal('Test6', l.title)
3485
3486 " Add a quickfix list using 'nr' set to one more than the quickfix
3487 " list size.
3488 let lastqf = g:Xgetlist({'nr':'$'}).nr
3489 silent! 99Xolder
3490 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3491 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3492 call assert_equal(lastqf + 1, l.nr)
3493 call assert_equal('Test7', l.title)
3494
3495 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3496 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3497 silent! 99Xolder
3498 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3499 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3500 call assert_equal(10, l.nr)
3501 call assert_equal('Test8', l.title)
3502
3503 " Add a quickfix list using 'nr' set to a value greater than 10
3504 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3505
3506 " Try adding a quickfix list with 'nr' set to a value greater than the
3507 " quickfix list size but less than 10.
3508 call g:Xsetlist([], 'f')
3509 Xexpr "" | Xexpr "" | Xexpr ""
3510 silent! 99Xolder
3511 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3512
3513 " Add a quickfix list using 'nr' set to a some string or list
3514 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3515endfunc
3516
3517func Test_add_qf()
3518 call XaddQf_tests('c')
3519 call XaddQf_tests('l')
3520endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003521
3522" Test for getting the quickfix list items from some text without modifying
3523" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003524func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003525 call s:setup_commands(a:cchar)
3526 call g:Xsetlist([], 'f')
3527
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003528 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003529 call assert_equal(2, len(l))
3530 call assert_equal(30, l[1].lnum)
3531
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003532 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3533 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3534 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3535 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003536
Bram Moolenaar36538222017-09-02 19:51:44 +02003537 " Parse text using a custom efm
3538 set efm&
3539 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3540 call assert_equal('Line30', l[0].text)
3541 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3542 call assert_equal('File3:30:Line30', l[0].text)
3543 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3544 call assert_equal({}, l)
3545 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3546 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3547
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003548 " Make sure that the quickfix stack is not modified
3549 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3550endfunc
3551
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003552func Test_get_list_from_lines()
3553 call XgetListFromLines('c')
3554 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003555endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003556
3557" Tests for the quickfix list id
3558func Xqfid_tests(cchar)
3559 call s:setup_commands(a:cchar)
3560
3561 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003562 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003563 Xexpr ''
3564 let start_id = g:Xgetlist({'id' : 0}).id
3565 Xexpr '' | Xexpr ''
3566 Xolder
3567 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3568 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3569 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003570 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003571 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003572 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3573 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003574
3575 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3576 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003577 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003578 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3579 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3580 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3581
3582 let qfid = g:Xgetlist({'id':0, 'nr':0})
3583 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003584 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003585endfunc
3586
3587func Test_qf_id()
3588 call Xqfid_tests('c')
3589 call Xqfid_tests('l')
3590endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003591
3592func Xqfjump_tests(cchar)
3593 call s:setup_commands(a:cchar)
3594
3595 call writefile(["Line1\tFoo", "Line2"], 'F1')
3596 call writefile(["Line1\tBar", "Line2"], 'F2')
3597 call writefile(["Line1\tBaz", "Line2"], 'F3')
3598
3599 call g:Xsetlist([], 'f')
3600
3601 " Tests for
3602 " Jumping to a line using a pattern
3603 " Jumping to a column greater than the last column in a line
3604 " Jumping to a line greater than the last line in the file
3605 let l = []
3606 for i in range(1, 7)
3607 call add(l, {})
3608 endfor
3609 let l[0].filename='F1'
3610 let l[0].pattern='Line1'
3611 let l[1].filename='F2'
3612 let l[1].pattern='Line1'
3613 let l[2].filename='F3'
3614 let l[2].pattern='Line1'
3615 let l[3].filename='F3'
3616 let l[3].lnum=1
3617 let l[3].col=9
3618 let l[3].vcol=1
3619 let l[4].filename='F3'
3620 let l[4].lnum=99
3621 let l[5].filename='F3'
3622 let l[5].lnum=1
3623 let l[5].col=99
3624 let l[5].vcol=1
3625 let l[6].filename='F3'
3626 let l[6].pattern='abcxyz'
3627
3628 call g:Xsetlist([], ' ', {'items' : l})
3629 Xopen | only
3630 2Xnext
3631 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003632 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003633 Xnext
3634 call assert_equal(7, col('.'))
3635 Xnext
3636 call assert_equal(2, line('.'))
3637 Xnext
3638 call assert_equal(9, col('.'))
3639 2
3640 Xnext
3641 call assert_equal(2, line('.'))
3642
3643 if a:cchar == 'l'
3644 " When jumping to a location list entry in the location list window and
3645 " no usable windows are available, then a new window should be opened.
3646 enew! | new | only
3647 call g:Xsetlist([], 'f')
3648 setlocal buftype=nofile
3649 new
3650 call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']})
3651 Xopen
3652 let winid = win_getid()
3653 wincmd p
3654 close
3655 call win_gotoid(winid)
3656 Xnext
3657 call assert_equal(3, winnr('$'))
3658 call assert_equal(1, winnr())
3659 call assert_equal(2, line('.'))
3660
3661 " When jumping to an entry in the location list window and the window
3662 " associated with the location list is not present and a window containing
3663 " the file is already present, then that window should be used.
3664 close
3665 belowright new
3666 call g:Xsetlist([], 'f')
3667 edit F3
3668 call win_gotoid(winid)
3669 Xlast
3670 call assert_equal(3, winnr())
3671 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3672 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3673 endif
3674
3675 " Cleanup
3676 enew!
3677 new | only
3678
3679 call delete('F1')
3680 call delete('F2')
3681 call delete('F3')
3682endfunc
3683
3684func Test_qfjump()
3685 call Xqfjump_tests('c')
3686 call Xqfjump_tests('l')
3687endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003688
3689" Tests for the getqflist() and getloclist() functions when the list is not
3690" present or is empty
3691func Xgetlist_empty_tests(cchar)
3692 call s:setup_commands(a:cchar)
3693
3694 " Empty quickfix stack
3695 call g:Xsetlist([], 'f')
3696 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3697 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3698 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3699 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3700 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3701 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3702 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3703 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003704 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003705 if a:cchar == 'c'
3706 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003707 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003708 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3709 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003710 else
3711 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3712 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003713 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003714 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003715 \ g:Xgetlist({'all' : 0}))
3716 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003717
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003718 " Quickfix window with empty stack
3719 silent! Xopen
3720 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003721 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003722 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3723 Xclose
3724
Bram Moolenaara6d48492017-12-12 22:45:31 +01003725 " Empty quickfix list
3726 Xexpr ""
3727 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3728 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3729 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3730 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3731 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3732 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3733 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3734 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003735 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003736
3737 let qfid = g:Xgetlist({'id' : 0}).id
3738 call g:Xsetlist([], 'f')
3739
3740 " Non-existing quickfix identifier
3741 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3742 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3743 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3744 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3745 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3746 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3747 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3748 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003749 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003750 if a:cchar == 'c'
3751 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3752 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003753 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003754 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3755 else
3756 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3757 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003758 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3759 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003760 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3761 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003762
3763 " Non-existing quickfix list number
3764 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3765 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3766 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3767 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3768 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3769 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3770 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3771 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003772 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003773 if a:cchar == 'c'
3774 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3775 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003776 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3777 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003778 else
3779 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3780 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003781 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3782 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003783 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003784endfunc
3785
3786func Test_getqflist()
3787 call Xgetlist_empty_tests('c')
3788 call Xgetlist_empty_tests('l')
3789endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003790
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003791func Test_getqflist_invalid_nr()
3792 " The following commands used to crash Vim
3793 cexpr ""
3794 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3795
3796 " Cleanup
3797 call setqflist([], 'r')
3798endfunc
3799
Bram Moolenaarb254af32017-12-18 19:48:58 +01003800" Tests for the quickfix/location list changedtick
3801func Xqftick_tests(cchar)
3802 call s:setup_commands(a:cchar)
3803
3804 call g:Xsetlist([], 'f')
3805
3806 Xexpr "F1:10:Line10"
3807 let qfid = g:Xgetlist({'id' : 0}).id
3808 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3809 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3810 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3811 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3812 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3813 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3814 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3815 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3816 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3817
3818 enew!
3819 call append(0, ["F5:50:L50", "F6:60:L60"])
3820 Xaddbuffer
3821 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3822 enew!
3823
3824 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3825 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3826 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3827 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3828 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3829 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3830 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3831 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3832 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3833 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3834 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3835
3836 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3837 Xfile Xone
3838 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3839 Xaddfile Xone
3840 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3841
3842 " Test case for updating a non-current quickfix list
3843 call g:Xsetlist([], 'f')
3844 Xexpr "F1:1:L1"
3845 Xexpr "F2:2:L2"
3846 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3847 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3848 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3849
3850 call delete("Xone")
3851endfunc
3852
3853func Test_qf_tick()
3854 call Xqftick_tests('c')
3855 call Xqftick_tests('l')
3856endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003857
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003858" Test helpgrep with lang specifier
3859func Xtest_helpgrep_with_lang_specifier(cchar)
3860 call s:setup_commands(a:cchar)
3861 Xhelpgrep Vim@en
3862 call assert_equal('help', &filetype)
3863 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3864 new | only
3865endfunc
3866
3867func Test_helpgrep_with_lang_specifier()
3868 call Xtest_helpgrep_with_lang_specifier('c')
3869 call Xtest_helpgrep_with_lang_specifier('l')
3870endfunc
3871
Bram Moolenaar12237442017-12-19 12:38:52 +01003872" The following test used to crash Vim.
3873" Open the location list window and close the regular window associated with
3874" the location list. When the garbage collection runs now, it incorrectly
3875" marks the location list context as not in use and frees the context.
3876func Test_ll_window_ctx()
3877 call setloclist(0, [], 'f')
3878 call setloclist(0, [], 'a', {'context' : []})
3879 lopen | only
3880 call test_garbagecollect_now()
3881 echo getloclist(0, {'context' : 1}).context
3882 enew | only
3883endfunc
3884
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003885" The following test used to crash vim
3886func Test_lfile_crash()
3887 sp Xtest
3888 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003889 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003890 au! QuickFixCmdPre
3891endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003892
3893" The following test used to crash vim
3894func Test_lbuffer_crash()
3895 sv Xtest
3896 augroup QF_Test
3897 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003898 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003899 augroup END
3900 lbuffer
3901 augroup QF_Test
3902 au!
3903 augroup END
3904endfunc
3905
3906" The following test used to crash vim
3907func Test_lexpr_crash()
3908 augroup QF_Test
3909 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003910 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003911 augroup END
3912 lexpr ""
3913 augroup QF_Test
3914 au!
3915 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003916
Bram Moolenaar3c097222017-12-21 20:54:49 +01003917 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003918 augroup QF_Test
3919 au!
3920 au BufNew * call setloclist(0, [], 'f')
3921 augroup END
3922 lexpr 'x:1:x'
3923 augroup QF_Test
3924 au!
3925 augroup END
3926
3927 enew | only
3928 lexpr ''
3929 lopen
3930 augroup QF_Test
3931 au!
3932 au FileType * call setloclist(0, [], 'f')
3933 augroup END
3934 lexpr ''
3935 augroup QF_Test
3936 au!
3937 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003938endfunc
3939
3940" The following test used to crash Vim
3941func Test_lvimgrep_crash()
3942 sv Xtest
3943 augroup QF_Test
3944 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003945 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003946 augroup END
3947 lvimgrep quickfix test_quickfix.vim
3948 augroup QF_Test
3949 au!
3950 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003951
3952 new | only
3953 augroup QF_Test
3954 au!
3955 au BufEnter * call setloclist(0, [], 'r')
3956 augroup END
3957 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3958 augroup QF_Test
3959 au!
3960 augroup END
3961
Bram Moolenaar3c097222017-12-21 20:54:49 +01003962 enew | only
3963endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003964
Bram Moolenaar2573af32020-03-14 17:21:34 +01003965func Test_lvimgrep_crash2()
3966 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003967 call assert_fails('lvimgrep x x', 'E471:')
3968 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003969
3970 au! BufNewFile
3971endfunc
3972
Bram Moolenaarde046542017-12-26 13:53:11 +01003973" Test for the position of the quickfix and location list window
3974func Test_qfwin_pos()
3975 " Open two windows
3976 new | only
3977 new
3978 cexpr ['F1:10:L10']
3979 copen
3980 " Quickfix window should be the bottom most window
3981 call assert_equal(3, winnr())
3982 close
3983 " Open at the very top
3984 wincmd t
3985 topleft copen
3986 call assert_equal(1, winnr())
3987 close
3988 " open left of the current window
3989 wincmd t
3990 below new
3991 leftabove copen
3992 call assert_equal(2, winnr())
3993 close
3994 " open right of the current window
3995 rightbelow copen
3996 call assert_equal(3, winnr())
3997 close
3998endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003999
4000" Tests for quickfix/location lists changed by autocommands when
4001" :vimgrep/:lvimgrep commands are running.
4002func Test_vimgrep_autocmd()
4003 call setqflist([], 'f')
4004 call writefile(['stars'], 'Xtest1.txt')
4005 call writefile(['stars'], 'Xtest2.txt')
4006
4007 " Test 1:
4008 " When searching for a pattern using :vimgrep, if the quickfix list is
4009 " changed by an autocmd, the results should be added to the correct quickfix
4010 " list.
4011 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4012 silent vimgrep stars Xtest*.txt
4013 call assert_equal(1, getqflist({'nr' : 0}).nr)
4014 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4015 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4016 au! BufRead Xtest2.txt
4017
4018 " Test 2:
4019 " When searching for a pattern using :vimgrep, if the quickfix list is
4020 " freed, then a error should be given.
4021 silent! %bwipe!
4022 call setqflist([], 'f')
4023 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4024 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4025 au! BufRead Xtest2.txt
4026
4027 " Test 3:
4028 " When searching for a pattern using :lvimgrep, if the location list is
4029 " freed, then the command should error out.
4030 silent! %bwipe!
4031 let g:save_winid = win_getid()
4032 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4033 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4034 au! BufRead Xtest2.txt
4035
4036 call delete('Xtest1.txt')
4037 call delete('Xtest2.txt')
4038 call setqflist([], 'f')
4039endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004040
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004041" Test for an autocmd changing the current directory when running vimgrep
4042func Xvimgrep_autocmd_cd(cchar)
4043 call s:setup_commands(a:cchar)
4044
4045 %bwipe
4046 let save_cwd = getcwd()
4047
4048 augroup QF_Test
4049 au!
4050 autocmd BufRead * silent cd %:p:h
4051 augroup END
4052
4053 10Xvimgrep /vim/ Xdir/**
4054 let l = g:Xgetlist()
4055 call assert_equal('f1.txt', bufname(l[0].bufnr))
4056 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4057
4058 augroup QF_Test
4059 au!
4060 augroup END
4061
4062 exe 'cd ' . save_cwd
4063endfunc
4064
4065func Test_vimgrep_autocmd_cd()
4066 call mkdir('Xdir/a', 'p')
4067 call mkdir('Xdir/b', 'p')
4068 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4069 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4070 call Xvimgrep_autocmd_cd('c')
4071 call Xvimgrep_autocmd_cd('l')
4072 %bwipe
4073 call delete('Xdir', 'rf')
4074endfunc
4075
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004076" The following test used to crash Vim
4077func Test_lhelpgrep_autocmd()
4078 lhelpgrep quickfix
4079 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4080 lhelpgrep buffer
4081 call assert_equal('help', &filetype)
4082 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4083 lhelpgrep tabpage
4084 call assert_equal('help', &filetype)
4085 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4086 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004087
4088 new | only
4089 augroup QF_Test
4090 au!
4091 au BufEnter * call setqflist([], 'f')
4092 augroup END
4093 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004094 " run the test with a help window already open
4095 help
4096 wincmd w
4097 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004098 augroup QF_Test
4099 au! BufEnter
4100 augroup END
4101
4102 new | only
4103 augroup QF_Test
4104 au!
4105 au BufEnter * call setqflist([], 'r')
4106 augroup END
4107 call assert_fails('helpgrep quickfix', 'E925:')
4108 augroup QF_Test
4109 au! BufEnter
4110 augroup END
4111
4112 new | only
4113 augroup QF_Test
4114 au!
4115 au BufEnter * call setloclist(0, [], 'r')
4116 augroup END
4117 call assert_fails('lhelpgrep quickfix', 'E926:')
4118 augroup QF_Test
4119 au! BufEnter
4120 augroup END
4121
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004122 new | only
4123endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004124
4125" Test for shortening/simplifying the file name when opening the
4126" quickfix window or when displaying the quickfix list
4127func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004128 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004129 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004130 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004131 let fname = getcwd() . '/test_quickfix.vim'
4132 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4133 call assert_equal(fname, bufname('test_quickfix.vim'))
4134 " Opening the quickfix window should simplify the file path
4135 cwindow
4136 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4137 cclose
4138 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004139 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004140 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4141 call assert_equal(fname, bufname('test_quickfix.vim'))
4142 " Displaying the quickfix list should simplify the file path
4143 silent! clist
4144 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004145 " Add a few entries for the same file with different paths and check whether
4146 " the buffer name is shortened
4147 %bwipe
4148 call setqflist([], 'f')
4149 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4150 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4151 \ {'filename' : fname, 'lnum' : 30}], ' ')
4152 copen
4153 call assert_equal(['test_quickfix.vim|10| ',
4154 \ 'test_quickfix.vim|20| ',
4155 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4156 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004157endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004158
4159" Quickfix title tests
4160" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4161" Otherwise due to indentation, the title is set with spaces at the beginning
4162" of the command.
4163func Test_qftitle()
4164 call writefile(["F1:1:Line1"], 'Xerr')
4165
4166 " :cexpr
4167 exe "cexpr readfile('Xerr')"
4168 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4169
4170 " :cgetexpr
4171 exe "cgetexpr readfile('Xerr')"
4172 call assert_equal(":cgetexpr readfile('Xerr')",
4173 \ getqflist({'title' : 1}).title)
4174
4175 " :caddexpr
4176 call setqflist([], 'f')
4177 exe "caddexpr readfile('Xerr')"
4178 call assert_equal(":caddexpr readfile('Xerr')",
4179 \ getqflist({'title' : 1}).title)
4180
4181 " :cbuffer
4182 new Xerr
4183 exe "cbuffer"
4184 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4185
4186 " :cgetbuffer
4187 edit Xerr
4188 exe "cgetbuffer"
4189 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4190
4191 " :caddbuffer
4192 call setqflist([], 'f')
4193 edit Xerr
4194 exe "caddbuffer"
4195 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4196
4197 " :cfile
4198 exe "cfile Xerr"
4199 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4200
4201 " :cgetfile
4202 exe "cgetfile Xerr"
4203 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4204
4205 " :caddfile
4206 call setqflist([], 'f')
4207 exe "caddfile Xerr"
4208 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4209
4210 " :grep
4211 set grepprg=internal
4212 exe "grep F1 Xerr"
4213 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4214
4215 " :grepadd
4216 call setqflist([], 'f')
4217 exe "grepadd F1 Xerr"
4218 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4219 set grepprg&vim
4220
4221 " :vimgrep
4222 exe "vimgrep F1 Xerr"
4223 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4224
4225 " :vimgrepadd
4226 call setqflist([], 'f')
4227 exe "vimgrepadd F1 Xerr"
4228 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4229
4230 call setqflist(['F1:10:L10'], ' ')
4231 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4232
4233 call setqflist([], 'f')
4234 call setqflist(['F1:10:L10'], 'a')
4235 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4236
4237 call setqflist([], 'f')
4238 call setqflist(['F1:10:L10'], 'r')
4239 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4240
4241 close
4242 call delete('Xerr')
4243
4244 call setqflist([], ' ', {'title' : 'Errors'})
4245 copen
4246 call assert_equal('Errors', w:quickfix_title)
4247 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4248 call assert_equal('Errors', w:quickfix_title)
4249 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004250
4251 " Switching to another quickfix list in one tab page should update the
4252 " quickfix window title and statusline in all the other tab pages also
4253 call setqflist([], 'f')
4254 %bw!
4255 cgetexpr ['file_one:1:1: error in the first quickfix list']
4256 call setqflist([], 'a', {'title': 'first quickfix list'})
4257 cgetexpr ['file_two:2:1: error in the second quickfix list']
4258 call setqflist([], 'a', {'title': 'second quickfix list'})
4259 copen
4260 wincmd t
4261 tabnew two
4262 copen
4263 wincmd t
4264 colder
4265 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4266 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4267 call assert_equal(1, tabpagewinnr(1))
4268 call assert_equal(1, tabpagewinnr(2))
4269 tabnew
4270 call setqflist([], 'a', {'title': 'new quickfix title'})
4271 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4272 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4273 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004274endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004275
4276func Test_lbuffer_with_bwipe()
4277 new
4278 new
4279 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004280 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004281 augroup END
4282 lbuffer
4283 augroup nasty
4284 au!
4285 augroup END
4286endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004287
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004288" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4289" running
4290func Xexpr_acmd_freelist(cchar)
4291 call s:setup_commands(a:cchar)
4292
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004293 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004294 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004295 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004296 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004297 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004298 augroup nasty
4299 au!
4300 augroup END
4301endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004302
4303func Test_cexpr_acmd_freelist()
4304 call Xexpr_acmd_freelist('c')
4305 call Xexpr_acmd_freelist('l')
4306endfunc
4307
4308" Test for commands that create a new quickfix/location list and jump to the
4309" first error automatically.
4310func Xjumpto_first_error_test(cchar)
4311 call s:setup_commands(a:cchar)
4312
4313 call s:create_test_file('Xtestfile1')
4314 call s:create_test_file('Xtestfile2')
4315 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4316
4317 " Test for cexpr/lexpr
4318 enew
4319 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004320 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004321 call assert_equal(2, line('.'))
4322
4323 " Test for cfile/lfile
4324 enew
4325 call writefile(l, 'Xerr')
4326 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004327 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004328 call assert_equal(2, line('.'))
4329
4330 " Test for cbuffer/lbuffer
4331 edit Xerr
4332 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004333 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004334 call assert_equal(2, line('.'))
4335
4336 call delete('Xerr')
4337 call delete('Xtestfile1')
4338 call delete('Xtestfile2')
4339endfunc
4340
4341func Test_jumpto_first_error()
4342 call Xjumpto_first_error_test('c')
4343 call Xjumpto_first_error_test('l')
4344endfunc
4345
4346" Test for a quickfix autocmd changing the quickfix/location list before
4347" jumping to the first error in the new list.
4348func Xautocmd_changelist(cchar)
4349 call s:setup_commands(a:cchar)
4350
4351 " Test for cfile/lfile
4352 call s:create_test_file('Xtestfile1')
4353 call s:create_test_file('Xtestfile2')
4354 Xexpr 'Xtestfile1:2:Line2'
4355 autocmd QuickFixCmdPost * Xolder
4356 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4357 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004358 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004359 call assert_equal(4, line('.'))
4360 autocmd! QuickFixCmdPost
4361
4362 " Test for cbuffer/lbuffer
4363 call g:Xsetlist([], 'f')
4364 Xexpr 'Xtestfile1:2:Line2'
4365 autocmd QuickFixCmdPost * Xolder
4366 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4367 edit Xerr
4368 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004369 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004370 call assert_equal(4, line('.'))
4371 autocmd! QuickFixCmdPost
4372
4373 " Test for cexpr/lexpr
4374 call g:Xsetlist([], 'f')
4375 Xexpr 'Xtestfile1:2:Line2'
4376 autocmd QuickFixCmdPost * Xolder
4377 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004378 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004379 call assert_equal(4, line('.'))
4380 autocmd! QuickFixCmdPost
4381
Bram Moolenaar851332e2018-07-03 19:16:00 +02004382 " The grepprg may not be set on non-Unix systems
4383 if has('unix')
4384 " Test for grep/lgrep
4385 call g:Xsetlist([], 'f')
4386 Xexpr 'Xtestfile1:2:Line2'
4387 autocmd QuickFixCmdPost * Xolder
4388 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004389 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004390 call assert_equal(5, line('.'))
4391 autocmd! QuickFixCmdPost
4392 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004393
4394 " Test for vimgrep/lvimgrep
4395 call g:Xsetlist([], 'f')
4396 Xexpr 'Xtestfile1:2:Line2'
4397 autocmd QuickFixCmdPost * Xolder
4398 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004399 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004400 call assert_equal(5, line('.'))
4401 autocmd! QuickFixCmdPost
4402
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004403 " Test for autocommands clearing the quickfix list before jumping to the
4404 " first error. This should not result in an error
4405 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4406 let v:errmsg = ''
4407 " Test for cfile/lfile
4408 Xfile Xerr
4409 call assert_true(v:errmsg !~# 'E42:')
4410 " Test for cbuffer/lbuffer
4411 edit Xerr
4412 Xbuffer
4413 call assert_true(v:errmsg !~# 'E42:')
4414 " Test for cexpr/lexpr
4415 Xexpr 'Xtestfile2:4:Line4'
4416 call assert_true(v:errmsg !~# 'E42:')
4417 " Test for grep/lgrep
4418 " The grepprg may not be set on non-Unix systems
4419 if has('unix')
4420 silent Xgrep Line5 Xtestfile2
4421 call assert_true(v:errmsg !~# 'E42:')
4422 endif
4423 " Test for vimgrep/lvimgrep
4424 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4425 autocmd! QuickFixCmdPost
4426
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004427 call delete('Xerr')
4428 call delete('Xtestfile1')
4429 call delete('Xtestfile2')
4430endfunc
4431
4432func Test_autocmd_changelist()
4433 call Xautocmd_changelist('c')
4434 call Xautocmd_changelist('l')
4435endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004436
4437" Tests for the ':filter /pat/ clist' command
4438func Test_filter_clist()
4439 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4440 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4441 \ split(execute('filter /Line 15/ clist'), "\n"))
4442 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4443 \ split(execute('filter /Xfile1/ clist'), "\n"))
4444 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4445
4446 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4447 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4448 call assert_equal([' 2 pqr:pat2: '],
4449 \ split(execute('filter /pqr/ clist'), "\n"))
4450 call assert_equal([' 1 abc:pat1: '],
4451 \ split(execute('filter /pat1/ clist'), "\n"))
4452endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004453
4454" Tests for the "CTRL-W <CR>" command.
4455func Xview_result_split_tests(cchar)
4456 call s:setup_commands(a:cchar)
4457
4458 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4459 call g:Xsetlist([])
4460 Xopen
4461 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004462 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004463 call assert_equal(l:win_count, winnr('$'))
4464 Xclose
4465endfunc
4466
4467func Test_view_result_split()
4468 call Xview_result_split_tests('c')
4469 call Xview_result_split_tests('l')
4470endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004471
4472" Test that :cc sets curswant
4473func Test_curswant()
4474 helpgrep quickfix
4475 normal! llll
4476 1cc
4477 call assert_equal(getcurpos()[4], virtcol('.'))
4478 cclose | helpclose
4479endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004480
4481" Test for opening a file from the quickfix window using CTRL-W <Enter>
4482" doesn't leave an empty buffer around.
4483func Test_splitview()
4484 call s:create_test_file('Xtestfile1')
4485 call s:create_test_file('Xtestfile2')
4486 new | only
4487 let last_bufnr = bufnr('Test_sv_1', 1)
4488 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4489 cgetexpr l
4490 copen
4491 let numbufs = len(getbufinfo())
4492 exe "normal \<C-W>\<CR>"
4493 copen
4494 exe "normal j\<C-W>\<CR>"
4495 " Make sure new empty buffers are not created
4496 call assert_equal(numbufs, len(getbufinfo()))
4497 " Creating a new buffer should use the next available buffer number
4498 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4499 bwipe Test_sv_1
4500 bwipe Test_sv_2
4501 new | only
4502
4503 " When split opening files from location list window, make sure that two
4504 " windows doesn't refer to the same location list
4505 lgetexpr l
4506 let locid = getloclist(0, {'id' : 0}).id
4507 lopen
4508 exe "normal \<C-W>\<CR>"
4509 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4510 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4511 new | only
4512
4513 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004514 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004515 lhelpgrep window
4516 let locid = getloclist(0, {'id' : 0}).id
4517 lwindow
4518 exe "normal j\<C-W>\<CR>"
4519 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4520 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4521 new | only
4522
Bram Moolenaar406cd902020-02-18 21:54:41 +01004523 " Using :split or :vsplit from a quickfix window should behave like a :new
4524 " or a :vnew command
4525 copen
4526 split
4527 call assert_equal(3, winnr('$'))
4528 let l = getwininfo()
4529 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4530 close
4531 copen
4532 vsplit
4533 let l = getwininfo()
4534 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4535 new | only
4536
Bram Moolenaarb2443732018-11-11 22:50:27 +01004537 call delete('Xtestfile1')
4538 call delete('Xtestfile2')
4539endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004540
4541" Test for parsing entries using visual screen column
4542func Test_viscol()
4543 enew
4544 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4545 edit Xfile1
4546
4547 " Use byte offset for column number
4548 set efm&
4549 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4550 call assert_equal([5, 8], [col('.'), virtcol('.')])
4551 cnext
4552 call assert_equal([9, 12], [col('.'), virtcol('.')])
4553 cnext
4554 call assert_equal([14, 20], [col('.'), virtcol('.')])
4555
4556 " Use screen column offset for column number
4557 set efm=%f:%l:%v:%m
4558 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4559 call assert_equal([5, 8], [col('.'), virtcol('.')])
4560 cnext
4561 call assert_equal([9, 12], [col('.'), virtcol('.')])
4562 cnext
4563 call assert_equal([14, 20], [col('.'), virtcol('.')])
4564 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4565 call assert_equal([5, 8], [col('.'), virtcol('.')])
4566 cnext
4567 call assert_equal([10, 16], [col('.'), virtcol('.')])
4568 cnext
4569 call assert_equal([14, 20], [col('.'), virtcol('.')])
4570
4571 enew
4572 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4573
4574 " Use byte offset for column number
4575 set efm&
4576 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4577 call assert_equal([8, 10], [col('.'), virtcol('.')])
4578 cnext
4579 call assert_equal([11, 17], [col('.'), virtcol('.')])
4580 cnext
4581 call assert_equal([16, 25], [col('.'), virtcol('.')])
4582
4583 " Use screen column offset for column number
4584 set efm=%f:%l:%v:%m
4585 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4586 call assert_equal([8, 10], [col('.'), virtcol('.')])
4587 cnext
4588 call assert_equal([11, 17], [col('.'), virtcol('.')])
4589 cnext
4590 call assert_equal([16, 25], [col('.'), virtcol('.')])
4591
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004592 " Use screen column number with a multi-line error message
4593 enew
4594 call writefile(["à test"], 'Xfile1')
4595 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4596 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4597 call assert_equal('Xfile1', @%)
4598 call assert_equal([0, 1, 4, 0], getpos('.'))
4599
4600 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4601 " does not break this
4602 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4603 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4604 call assert_equal('Xfile1', @%)
4605 call assert_equal([0, 1, 3, 0], getpos('.'))
4606
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004607 enew | only
4608 set efm&
4609 call delete('Xfile1')
4610endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004611
4612" Test for the quickfix window buffer
4613func Xqfbuf_test(cchar)
4614 call s:setup_commands(a:cchar)
4615
4616 " Quickfix buffer should be reused across closing and opening a quickfix
4617 " window
4618 Xexpr "F1:10:Line10"
4619 Xopen
4620 let qfbnum = bufnr('')
4621 Xclose
4622 " Even after the quickfix window is closed, the buffer should be loaded
4623 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004624 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004625 Xopen
4626 " Buffer should be reused when opening the window again
4627 call assert_equal(qfbnum, bufnr(''))
4628 Xclose
4629
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004630 " When quickfix buffer is wiped out, getqflist() should return 0
4631 %bw!
4632 Xexpr ""
4633 Xopen
4634 bw!
4635 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4636
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004637 if a:cchar == 'l'
4638 %bwipe
4639 " For a location list, when both the file window and the location list
4640 " window for the list are closed, then the buffer should be freed.
4641 new | only
4642 lexpr "F1:10:Line10"
4643 let wid = win_getid()
4644 lopen
4645 let qfbnum = bufnr('')
4646 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4647 close
4648 " When the location list window is closed, the buffer name should not
4649 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004650 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004651 call assert_true(bufloaded(qfbnum))
4652
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004653 " After deleting a location list buffer using ":bdelete", opening the
4654 " location list window should mark the buffer as a location list buffer.
4655 exe "bdelete " . qfbnum
4656 lopen
4657 call assert_equal("quickfix", &buftype)
4658 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4659 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4660 call assert_false(&swapfile)
4661 lclose
4662
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004663 " When the location list is cleared for the window, the buffer should be
4664 " removed
4665 call setloclist(0, [], 'f')
4666 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004667 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004668
4669 " When the location list is freed with the location list window open, the
4670 " location list buffer should not be lost. It should be reused when the
4671 " location list is again populated.
4672 lexpr "F1:10:Line10"
4673 lopen
4674 let wid = win_getid()
4675 let qfbnum = bufnr('')
4676 wincmd p
4677 call setloclist(0, [], 'f')
4678 lexpr "F1:10:Line10"
4679 lopen
4680 call assert_equal(wid, win_getid())
4681 call assert_equal(qfbnum, bufnr(''))
4682 lclose
4683
4684 " When the window with the location list is closed, the buffer should be
4685 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004686 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004687 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004688 endif
4689endfunc
4690
4691func Test_qfbuf()
4692 call Xqfbuf_test('c')
4693 call Xqfbuf_test('l')
4694endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004695
4696" If there is an autocmd to use only one window, then opening the location
4697" list window used to crash Vim.
4698func Test_winonly_autocmd()
4699 call s:create_test_file('Xtest1')
4700 " Autocmd to show only one Vim window at a time
4701 autocmd WinEnter * only
4702 new
4703 " Load the location list
4704 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4705 let loclistid = getloclist(0, {'id' : 0}).id
4706 " Open the location list window. Only this window will be shown and the file
4707 " window is closed.
4708 lopen
4709 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4710 " Jump to an entry in the location list and make sure that the cursor is
4711 " positioned correctly.
4712 ll 3
4713 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004714 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004715 call assert_equal(15, line('.'))
4716 " Cleanup
4717 autocmd! WinEnter
4718 new | only
4719 call delete('Xtest1')
4720endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004721
4722" Test to make sure that an empty quickfix buffer is not reused for loading
4723" a normal buffer.
4724func Test_empty_qfbuf()
4725 enew | only
4726 call writefile(["Test"], 'Xfile1')
4727 call setqflist([], 'f')
4728 copen | only
4729 let qfbuf = bufnr('')
4730 edit Xfile1
4731 call assert_notequal(qfbuf, bufnr(''))
4732 enew
4733 call delete('Xfile1')
4734endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004735
4736" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004737" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004738func Xtest_below(cchar)
4739 call s:setup_commands(a:cchar)
4740
4741 " No quickfix/location list
4742 call assert_fails('Xbelow', 'E42:')
4743 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004744 call assert_fails('Xbefore', 'E42:')
4745 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004746
4747 " Empty quickfix/location list
4748 call g:Xsetlist([])
4749 call assert_fails('Xbelow', 'E42:')
4750 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004751 call assert_fails('Xbefore', 'E42:')
4752 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004753
4754 call s:create_test_file('X1')
4755 call s:create_test_file('X2')
4756 call s:create_test_file('X3')
4757 call s:create_test_file('X4')
4758
4759 " Invalid entries
4760 edit X1
4761 call g:Xsetlist(["E1", "E2"])
4762 call assert_fails('Xbelow', 'E42:')
4763 call assert_fails('Xabove', 'E42:')
4764 call assert_fails('3Xbelow', 'E42:')
4765 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004766 call assert_fails('Xbefore', 'E42:')
4767 call assert_fails('Xafter', 'E42:')
4768 call assert_fails('3Xbefore', 'E42:')
4769 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004770
4771 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004772 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 +02004773 edit +7 X2
4774 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004775 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004776 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004777 normal 7G
4778 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004779 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004780 call assert_fails('Xbefore', 'E553:')
4781
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004782 normal 2j
4783 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004784 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004785 normal 7G
4786 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004787 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004788
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004789 " Last error in this file
4790 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004791 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004792 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004793 normal gg
4794 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004795 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004796 call assert_fails('Xafter', 'E553:')
4797
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004798 " First error in this file
4799 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004800 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004801 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004802 normal G
4803 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004804 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004805 call assert_fails('Xbefore', 'E553:')
4806
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004807 normal gg
4808 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004809 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004810 normal gg
4811 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004812 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004813
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004814 normal G
4815 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004816 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004817 normal G
4818 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004819 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004820
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004821 edit X4
4822 call assert_fails('Xabove', 'E42:')
4823 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004824 call assert_fails('Xbefore', 'E42:')
4825 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004826 if a:cchar == 'l'
4827 " If a buffer has location list entries from some other window but not
4828 " from the current window, then the commands should fail.
4829 edit X1 | split | call setloclist(0, [], 'f')
4830 call assert_fails('Xabove', 'E776:')
4831 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004832 call assert_fails('Xbefore', 'E776:')
4833 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004834 close
4835 endif
4836
4837 " Test for lines with multiple quickfix entries
4838 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4839 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4840 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4841 edit +1 X2
4842 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004843 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004844 normal 1G
4845 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004846 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004847
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004848 normal gg
4849 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004850 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004851 normal gg
4852 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004853 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004854
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004855 normal G
4856 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004857 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004858 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004859 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004860 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004861
4862 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004863 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004864 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004865 normal G
4866 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004867 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004868
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004869 normal 10G
4870 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004871 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004872 normal 10G$
4873 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004874 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004875
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004876 normal 10G
4877 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004878 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004879 normal 9G
4880 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004881 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004882
4883 " Invalid range
4884 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004885 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004886 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004887 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004888 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004889 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004890 endif
4891
4892 call delete('X1')
4893 call delete('X2')
4894 call delete('X3')
4895 call delete('X4')
4896endfunc
4897
4898func Test_cbelow()
4899 call Xtest_below('c')
4900 call Xtest_below('l')
4901endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004902
4903func Test_quickfix_count()
4904 let commands = [
4905 \ 'cNext',
4906 \ 'cNfile',
4907 \ 'cabove',
4908 \ 'cbelow',
4909 \ 'cfirst',
4910 \ 'clast',
4911 \ 'cnewer',
4912 \ 'cnext',
4913 \ 'cnfile',
4914 \ 'colder',
4915 \ 'cprevious',
4916 \ 'crewind',
4917 \
4918 \ 'lNext',
4919 \ 'lNfile',
4920 \ 'labove',
4921 \ 'lbelow',
4922 \ 'lfirst',
4923 \ 'llast',
4924 \ 'lnewer',
4925 \ 'lnext',
4926 \ 'lnfile',
4927 \ 'lolder',
4928 \ 'lprevious',
4929 \ 'lrewind',
4930 \ ]
4931 for cmd in commands
4932 call assert_fails('-1' .. cmd, 'E16:')
4933 call assert_fails('.' .. cmd, 'E16:')
4934 call assert_fails('%' .. cmd, 'E16:')
4935 call assert_fails('$' .. cmd, 'E16:')
4936 endfor
4937endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004938
4939" Test for aborting quickfix commands using QuickFixCmdPre
4940func Xtest_qfcmd_abort(cchar)
4941 call s:setup_commands(a:cchar)
4942
4943 call g:Xsetlist([], 'f')
4944
4945 " cexpr/lexpr
4946 let e = ''
4947 try
4948 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4949 catch /.*/
4950 let e = v:exception
4951 endtry
4952 call assert_equal('AbortCmd', e)
4953 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4954
4955 " cfile/lfile
4956 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4957 let e = ''
4958 try
4959 Xfile Xfile1
4960 catch /.*/
4961 let e = v:exception
4962 endtry
4963 call assert_equal('AbortCmd', e)
4964 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4965 call delete('Xfile1')
4966
4967 " cgetbuffer/lgetbuffer
4968 enew!
4969 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4970 let e = ''
4971 try
4972 Xgetbuffer
4973 catch /.*/
4974 let e = v:exception
4975 endtry
4976 call assert_equal('AbortCmd', e)
4977 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4978 enew!
4979
4980 " vimgrep/lvimgrep
4981 let e = ''
4982 try
4983 Xvimgrep /func/ test_quickfix.vim
4984 catch /.*/
4985 let e = v:exception
4986 endtry
4987 call assert_equal('AbortCmd', e)
4988 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4989
4990 " helpgrep/lhelpgrep
4991 let e = ''
4992 try
4993 Xhelpgrep quickfix
4994 catch /.*/
4995 let e = v:exception
4996 endtry
4997 call assert_equal('AbortCmd', e)
4998 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4999
5000 " grep/lgrep
5001 if has('unix')
5002 let e = ''
5003 try
5004 silent Xgrep func test_quickfix.vim
5005 catch /.*/
5006 let e = v:exception
5007 endtry
5008 call assert_equal('AbortCmd', e)
5009 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5010 endif
5011endfunc
5012
5013func Test_qfcmd_abort()
5014 augroup QF_Test
5015 au!
5016 autocmd QuickFixCmdPre * throw "AbortCmd"
5017 augroup END
5018
5019 call Xtest_qfcmd_abort('c')
5020 call Xtest_qfcmd_abort('l')
5021
5022 augroup QF_Test
5023 au!
5024 augroup END
5025endfunc
5026
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005027" Test for using a file in one of the parent directories.
5028func Test_search_in_dirstack()
5029 call mkdir('Xtestdir/a/b/c', 'p')
5030 let save_cwd = getcwd()
5031 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5032 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5033 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5034 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5035
5036 let lines = "Entering dir Xtestdir\n" .
5037 \ "Entering dir a\n" .
5038 \ "Entering dir b\n" .
5039 \ "Xfile2:2:X2_L2\n" .
5040 \ "Leaving dir a\n" .
5041 \ "Xfile1:2:X1_L2\n" .
5042 \ "Xfile3:1:X3_L1\n" .
5043 \ "Entering dir c\n" .
5044 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005045 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005046 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005047 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005048 call assert_equal(11, getqflist({'size' : 0}).size)
5049 call assert_equal(4, getqflist({'idx' : 0}).idx)
5050 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005051 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005052 cnext
5053 call assert_equal(6, getqflist({'idx' : 0}).idx)
5054 call assert_equal('X1_L2', getline('.'))
5055 cnext
5056 call assert_equal(7, getqflist({'idx' : 0}).idx)
5057 call assert_equal(1, line('$'))
5058 call assert_equal('', getline(1))
5059 cnext
5060 call assert_equal(9, getqflist({'idx' : 0}).idx)
5061 call assert_equal(1, line('$'))
5062 call assert_equal('', getline(1))
5063
5064 set efm&
5065 exe 'cd ' . save_cwd
5066 call delete('Xtestdir', 'rf')
5067endfunc
5068
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005069" Test for :cquit
5070func Test_cquit()
5071 " Exit Vim with a non-zero value
5072 if RunVim([], ["cquit 7"], '')
5073 call assert_equal(7, v:shell_error)
5074 endif
5075
5076 if RunVim([], ["50cquit"], '')
5077 call assert_equal(50, v:shell_error)
5078 endif
5079
5080 " Exit Vim with default value
5081 if RunVim([], ["cquit"], '')
5082 call assert_equal(1, v:shell_error)
5083 endif
5084
5085 " Exit Vim with zero value
5086 if RunVim([], ["cquit 0"], '')
5087 call assert_equal(0, v:shell_error)
5088 endif
5089
5090 " Exit Vim with negative value
5091 call assert_fails('-3cquit', 'E16:')
5092endfunc
5093
Bram Moolenaar858ba062020-05-31 23:11:59 +02005094" Test for getting a specific item from a quickfix list
5095func Xtest_getqflist_by_idx(cchar)
5096 call s:setup_commands(a:cchar)
5097 " Empty list
5098 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5099 Xexpr ['F1:10:L10', 'F1:20:L20']
5100 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5101 call assert_equal(bufnr('F1'), l[0].bufnr)
5102 call assert_equal(20, l[0].lnum)
5103 call assert_equal('L20', l[0].text)
5104 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5105 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5106 %bwipe!
5107endfunc
5108
5109func Test_getqflist_by_idx()
5110 call Xtest_getqflist_by_idx('c')
5111 call Xtest_getqflist_by_idx('l')
5112endfunc
5113
5114" Test for the 'quickfixtextfunc' setting
5115func Tqfexpr(info)
5116 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005117 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005118 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005119 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005120 endif
5121
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005122 let l = []
5123 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5124 let e = qfl[idx]
5125 let s = ''
5126 if e.bufnr != 0
5127 let bname = bufname(e.bufnr)
5128 let s ..= fnamemodify(bname, ':.')
5129 endif
5130 let s ..= '-'
5131 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5132 let s ..= e.text
5133 call add(l, s)
5134 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005135
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005136 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005137endfunc
5138
5139func Xtest_qftextfunc(cchar)
5140 call s:setup_commands(a:cchar)
5141
5142 set efm=%f:%l:%c:%m
5143 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005144 call assert_equal('Tqfexpr', &quickfixtextfunc)
5145 call assert_equal('',
5146 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005147 call g:Xsetlist([
5148 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5149 \ 'end_col': 7, 'text': 'green'},
5150 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5151 \ 'end_col': 8, 'text': 'blue'},
5152 \ ])
5153
Bram Moolenaar858ba062020-05-31 23:11:59 +02005154 Xwindow
5155 call assert_equal('F1-L10C2-green', getline(1))
5156 call assert_equal('F1-L20C4-blue', getline(2))
5157 Xclose
5158 set quickfixtextfunc&vim
5159 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005160 call assert_equal('F1|10 col 2-7| green', getline(1))
5161 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005162 Xclose
5163 set efm&
5164 set quickfixtextfunc&
5165
5166 " Test for per list 'quickfixtextfunc' setting
5167 func PerQfText(info)
5168 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005169 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005170 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005171 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005172 endif
5173 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005174 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005175 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005176 let l = []
5177 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5178 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5179 endfor
5180 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005181 endfunc
5182 set quickfixtextfunc=Tqfexpr
5183 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5184 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5185 Xwindow
5186 call assert_equal('Line 10, Col 2', getline(1))
5187 call assert_equal('Line 20, Col 4', getline(2))
5188 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005189 call assert_equal(function('PerQfText'),
5190 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005191 " Add entries to the list when the quickfix buffer is hidden
5192 Xaddexpr ['F1:30:6:red']
5193 Xwindow
5194 call assert_equal('Line 30, Col 6', getline(3))
5195 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005196 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005197 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005198 set quickfixtextfunc&
5199 delfunc PerQfText
5200
5201 " Non-existing function
5202 set quickfixtextfunc=Tabc
5203 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5204 call assert_fails("Xwindow", 'E117:')
5205 Xclose
5206 set quickfixtextfunc&
5207
5208 " set option to a non-function
5209 set quickfixtextfunc=[10,\ 20]
5210 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5211 call assert_fails("Xwindow", 'E117:')
5212 Xclose
5213 set quickfixtextfunc&
5214
5215 " set option to a function with different set of arguments
5216 func Xqftext(a, b, c)
5217 return a:a .. a:b .. a:c
5218 endfunc
5219 set quickfixtextfunc=Xqftext
5220 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5221 call assert_fails("Xwindow", 'E119:')
5222 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005223
5224 " set option to a function that returns a list with non-strings
5225 func Xqftext2(d)
5226 return ['one', [], 'two']
5227 endfunc
5228 set quickfixtextfunc=Xqftext2
5229 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5230 \ 'E730:')
5231 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005232 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5233 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005234 Xclose
5235
Bram Moolenaar858ba062020-05-31 23:11:59 +02005236 set quickfixtextfunc&
5237 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005238 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005239
5240 " set the global option to a lambda function
5241 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5242 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5243 Xwindow
5244 call assert_equal(['green', 'blue'], getline(1, '$'))
5245 Xclose
5246 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)
5247 set quickfixtextfunc&
5248
5249 " use a lambda function that returns an empty list
5250 set quickfixtextfunc={d\ ->\ []}
5251 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5252 Xwindow
5253 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5254 \ getline(1, '$'))
5255 Xclose
5256 set quickfixtextfunc&
5257
5258 " use a lambda function that returns a list with empty strings
5259 set quickfixtextfunc={d\ ->\ ['',\ '']}
5260 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5261 Xwindow
5262 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5263 \ getline(1, '$'))
5264 Xclose
5265 set quickfixtextfunc&
5266
5267 " set the per-quickfix list text function to a lambda function
5268 call g:Xsetlist([], ' ',
5269 \ {'quickfixtextfunc' :
5270 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5271 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5272 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5273 Xwindow
5274 call assert_equal('Line 10, Col 2', getline(1))
5275 call assert_equal('Line 20, Col 4', getline(2))
5276 Xclose
5277 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5278 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005279endfunc
5280
5281func Test_qftextfunc()
5282 call Xtest_qftextfunc('c')
5283 call Xtest_qftextfunc('l')
5284endfunc
5285
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005286func Test_qftextfunc_callback()
5287 let lines =<< trim END
5288 set efm=%f:%l:%c:%m
5289
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005290 #" Test for using a function name
5291 LET &qftf = 'g:Tqfexpr'
5292 cexpr "F0:0:0:L0"
5293 copen
5294 call assert_equal('F0-L0C0-L0', getline(1))
5295 cclose
5296
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005297 #" Test for using a function()
5298 set qftf=function('g:Tqfexpr')
5299 cexpr "F1:1:1:L1"
5300 copen
5301 call assert_equal('F1-L1C1-L1', getline(1))
5302 cclose
5303
5304 #" Using a funcref variable to set 'quickfixtextfunc'
5305 VAR Fn = function('g:Tqfexpr')
5306 LET &qftf = Fn
5307 cexpr "F2:2:2:L2"
5308 copen
5309 call assert_equal('F2-L2C2-L2', getline(1))
5310 cclose
5311
5312 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5313 LET Fn = function('g:Tqfexpr')
5314 LET &qftf = string(Fn)
5315 cexpr "F3:3:3:L3"
5316 copen
5317 call assert_equal('F3-L3C3-L3', getline(1))
5318 cclose
5319
5320 #" Test for using a funcref()
5321 set qftf=funcref('g:Tqfexpr')
5322 cexpr "F4:4:4:L4"
5323 copen
5324 call assert_equal('F4-L4C4-L4', getline(1))
5325 cclose
5326
5327 #" Using a funcref variable to set 'quickfixtextfunc'
5328 LET Fn = funcref('g:Tqfexpr')
5329 LET &qftf = Fn
5330 cexpr "F5:5:5:L5"
5331 copen
5332 call assert_equal('F5-L5C5-L5', getline(1))
5333 cclose
5334
5335 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5336 LET Fn = funcref('g:Tqfexpr')
5337 LET &qftf = string(Fn)
5338 cexpr "F5:5:5:L5"
5339 copen
5340 call assert_equal('F5-L5C5-L5', getline(1))
5341 cclose
5342
5343 #" Test for using a lambda function with set
5344 VAR optval = "LSTART a LMIDDLE Tqfexpr(a) LEND"
5345 LET optval = substitute(optval, ' ', '\\ ', 'g')
5346 exe "set qftf=" .. optval
5347 cexpr "F6:6:6:L6"
5348 copen
5349 call assert_equal('F6-L6C6-L6', getline(1))
5350 cclose
5351
5352 #" Set 'quickfixtextfunc' to a lambda expression
5353 LET &qftf = LSTART a LMIDDLE Tqfexpr(a) LEND
5354 cexpr "F7:7:7:L7"
5355 copen
5356 call assert_equal('F7-L7C7-L7', getline(1))
5357 cclose
5358
5359 #" Set 'quickfixtextfunc' to string(lambda_expression)
5360 LET &qftf = "LSTART a LMIDDLE Tqfexpr(a) LEND"
5361 cexpr "F8:8:8:L8"
5362 copen
5363 call assert_equal('F8-L8C8-L8', getline(1))
5364 cclose
5365
5366 #" Set 'quickfixtextfunc' to a variable with a lambda expression
5367 VAR Lambda = LSTART a LMIDDLE Tqfexpr(a) LEND
5368 LET &qftf = Lambda
5369 cexpr "F9:9:9:L9"
5370 copen
5371 call assert_equal('F9-L9C9-L9', getline(1))
5372 cclose
5373
5374 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
5375 LET Lambda = LSTART a LMIDDLE Tqfexpr(a) LEND
5376 LET &qftf = string(Lambda)
5377 cexpr "F9:9:9:L9"
5378 copen
5379 call assert_equal('F9-L9C9-L9', getline(1))
5380 cclose
5381 END
5382 call CheckLegacyAndVim9Success(lines)
5383
5384 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5385 func SetQftfFunc()
5386 let params = {'qftf': function('g:DictQftfFunc')}
5387 let &quickfixtextfunc = params.qftf
5388 endfunc
5389 func g:DictQftfFunc(_) dict
5390 endfunc
5391 call SetQftfFunc()
5392 new
5393 call SetQftfFunc()
5394 bw
5395 call test_garbagecollect_now()
5396 new
5397 set qftf=
5398 wincmd w
5399 set qftf=
5400 :%bw!
5401
5402 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5403 " to cause a crash.
5404 let &qftf = ''
5405 func SetLocalQftfFunc()
5406 let params = {'qftf': function('g:DictQftfFunc')}
5407 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5408 endfunc
5409 call SetLocalQftfFunc()
5410 call test_garbagecollect_now()
5411 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5412 delfunc g:DictQftfFunc
5413 delfunc SetQftfFunc
5414 delfunc SetLocalQftfFunc
5415 set efm&
5416endfunc
5417
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005418" Test for updating a location list for some other window and check that
5419" 'qftextfunc' uses the correct location list.
5420func Test_qftextfunc_other_loclist()
5421 %bw!
5422 call setloclist(0, [], 'f')
5423
5424 " create a window and a location list for it and open the location list
5425 " window
5426 lexpr ['F1:10:12:one', 'F1:20:14:two']
5427 let w1_id = win_getid()
5428 call setloclist(0, [], ' ',
5429 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5430 \ 'quickfixtextfunc':
5431 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5432 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5433 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5434 lwindow
5435 let w2_id = win_getid()
5436
5437 " create another window and a location list for it and open the location
5438 " list window
5439 topleft new
5440 let w3_id = win_getid()
5441 call setloclist(0, [], ' ',
5442 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5443 \ 'quickfixtextfunc':
5444 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5445 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5446 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5447 lwindow
5448 let w4_id = win_getid()
5449
5450 topleft new
5451 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5452 let w5_id = win_getid()
5453
5454 " change the location list for some other window
5455 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5456 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5457 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5458 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5459 \ getbufline(winbufnr(w2_id), 1, '$'))
5460 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5461 \ getbufline(winbufnr(w4_id), 1, '$'))
5462 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5463 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5464 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5465 \ getbufline(winbufnr(w2_id), 1, '$'))
5466 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5467 \ getbufline(winbufnr(w4_id), 1, '$'))
5468
5469 call win_gotoid(w5_id)
5470 lwindow
5471 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5472 \ getline(1, '$'))
5473 %bw!
5474endfunc
5475
Bram Moolenaarec98e932020-06-08 19:35:59 +02005476" Running :lhelpgrep command more than once in a help window, doesn't jump to
5477" the help topic
5478func Test_lhelpgrep_from_help_window()
5479 call mkdir('Xtestdir/doc', 'p')
5480 call writefile(['window'], 'Xtestdir/doc/a.txt')
5481 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5482 let save_rtp = &rtp
5483 let &rtp = 'Xtestdir'
5484 lhelpgrep window
5485 lhelpgrep buffer
5486 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5487 lhelpgrep window
5488 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5489 let &rtp = save_rtp
5490 call delete('Xtestdir', 'rf')
5491 new | only!
5492endfunc
5493
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005494" Test for the crash fixed by 7.3.715
5495func Test_setloclist_crash()
5496 %bw!
5497 let g:BufNum = bufnr()
5498 augroup QF_Test
5499 au!
5500 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5501 augroup END
5502
5503 try
5504 lvimgrep /.*/ *.mak
5505 catch /E926:/
5506 endtry
5507 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5508 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5509
5510 augroup QF_Test
5511 au!
5512 augroup END
5513 unlet g:BufNum
5514 %bw!
5515endfunc
5516
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005517" Test for adding an invalid entry with the quickfix window open and making
5518" sure that the window contents are not changed
5519func Test_add_invalid_entry_with_qf_window()
5520 call setqflist([], 'f')
5521 cexpr "Xfile1:10:aa"
5522 copen
5523 call setqflist(['bb'], 'a')
5524 call assert_equal(1, line('$'))
5525 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005526 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())
5527
5528 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5529 call assert_equal(1 , line('$'))
5530 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5531 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())
5532
5533 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')
5534 call assert_equal(1 , line('$'))
5535 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5536 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())
5537
5538 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')
5539 call assert_equal(1 , line('$'))
5540 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5541 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())
5542
5543 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')
5544 call assert_equal(1 , line('$'))
5545 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5546 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())
5547
5548 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')
5549 call assert_equal(1 , line('$'))
5550 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5551 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())
5552
5553 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')
5554 call assert_equal(1 , line('$'))
5555 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5556 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())
5557
5558 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')
5559 call assert_equal(1 , line('$'))
5560 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5561 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 +01005562 cclose
5563endfunc
5564
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005565" Test for very weird problem: autocommand causes a failure, resulting opening
5566" the quickfix window to fail. This still splits the window, but otherwise
5567" should not mess up buffers.
5568func Test_quickfix_window_fails_to_open()
5569 CheckScreendump
5570
5571 let lines =<< trim END
5572 anything
5573 try
5574 anything
5575 endtry
5576 END
5577 call writefile(lines, 'XquickfixFails')
5578
5579 let lines =<< trim END
5580 split XquickfixFails
5581 silent vimgrep anything %
5582 normal o
5583 au BufLeave * ++once source XquickfixFails
5584 " This will trigger the autocommand, which causes an error, what follows
5585 " is aborted but the window was already split.
5586 silent! cwindow
5587 END
5588 call writefile(lines, 'XtestWinFails')
5589 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5590 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5591
5592 " clean up
5593 call term_sendkeys(buf, ":bwipe!\<CR>")
5594 call term_wait(buf)
5595 call StopVimInTerminal(buf)
5596 call delete('XtestWinFails')
5597 call delete('XquickfixFails')
5598endfunc
5599
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005600" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005601" is changed.
5602func Xqfbuf_update(cchar)
5603 call s:setup_commands(a:cchar)
5604
5605 Xexpr "F1:1:line1"
5606 Xopen
5607 call assert_equal(['F1|1| line1'], getline(1, '$'))
5608 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5609
5610 " Test setqflist() using the 'lines' key in 'what'
5611 " add a new entry
5612 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5613 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5614 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5615 " replace all the entries with a single entry
5616 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5617 call assert_equal(['F3|3| line3'], getline(1, '$'))
5618 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5619 " remove all the entries
5620 call g:Xsetlist([], 'r', {'lines' : []})
5621 call assert_equal([''], getline(1, '$'))
5622 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5623 " add a new list
5624 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5625 call assert_equal(['F4|4| line4'], getline(1, '$'))
5626 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5627
5628 " Test setqflist() using the 'items' key in 'what'
5629 " add a new entry
5630 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5631 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5632 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5633 " replace all the entries with a single entry
5634 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5635 call assert_equal(['F6|6| line6'], getline(1, '$'))
5636 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5637 " remove all the entries
5638 call g:Xsetlist([], 'r', {'items' : []})
5639 call assert_equal([''], getline(1, '$'))
5640 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5641 " add a new list
5642 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5643 call assert_equal(['F7|7| line7'], getline(1, '$'))
5644 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5645
5646 call g:Xsetlist([], ' ', {})
5647 call assert_equal([''], getline(1, '$'))
5648 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5649
5650 Xclose
5651endfunc
5652
5653func Test_qfbuf_update()
5654 call Xqfbuf_update('c')
5655 call Xqfbuf_update('l')
5656endfunc
5657
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005658func Test_vimgrep_noswapfile()
5659 set noswapfile
5660 call writefile(['one', 'two', 'three'], 'Xgreppie')
5661 vimgrep two Xgreppie
5662 call assert_equal('two', getline('.'))
5663
5664 call delete('Xgreppie')
5665 set swapfile
5666endfunc
5667
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005668" Test for the :vimgrep 'f' flag (fuzzy match)
5669func Xvimgrep_fuzzy_match(cchar)
5670 call s:setup_commands(a:cchar)
5671
5672 Xvimgrep /three one/f Xfile*
5673 let l = g:Xgetlist()
5674 call assert_equal(2, len(l))
5675 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5676 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5677 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5678 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5679
5680 Xvimgrep /the/f Xfile*
5681 let l = g:Xgetlist()
5682 call assert_equal(3, len(l))
5683 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5684 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5685 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5686 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5687 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5688 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5689
5690 Xvimgrep /aaa/fg Xfile*
5691 let l = g:Xgetlist()
5692 call assert_equal(4, len(l))
5693 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5694 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5695 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5696 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5697 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5698 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5699 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5700 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5701
5702 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5703endfunc
5704
5705func Test_vimgrep_fuzzy_match()
5706 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5707 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5708 call Xvimgrep_fuzzy_match('c')
5709 call Xvimgrep_fuzzy_match('l')
5710 call delete('Xfile1')
5711 call delete('Xfile2')
5712endfunc
5713
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005714func Test_locationlist_open_in_newtab()
5715 call s:create_test_file('Xqftestfile1')
5716 call s:create_test_file('Xqftestfile2')
5717 call s:create_test_file('Xqftestfile3')
5718
5719 %bwipe!
5720
5721 lgetexpr ['Xqftestfile1:5:Line5',
5722 \ 'Xqftestfile2:10:Line10',
5723 \ 'Xqftestfile3:16:Line16']
5724
5725 silent! llast
5726 call assert_equal(1, tabpagenr('$'))
5727 call assert_equal('Xqftestfile3', bufname())
5728
5729 set switchbuf=newtab
5730
5731 silent! lfirst
5732 call assert_equal(2, tabpagenr('$'))
5733 call assert_equal('Xqftestfile1', bufname())
5734
5735 silent! lnext
5736 call assert_equal(3, tabpagenr('$'))
5737 call assert_equal('Xqftestfile2', bufname())
5738
5739 call delete('Xqftestfile1')
5740 call delete('Xqftestfile2')
5741 call delete('Xqftestfile3')
5742 set switchbuf&vim
5743
5744 %bwipe!
5745endfunc
5746
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005747" Test for win_gettype() in quickfix and location list windows
5748func Test_win_gettype()
5749 copen
5750 call assert_equal("quickfix", win_gettype())
5751 let wid = win_getid()
5752 wincmd p
5753 call assert_equal("quickfix", win_gettype(wid))
5754 cclose
5755 lexpr ''
5756 lopen
5757 call assert_equal("loclist", win_gettype())
5758 let wid = win_getid()
5759 wincmd p
5760 call assert_equal("loclist", win_gettype(wid))
5761 lclose
5762endfunc
5763
Christian Brabandt0b226f62021-12-01 10:54:24 +00005764fun Test_vimgrep_nomatch()
5765 call XexprTests('c')
5766 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5767 copen
5768 if has("win32")
5769 call assert_fails('vimgrep foo *.zzz', 'E479:')
5770 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'}]
5771 else
5772 call assert_fails('vimgrep foo *.zzz', 'E480:')
5773 let expected = []
5774 endif
5775 call assert_equal(expected, getqflist())
5776 cclose
5777endfunc
5778
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005779" Test for opening the quickfix window in two tab pages and then closing one
5780" of the quickfix windows. This should not make the quickfix buffer unlisted.
5781" (github issue #9300).
5782func Test_two_qf_windows()
5783 cexpr "F1:1:line1"
5784 copen
5785 tabnew
5786 copen
5787 call assert_true(&buflisted)
5788 cclose
5789 tabfirst
5790 call assert_true(&buflisted)
5791 let bnum = bufnr()
5792 cclose
5793 " if all the quickfix windows are closed, then buffer should be unlisted.
5794 call assert_false(buflisted(bnum))
5795 %bw!
5796
5797 " Repeat the test for a location list
5798 lexpr "F2:2:line2"
5799 lopen
5800 let bnum = bufnr()
5801 tabnew
5802 exe "buffer" bnum
5803 tabfirst
5804 lclose
5805 tablast
5806 call assert_true(buflisted(bnum))
5807 tabclose
5808 lopen
5809 call assert_true(buflisted(bnum))
5810 lclose
5811 call assert_false(buflisted(bnum))
5812 %bw!
5813endfunc
5814
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005815" vim: shiftwidth=2 sts=2 expandtab