blob: 07fdb9644b505570193391ccf69e60bef1450bda [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00004import './vim9.vim' as v9
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020046 let g:Xgetlist = function('getqflist')
47 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020048 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020049 else
50 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
51 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020052 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020053 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020054 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010055 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020057 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xclose <mods>lclose <args>
59 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
60 command! -nargs=* Xgetfile <mods>lgetfile <args>
61 command! -nargs=* Xaddfile <mods>laddfile <args>
62 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
63 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
64 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
65 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020066 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
67 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020068 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
69 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020070 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020071 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020072 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020073 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010074 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020075 command! -nargs=* Xgrep <mods> lgrep <args>
76 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
77 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010078 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020079 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
80 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020081 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
82 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020083 let g:Xgetlist = function('getloclist', [0])
84 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020085 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020086 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010087endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088
Bram Moolenaara5d78d12021-12-15 12:28:22 +000089" This must be run before any error lists are created.
90func Test_AA_cc_no_errors()
91 call assert_fails('cc', 'E42:')
92 call assert_fails('ll', 'E42:')
93endfunc
94
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010096func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020097 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020099 if a:cchar == 'l'
100 call assert_fails('llist', 'E776:')
101 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200103 Xgetexpr []
104 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100105 call assert_true(v:errmsg ==# 'E42: No Errors')
106
107 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200108 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100109 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100110 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100111
112 " List only valid 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([' 2 Xtestfile1:1 col 3: Line1',
115 \ ' 4 Xtestfile2:2 col 2: Line2',
116 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
117
118 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100119 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100120 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
121 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100122 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123
124 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
127 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
128
Bram Moolenaaree85df32017-03-19 14:19:50 +0100129 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100130 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
131
Bram Moolenaaree85df32017-03-19 14:19:50 +0100132 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100133 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
134
Bram Moolenaaree85df32017-03-19 14:19:50 +0100135 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100136 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
137 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100138
139 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100140 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100141 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
142 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100143
thinca6864efa2021-06-19 20:45:20 +0200144 " Ranged entries
145 call g:Xsetlist([{'lnum':10,'text':'Line1'},
146 \ {'lnum':20,'col':10,'text':'Line2'},
147 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
148 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
149 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
150 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
151 let l = split(execute('Xlist', ""), "\n")
152 call assert_equal([' 1:10: Line1',
153 \ ' 2:20 col 10: Line2',
154 \ ' 3:30 col 15-20: Line3',
155 \ ' 4:40-45: Line4',
156 \ ' 5:50-55 col 15: Line5',
157 \ ' 6:60-65 col 25-35: Line6'], l)
158
Bram Moolenaaree85df32017-03-19 14:19:50 +0100159 " Different types of errors
160 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
161 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
162 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
163 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
164 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
165 let l = split(execute('Xlist', ""), "\n")
166 call assert_equal([' 1:10 col 5 warning 11: Warning',
167 \ ' 2:20 col 10 error 22: Error',
168 \ ' 3:30 col 15 info 33: Info',
169 \ ' 4:40 col 20 x 44: Other',
170 \ ' 5:50 col 25 55: one'], l)
171
Bram Moolenaard76ce852018-05-01 15:02:04 +0200172 " Test for module names, one needs to explicitly set `'valid':v:true` so
173 call g:Xsetlist([
174 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
175 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
176 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
177 let l = split(execute('Xlist', ""), "\n")
178 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
179 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
180 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
181
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100182 " For help entries in the quickfix list, only the filename without directory
183 " should be displayed
184 Xhelpgrep setqflist()
185 let l = split(execute('Xlist 1', ''), "\n")
186 call assert_match('^ 1 [^\\/]\{-}:', l[0])
187
Bram Moolenaaree85df32017-03-19 14:19:50 +0100188 " Error cases
189 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100190endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100191
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100192func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100193 call XlistTests('c')
194 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100195endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100196
197" Tests for the :colder, :cnewer, :lolder and :lnewer commands
198" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100199" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100200func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200201 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100202
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200203 if a:cchar == 'l'
204 " No location list for the current window
205 call assert_fails('lolder', 'E776:')
206 call assert_fails('lnewer', 'E776:')
207 endif
208
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200209 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200210 call g:Xsetlist(list)
211
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100212 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100214 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
215
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200216 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100217 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
218
219 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200220 Xgetexpr ['Xtestfile1:1:3:Line1']
221 Xgetexpr ['Xtestfile2:2:2:Line2']
222 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223
224 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200225 Xolder
226 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100227 call assert_equal('Line2', l[0].text)
228
229 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 Xnewer
231 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100232 call assert_equal('Line3', l[0].text)
233
234 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200235 Xolder 2
236 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 call assert_equal('Line1', l[0].text)
238
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200239 Xnewer 2
240 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100241 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100242endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100243
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100244func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100245 call XageTests('c')
246 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100247endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100248
249" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
250" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100251func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200252 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200254 " Opening the location list window without any errors should fail
255 if a:cchar == 'l'
256 call assert_fails('lopen', 'E776:')
257 endif
258
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100259 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200260 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100261
262 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200263 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100264 call assert_true(winnr('$') == 1)
265
266 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200267 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
268 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
270 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200271 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100272 call assert_true(winnr('$') == 2 && winnr() == 2 &&
273 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200274 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100275
276 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200277 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100278 call assert_true(winnr('$') == 1)
279
280 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200281 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100282
283 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200284 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100285 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200286 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100287
288 " Opening the window again, should move the cursor to that window
289 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200290 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100291 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200292 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100293 \ getline('.') ==# '|| non-error 1')
294
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100295 " :cnext in quickfix window should move to the next entry
296 Xnext
297 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100298
299 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200300 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100301 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200302
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100303 " Specifying the width should adjust the width for a vertically split
304 " quickfix window.
305 vert Xopen
306 call assert_equal(10, winwidth(0))
307 vert Xopen 12
308 call assert_equal(12, winwidth(0))
309 Xclose
310
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200311 " Horizontally or vertically splitting the quickfix window should create a
312 " normal window/buffer
313 Xopen
314 wincmd s
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 wincmd v
321 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
322 call assert_equal(0, getwininfo(win_getid())[0].loclist)
323 call assert_notequal('quickfix', &buftype)
324 close
325 Xopen
326 Xclose
327
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200328 if a:cchar == 'c'
329 " Opening the quickfix window in multiple tab pages should reuse the
330 " quickfix buffer
331 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
332 \ 'Xtestfile3:3:1:Line3']
333 Xopen
334 let qfbufnum = bufnr('%')
335 tabnew
336 Xopen
337 call assert_equal(qfbufnum, bufnr('%'))
338 new | only | tabonly
339 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100340endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100341
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100342func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100343 call XwindowTests('c')
344 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100345endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346
Bram Moolenaar36d50222019-05-02 20:17:40 +0200347func Test_copenHeight()
348 copen
349 wincmd H
350 let height = winheight(0)
351 copen 10
352 call assert_equal(height, winheight(0))
353 quit
354endfunc
355
Bram Moolenaar1142a312019-10-16 14:51:39 +0200356func Test_copenHeight_tabline()
357 set tabline=foo showtabline=2
358 copen
359 wincmd H
360 let height = winheight(0)
361 copen 10
362 call assert_equal(height, winheight(0))
363 quit
364 set tabline& showtabline&
365endfunc
366
367
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
369" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100370func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100372
373 call writefile(['Xtestfile1:700:10:Line 700',
374 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
375
376 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200377 Xfile Xqftestfile1
378 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100379 call assert_true(len(l) == 2 &&
380 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
381 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
382
Bram Moolenaar049cba92016-06-26 14:38:04 +0200383 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200384 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200385
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100386 " Run cfile/lfile from a modified buffer
387 enew!
388 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200389 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100390 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
391
392 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200393 Xaddfile Xqftestfile1
394 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395 call assert_true(len(l) == 3 &&
396 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
397
398 call writefile(['Xtestfile1:222:77:Line 222',
399 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
400
401 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200402 Xgetfile Xqftestfile1
403 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100404 call assert_true(len(l) == 2 &&
405 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
406 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
407
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100408 " Test for a file with a long line and without a newline at the end
409 let text = repeat('x', 1024)
410 let t = 'a.txt:18:' . text
411 call writefile([t], 'Xqftestfile1', 'b')
412 silent! Xfile Xqftestfile1
413 call assert_equal(text, g:Xgetlist()[0].text)
414
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100415 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100416endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100417
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100418func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100419 call XfileTests('c')
420 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100421endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100422
423" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
424" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100425func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200426 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100427
428 enew!
429 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
430 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200431 Xbuffer!
432 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100433 call assert_true(len(l) == 2 &&
434 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
435 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
436
437 enew!
438 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
439 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200440 Xgetbuffer
441 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100442 call assert_true(len(l) == 2 &&
443 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
444 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
445
446 enew!
447 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
448 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200449 Xaddbuffer
450 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100451 call assert_true(len(l) == 4 &&
452 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
453 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
454 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200455 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100456
Bram Moolenaaree85df32017-03-19 14:19:50 +0100457 " Check for invalid buffer
458 call assert_fails('Xbuffer 199', 'E474:')
459
460 " Check for unloaded buffer
461 edit Xtestfile1
462 let bnr = bufnr('%')
463 enew!
464 call assert_fails('Xbuffer ' . bnr, 'E681:')
465
466 " Check for invalid range
467 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
468 " commands. So directly call the commands.
469 if (a:cchar == 'c')
470 call assert_fails('900,999cbuffer', 'E16:')
471 else
472 call assert_fails('900,999lbuffer', 'E16:')
473 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100474endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100475
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100476func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100477 call XbufferTests('c')
478 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100479endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100480
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100481func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200482 call s:setup_commands(a:cchar)
483
484 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100485endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200486
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100487func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200488 call XexprTests('c')
489 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100490endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200491
492" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100493func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200494 call s:setup_commands(a:cchar)
495
Bram Moolenaar74240d32017-12-10 15:26:15 +0100496 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200497 " Jumping to first or next location list entry without any error should
498 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100499 if a:cchar == 'c'
500 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100501 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100502 else
503 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100504 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200505 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100506 call assert_fails('Xnext', err)
507 call assert_fails('Xprev', err)
508 call assert_fails('Xnfile', err)
509 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100510 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200511
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100512 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100513 call assert_fails(cmd, 'E42:')
514
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200515 call s:create_test_file('Xqftestfile1')
516 call s:create_test_file('Xqftestfile2')
517
518 Xgetexpr ['Xqftestfile1:5:Line5',
519 \ 'Xqftestfile1:6:Line6',
520 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200521 \ 'Xqftestfile2:11:Line11',
522 \ 'RegularLine1',
523 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200524
525 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100526 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200527 call assert_fails('Xprev', 'E553:')
528 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200529 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200530 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200531 call assert_equal(10, line('.'))
532 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200533 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200534 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100535 5Xcc
536 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
537 2Xcc
538 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100539 if a:cchar == 'c'
540 cc
541 else
542 ll
543 endif
544 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100545 10Xcc
546 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200547 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200549 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200550 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200551 call assert_fails('Xnext', 'E553:')
552 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100553 " To process the range using quickfix list entries, directly use the
554 " quickfix commands (don't use the user defined commands)
555 if a:cchar == 'c'
556 $cc
557 else
558 $ll
559 endif
560 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200561 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200562 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200563 call assert_equal(5, line('.'))
564
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200565 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200566 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200567 call assert_equal(11, line('.'))
568 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200569 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200570 call assert_equal(5, line('.'))
571
Bram Moolenaar74240d32017-12-10 15:26:15 +0100572 " Jumping to an error from the error window using cc command
573 Xgetexpr ['Xqftestfile1:5:Line5',
574 \ 'Xqftestfile1:6:Line6',
575 \ 'Xqftestfile2:10:Line10',
576 \ 'Xqftestfile2:11:Line11']
577 Xopen
578 10Xcc
579 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200580 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100581 Xopen
582 call cursor(2, 1)
583 if a:cchar == 'c'
584 .cc
585 else
586 .ll
587 endif
588 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200589 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100590
591 " Jumping to an error from the error window (when only the error window is
592 " present)
593 Xopen | only
594 Xlast 1
595 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200596 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100597
Bram Moolenaaree85df32017-03-19 14:19:50 +0100598 Xexpr ""
599 call assert_fails('Xnext', 'E42:')
600
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200601 call delete('Xqftestfile1')
602 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200603
604 " Should be able to use next/prev with invalid entries
605 Xexpr ""
606 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
607 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100608 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200609 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
610 Xlast
611 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
612 Xfirst
613 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
614 2Xnext
615 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100616endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200617
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100618func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200619 call Xtest_browse('c')
620 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100621endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200622
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100623func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200624 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100625 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100626
Bram Moolenaarce90e362019-09-08 18:58:44 +0200627 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100628 call assert_fails('vimgrep vim 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_namebuf'), 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
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200633 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100634 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100635
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200636 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100637 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100638
639endfunc
640
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100641func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200642 call s:setup_commands(a:cchar)
643 Xhelpgrep quickfix
644 Xopen
645 if a:cchar == 'c'
646 let title_text = ':helpgrep quickfix'
647 else
648 let title_text = ':lhelpgrep quickfix'
649 endif
650 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200651
652 " Jumping to a help topic should open the help window
653 only
654 Xnext
655 call assert_true(&buftype == 'help')
656 call assert_true(winnr('$') == 2)
657 " Jumping to the next match should reuse the help window
658 Xnext
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
661 call assert_true(winnr('$') == 2)
662 " Jumping to the next match from the quickfix window should reuse the help
663 " window
664 Xopen
665 Xnext
666 call assert_true(&buftype == 'help')
667 call assert_true(winnr() == 1)
668 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200669 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200670
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100671 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200672 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100673
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100674 " When the current window is vertically split, jumping to a help match
675 " should open the help window at the top.
676 only | enew
677 let w1 = win_getid()
678 vert new
679 let w2 = win_getid()
680 Xnext
681 let w3 = win_getid()
682 call assert_true(&buftype == 'help')
683 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100684 " See jump_to_help_window() for details
685 let w2_width = winwidth(w2)
686 if w2_width != &columns && w2_width < 80
687 call assert_equal(['col', [['leaf', w3],
688 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
689 else
690 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
691 \ ['leaf', w1]]] , winlayout())
692 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100693
694 new | only
695 set buftype=help
696 set modified
697 call assert_fails('Xnext', 'E37:')
698 set nomodified
699 new | only
700
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200701 if a:cchar == 'l'
702 " When a help window is present, running :lhelpgrep should reuse the
703 " help window and not the current window
704 new | only
705 call g:Xsetlist([], 'f')
706 help index.txt
707 wincmd w
708 lhelpgrep quickfix
709 call assert_equal(1, winnr())
710 call assert_notequal([], getloclist(1))
711 call assert_equal([], getloclist(2))
712 endif
713
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200714 new | only
715
Bram Moolenaaree85df32017-03-19 14:19:50 +0100716 " Search for non existing help string
717 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200718 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200719 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100720endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200721
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100722func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200723 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200724 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200725 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100726endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100727
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100728def Test_helpgrep_vim9_restore_cpo()
729 assert_equal('aABceFs', &cpo)
730
731 var rtp_save = &rtp
732 var dir = 'Xruntime/after'
733 &rtp ..= ',' .. dir
734 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100735 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100736 filetype plugin on
737 silent helpgrep grail
738 cwindow
739 silent helpgrep grail
740
741 assert_equal('aABceFs', &cpo)
742 delete(dir, 'rf')
743 &rtp = rtp_save
744 cclose
745 helpclose
746enddef
747
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200748def Test_vim9_cexpr()
749 var text = 'somefile:95:error'
750 cexpr text
751 var l = getqflist()
752 assert_equal(1, l->len())
753 assert_equal(95, l[0].lnum)
754 assert_equal('error', l[0].text)
755
756 text = 'somefile:77:warning'
757 caddexpr text
758 l = getqflist()
759 assert_equal(2, l->len())
760 assert_equal(77, l[1].lnum)
761 assert_equal('warning', l[1].text)
762enddef
763
Bram Moolenaar6920c722016-01-22 22:44:10 +0100764func Test_errortitle()
765 augroup QfBufWinEnter
766 au!
767 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
768 augroup END
769 copen
770 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'')'}]
771 call setqflist(a)
772 call assert_equal(':setqflist()', g:a)
773 augroup QfBufWinEnter
774 au!
775 augroup END
776 augroup! QfBufWinEnter
777endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100778
Bram Moolenaar5584df62016-03-18 21:00:51 +0100779func Test_vimgreptitle()
780 augroup QfBufWinEnter
781 au!
782 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
783 augroup END
784 try
785 vimgrep /pattern/j file
786 catch /E480/
787 endtry
788 copen
789 call assert_equal(': vimgrep /pattern/j file', g:a)
790 augroup QfBufWinEnter
791 au!
792 augroup END
793 augroup! QfBufWinEnter
794endfunc
795
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100796func Test_bufwinenter_once()
797 augroup QfBufWinEnter
798 au!
799 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
800 augroup END
801 let g:got_afile = ''
802 copen
803 call assert_equal('got quickfix', g:got_afile)
804
805 cclose
806 unlet g:got_afile
807 augroup QfBufWinEnter
808 au!
809 augroup END
810 augroup! QfBufWinEnter
811endfunc
812
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100813func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200814 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100815
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200816 Xgetexpr ['file:1:1:message']
817 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100818 if a:cchar == 'c'
819 call setqflist(l, 'r')
820 else
821 call setloclist(0, l, 'r')
822 endif
823
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200824 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100825 if a:cchar == 'c'
826 let title = ':setqflist()'
827 else
828 let title = ':setloclist()'
829 endif
830 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200831 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100832endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100833
834" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100835func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200836 call XqfTitleTests('c')
837 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100838endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100839
840" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100841func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100842 let save_efm = &efm
843 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
844 cgetexpr ['WWWW', 'EEEE', 'CCCC']
845 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
846 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
847 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
848 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
849 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
850 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
851 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
852 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
853 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100854endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100855
856" This will test for problems in quickfix:
857" A. incorrectly copying location lists which caused the location list to show
858" a different name than the file that was actually being displayed.
859" B. not reusing the window for which the location list window is opened but
860" instead creating new windows.
861" C. make sure that the location list window is not reused instead of the
862" window it belongs to.
863"
864" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100865func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100866 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
867 let word = substitute(base, '\v(.*)\..*', '\1', '')
868
869 setl modifiable
870 setl noreadonly
871 setl noswapfile
872 setl bufhidden=delete
873 %del _
874 " For problem 2:
875 " 'buftype' has to be set to reproduce the constant opening of new windows
876 setl buftype=nofile
877
878 call setline(1, word)
879
880 setl nomodified
881 setl nomodifiable
882 setl readonly
883 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100884endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100885
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100886func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200887 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100888
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200889 augroup testgroup
890 au!
891 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
892 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100893
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200894 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100895
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200896 let qflist = []
897 for word in words
898 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
899 " NOTE: problem 1:
900 " intentionally not setting 'lnum' so that the quickfix entries are not
901 " valid
902 eval qflist->setloclist(0, ' ')
903 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100904
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200905 " Test A
906 lrewind
907 enew
908 lopen
909 4lnext
910 vert split
911 wincmd L
912 lopen
913 wincmd p
914 lnext
915 let fileName = expand("%")
916 wincmd p
917 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
918 let fileName = substitute(fileName, '\\', '/', 'g')
919 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
920 call assert_equal("test://bar.txt", fileName)
921 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100922
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200923 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100924
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200925 " Test B:
926 lrewind
927 lopen
928 2
929 exe "normal \<CR>"
930 wincmd p
931 3
932 exe "normal \<CR>"
933 wincmd p
934 4
935 exe "normal \<CR>"
936 call assert_equal(2, winnr('$'))
937 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100938
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200939 " Test C:
940 lrewind
941 lopen
942 " Let's move the location list window to the top to check whether it (the
943 " first window found) will be reused when we try to open new windows:
944 wincmd K
945 2
946 exe "normal \<CR>"
947 wincmd p
948 3
949 exe "normal \<CR>"
950 wincmd p
951 4
952 exe "normal \<CR>"
953 1wincmd w
954 call assert_equal('quickfix', &buftype)
955 2wincmd w
956 let bufferName = expand("%")
957 let bufferName = substitute(bufferName, '\\', '/', 'g')
958 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100959
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200960 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100961
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200962 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100963endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100964
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100965func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200966 augroup testgroup
967 au!
968 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
969 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100970
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200971 func! R(n)
972 quit
973 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100974
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200975 new
976 let q = []
977 call add(q, {'filename': 'test_curwin.txt' })
978 call setloclist(0, q)
979 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100980
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200981 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +0000982 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +0100983endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100984
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100985func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200986 call writefile(['loclistfoo'], 'loclistfoo')
987 call writefile(['loclistbar'], 'loclistbar')
988 set switchbuf=usetab
989
990 edit loclistfoo
991 tabedit loclistbar
992 silent lgrep loclistfoo loclist*
993 call assert_equal(1, tabpagenr())
994
995 enew | only | tabonly
996 set switchbuf&vim
997 call delete('loclistfoo')
998 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100999endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001000
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001001" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001002func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001003 " The 'errorformat' setting is different on non-Unix systems.
1004 " This test works only on Unix-like systems.
1005 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001006
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001007 let l =<< trim [DATA]
1008 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1009 "Xtestfile", line 6 col 19; this is an error
1010 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1011 Xtestfile:9: parse error before `asd'
1012 make: *** [vim] Error 1
1013 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001014
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001015 2 returned
1016 "Xtestfile", line 11 col 1; this is an error
1017 "Xtestfile", line 12 col 2; this is another error
1018 "Xtestfile", line 14:10; this is an error in column 10
1019 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1020 "Xtestfile", linenr 16: yet another problem
1021 Error in "Xtestfile" at line 17:
1022 x should be a dot
1023 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1024 ^
1025 Error in "Xtestfile" at line 18:
1026 x should be a dot
1027 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1028 .............^
1029 Error in "Xtestfile" at line 19:
1030 x should be a dot
1031 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1032 --------------^
1033 Error in "Xtestfile" at line 20:
1034 x should be a dot
1035 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1036 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001037
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001038 Does anyone know what is the problem and how to correction it?
1039 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1040 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1041 [DATA]
1042
1043 call writefile(l, 'Xerrorfile1')
1044 call writefile(l[:-2], 'Xerrorfile2')
1045
1046 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001047 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1048 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1049 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1051 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1052 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1055 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1056 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1060 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1061 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1062 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1063 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1064 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1065 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1066 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1067 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1068[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001069 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001070
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001071 let save_efm = &efm
1072 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1073 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001074
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001075 exe 'cf Xerrorfile2'
1076 clast
1077 copen
1078 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1079 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001080
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001081 exe 'cf Xerrorfile1'
1082 call assert_equal([4, 12], [line('.'), col('.')])
1083 cn
1084 call assert_equal([6, 19], [line('.'), col('.')])
1085 cn
1086 call assert_equal([9, 2], [line('.'), col('.')])
1087 cn
1088 call assert_equal([10, 2], [line('.'), col('.')])
1089 cn
1090 call assert_equal([11, 1], [line('.'), col('.')])
1091 cn
1092 call assert_equal([12, 2], [line('.'), col('.')])
1093 cn
1094 call assert_equal([14, 10], [line('.'), col('.')])
1095 cn
1096 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1097 cn
1098 call assert_equal([16, 2], [line('.'), col('.')])
1099 cn
1100 call assert_equal([17, 6], [line('.'), col('.')])
1101 cn
1102 call assert_equal([18, 7], [line('.'), col('.')])
1103 cn
1104 call assert_equal([19, 8], [line('.'), col('.')])
1105 cn
1106 call assert_equal([20, 9], [line('.'), col('.')])
1107 clast
1108 cprev
1109 cprev
1110 wincmd w
1111 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1112 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001113
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001114 let &efm = save_efm
1115 call delete('Xerrorfile1')
1116 call delete('Xerrorfile2')
1117 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001118endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001119
Bram Moolenaarab47c612016-06-14 22:02:26 +02001120" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001121func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001122 call s:setup_commands(a:cchar)
1123
Bram Moolenaarab47c612016-06-14 22:02:26 +02001124 let save_efm=&efm
1125 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1126
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001127 let lines = ["Entering dir 'dir1/a'",
1128 \ 'habits2.txt:1:Nine Healthy Habits',
1129 \ "Entering dir 'b'",
1130 \ 'habits3.txt:2:0 Hours of television',
1131 \ 'habits2.txt:7:5 Small meals',
1132 \ "Entering dir 'dir1/c'",
1133 \ 'habits4.txt:3:1 Hour of exercise',
1134 \ "Leaving dir 'dir1/c'",
1135 \ "Leaving dir 'dir1/a'",
1136 \ 'habits1.txt:4:2 Liters of water',
1137 \ "Entering dir 'dir2'",
1138 \ 'habits5.txt:5:3 Cups of hot green tea',
1139 \ "Leaving dir 'dir2'"
1140 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001141
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001142 Xexpr ""
1143 for l in lines
1144 Xaddexpr l
1145 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001146
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001147 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001148
1149 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1150 call assert_equal(1, qf[1].lnum)
1151 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1152 call assert_equal(2, qf[3].lnum)
1153 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1154 call assert_equal(7, qf[4].lnum)
1155 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1156 call assert_equal(3, qf[6].lnum)
1157 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1158 call assert_equal(4, qf[9].lnum)
1159 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1160 call assert_equal(5, qf[11].lnum)
1161
1162 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001163endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001164
1165" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001166func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001167 " Create the directory stack and files
1168 call mkdir('dir1')
1169 call mkdir('dir1/a')
1170 call mkdir('dir1/a/b')
1171 call mkdir('dir1/c')
1172 call mkdir('dir2')
1173
1174 let lines = ["Nine Healthy Habits",
1175 \ "0 Hours of television",
1176 \ "1 Hour of exercise",
1177 \ "2 Liters of water",
1178 \ "3 Cups of hot green tea",
1179 \ "4 Short mental breaks",
1180 \ "5 Small meals",
1181 \ "6 AM wake up time",
1182 \ "7 Minutes of laughter",
1183 \ "8 Hours of sleep (at least)",
1184 \ "9 PM end of the day and off to bed"
1185 \ ]
1186 call writefile(lines, 'habits1.txt')
1187 call writefile(lines, 'dir1/a/habits2.txt')
1188 call writefile(lines, 'dir1/a/b/habits3.txt')
1189 call writefile(lines, 'dir1/c/habits4.txt')
1190 call writefile(lines, 'dir2/habits5.txt')
1191
1192 call s:dir_stack_tests('c')
1193 call s:dir_stack_tests('l')
1194
1195 call delete('dir1', 'rf')
1196 call delete('dir2', 'rf')
1197 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001198endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001199
Bram Moolenaar9b457942016-10-09 16:10:05 +02001200" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001201func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001202 call s:setup_commands(a:cchar)
1203
1204 let save_efm = &efm
1205
1206 let &efm =
1207 \ '%Eerror %m %l,' .
1208 \ '%-Wignored %m %l,' .
1209 \ '%+Cmore ignored %m %l,' .
1210 \ '%Zignored end'
1211 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1212 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1213 call assert_equal([['resync', 1, 4, 'E']], l)
1214
1215 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001216endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001217
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001218func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001219 call Xefm_ignore_continuations('c')
1220 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001221endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001222
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001223" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001224func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001225 call s:setup_commands(a:cchar)
1226
Bram Moolenaar049cba92016-06-26 14:38:04 +02001227 let save_efm = &efm
1228
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001229 set efm=%f:%l:%m,%f:%f:%l:%m
1230 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1231
1232 set efm=%f:%l:%m,%f:%l:%r:%m
1233 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1234
1235 set efm=%f:%l:%m,%O:%f:%l:%m
1236 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1237
1238 set efm=%f:%l:%m,%f:%l:%*[^a-z
1239 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1240
1241 set efm=%f:%l:%m,%f:%l:%*c
1242 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1243
1244 set efm=%f:%l:%m,%L%M%N
1245 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1246
1247 set efm=%f:%l:%m,%f:%l:%m:%R
1248 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1249
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001250 " Invalid regular expression
1251 set efm=%\\%%k
1252 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1253
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001254 set efm=
1255 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1256
1257 set efm=%DEntering\ dir\ abc,%f:%l:%m
1258 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1259
1260 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001261endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001262
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001263func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001264 call Xinvalid_efm_Tests('c')
1265 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001266endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001267
1268" TODO:
1269" Add tests for the following formats in 'errorformat'
1270" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001271func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001272 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001273
1274 " Test for %s format in efm
1275 set efm=%f:%s
1276 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001277 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001278 call assert_equal('^\VLine search text\$', l[0].pattern)
1279 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001280
Bram Moolenaaree85df32017-03-19 14:19:50 +01001281 let l = split(execute('clist', ''), "\n")
1282 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1283
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001284 " Test for a long line
1285 cexpr 'Xtestfile:' . repeat('a', 1026)
1286 let l = getqflist()
1287 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1288
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001289 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001290 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001291 [Xtestfile1]
1292 (1,17) error: ';' missing
1293 (21,2) warning: variable 'z' not defined
1294 (67,3) error: end of file found before string ended
1295 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001296
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001297 [Xtestfile2]
1298 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001299
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001300 [Xtestfile3]
1301 NEW compiler v1.1
1302 (2,2) warning: variable 'x' not defined
1303 (67,3) warning: 's' already defined
1304 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001305 [DATA]
1306
Bram Moolenaaree85df32017-03-19 14:19:50 +01001307 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001308 " To exercise the push/pop file functionality in quickfix, the test files
1309 " need to be created.
1310 call writefile(['Line1'], 'Xtestfile1')
1311 call writefile(['Line2'], 'Xtestfile2')
1312 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001313 cexpr ""
1314 for l in lines
1315 caddexpr l
1316 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001317 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001318 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001319 call assert_equal(21, l[2].lnum)
1320 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001321 call assert_equal('w', l[2].type)
1322 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001323 call delete('Xtestfile1')
1324 call delete('Xtestfile2')
1325 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001326
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001327 " Test for %P, %Q with non-existing files
1328 cexpr lines
1329 let l = getqflist()
1330 call assert_equal(14, len(l))
1331 call assert_equal('[Xtestfile1]', l[0].text)
1332 call assert_equal('[Xtestfile2]', l[6].text)
1333 call assert_equal('[Xtestfile3]', l[9].text)
1334
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001335 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001336 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001337 Error 275
1338 line 42
1339 column 3
1340 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001341 [DATA]
1342
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001343 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1344 cgetexpr lines
1345 let l = getqflist()
1346 call assert_equal(275, l[0].nr)
1347 call assert_equal(42, l[0].lnum)
1348 call assert_equal(3, l[0].col)
1349 call assert_equal('E', l[0].type)
1350 call assert_equal("\n' ' expected after '--'", l[0].text)
1351
1352 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001353 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001354 Error in line 147 of foo.c:
1355 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001356 [DATA]
1357
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001358 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1359 cgetexpr lines
1360 let l = getqflist()
1361 call assert_equal(147, l[0].lnum)
1362 call assert_equal('E', l[0].type)
1363 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001364
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001365 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001366 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001367 ==============================================================
1368 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1369 --------------------------------------------------------------
1370 Traceback (most recent call last):
1371 File "unittests/dbfacadeTest.py", line 89, in testFoo
1372 self.assertEquals(34, dtid)
1373 File "/usr/lib/python2.2/unittest.py", line 286, in
1374 failUnlessEqual
1375 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001376 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001377
1378 --------------------------------------------------------------
1379 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001380 [DATA]
1381
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001382 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001383 cgetexpr lines
1384 let l = getqflist()
1385 call assert_equal(8, len(l))
1386 call assert_equal(89, l[4].lnum)
1387 call assert_equal(1, l[4].valid)
1388 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001389 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001390
Bram Moolenaard76ce852018-05-01 15:02:04 +02001391 " Test for %o
1392 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001393 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1394 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001395 let l = getqflist()
1396 call assert_equal(1, len(l), string(l))
1397 call assert_equal('Language.PureScript.Types', l[0].module)
1398 copen
1399 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1400 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001401 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001402 cclose
1403 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001404 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001405
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001406 " Test for a long module name
1407 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1408 let l = getqflist()
1409 call assert_equal(repeat('m', 1024), l[0].module)
1410 call assert_equal(15, l[0].lnum)
1411 call assert_equal('message', l[0].text)
1412
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001413 " The following sequence of commands used to crash Vim
1414 set efm=%W%m
1415 cgetexpr ['msg1']
1416 let l = getqflist()
1417 call assert_equal(1, len(l), string(l))
1418 call assert_equal('msg1', l[0].text)
1419 set efm=%C%m
1420 lexpr 'msg2'
1421 let l = getloclist(0)
1422 call assert_equal(1, len(l), string(l))
1423 call assert_equal('msg2', l[0].text)
1424 lopen
1425 call setqflist([], 'r')
1426 caddbuf
1427 let l = getqflist()
1428 call assert_equal(1, len(l), string(l))
1429 call assert_equal('|| msg2', l[0].text)
1430
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001431 " When matching error lines, case should be ignored. Test for this.
1432 set noignorecase
1433 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1434 call assert_equal(10, l.items[0].lnum)
1435 call assert_equal('Line 20', l.items[0].text)
1436 set ignorecase&
1437
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001438 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001439 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001440endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001441
Bram Moolenaare9283662020-06-07 14:10:47 +02001442" Test for '%t' (error type) field in 'efm'
1443func Test_efm_error_type()
1444 let save_efm = &efm
1445
1446 " error type
1447 set efm=%f:%l:%t:%m
1448 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1449 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1450 let output = split(execute('clist'), "\n")
1451 call assert_equal([
1452 \ ' 1 Xfile1:10 error: msg1',
1453 \ ' 2 Xfile1:20 warning: msg2',
1454 \ ' 3 Xfile1:30 info: msg3',
1455 \ ' 4 Xfile1:40 note: msg4',
1456 \ ' 5 Xfile1:50 R: msg5'], output)
1457
1458 " error type and a error number
1459 set efm=%f:%l:%t:%n:%m
1460 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1461 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1462 let output = split(execute('clist'), "\n")
1463 call assert_equal([
1464 \ ' 1 Xfile1:10 error 2: msg1',
1465 \ ' 2 Xfile1:20 warning 4: msg2',
1466 \ ' 3 Xfile1:30 info 6: msg3',
1467 \ ' 4 Xfile1:40 note 8: msg4',
1468 \ ' 5 Xfile1:50 R 3: msg5'], output)
1469 let &efm = save_efm
1470endfunc
1471
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001472func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001473 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001474 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001475 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001476 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001477 colder
1478 cgetexpr []
1479 endfunc
1480 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001481 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001482 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001483 lolder
1484 lgetexpr []
1485 endfunc
1486 endif
1487
1488 augroup testgroup
1489 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001490 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001491 augroup END
1492
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001493 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001494 let words = [ "a", "b" ]
1495 let qflist = []
1496 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001497 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001498 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001499 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001500 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001501
1502 augroup! testgroup
1503endfunc
1504
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001505func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001506 call XquickfixChangedByAutocmd('c')
1507 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001508endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001509
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001510func Test_setloclist_in_autocommand()
1511 call writefile(['test1', 'test2'], 'Xfile')
1512 edit Xfile
1513 let s:bufnr = bufnr()
1514 call setloclist(1,
1515 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1516 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1517
1518 augroup Test_LocList
1519 au!
1520 autocmd BufEnter * call setloclist(1,
1521 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1522 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1523 augroup END
1524
1525 lopen
1526 call assert_fails('exe "normal j\<CR>"', 'E926:')
1527
1528 augroup Test_LocList
1529 au!
1530 augroup END
1531 call delete('Xfile')
1532endfunc
1533
Bram Moolenaar8b201792016-03-25 15:01:10 +01001534func Test_caddbuffer_to_empty()
1535 helpgr quickfix
1536 call setqflist([], 'r')
1537 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001538 try
1539 cn
1540 catch
1541 " number of matches is unknown
1542 call assert_true(v:exception =~ 'E553:')
1543 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001544 quit!
1545endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001546
1547func Test_cgetexpr_works()
1548 " this must not crash Vim
1549 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001550 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001551endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001552
1553" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001554func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001555 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001556
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001557 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001558 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001560 call assert_equal(2, len(l))
1561 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001562 call assert_equal(3, l[1].end_lnum)
1563 call assert_equal(4, l[1].col)
1564 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001565
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001566 Xnext
1567 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1568 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001569 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001570 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001571 call assert_equal(3, line('.'))
1572
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001573 " Appending entries to the list should not change the cursor position
1574 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001575 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001576 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001577 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001578 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1579 call assert_equal(1, line('.'))
1580 close
1581
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001582 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001583 \ {'bufnr': a:bnum, 'lnum': 4},
1584 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001585 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001586 call assert_equal(3, len(l))
1587 call assert_equal(5, l[2].lnum)
1588
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001589 call g:Xsetlist([])
1590 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001591 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001592
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001593 " Tests for setting the 'valid' flag
1594 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1595 Xwindow
1596 call assert_equal(1, winnr('$'))
1597 let l = g:Xgetlist()
1598 call g:Xsetlist(l)
1599 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001600 " Adding a non-valid entry should not mark the list as having valid entries
1601 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1602 Xwindow
1603 call assert_equal(1, winnr('$'))
1604
1605 " :cnext/:cprev should still work even with invalid entries in the list
1606 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1607 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1608 call g:Xsetlist(l)
1609 Xnext
1610 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1611 Xprev
1612 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1613 " :cnext/:cprev should still work after appending invalid entries to an
1614 " empty list
1615 call g:Xsetlist([])
1616 call g:Xsetlist(l, 'a')
1617 Xnext
1618 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1619 Xprev
1620 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1621
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001622 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1623 Xwindow
1624 call assert_equal(2, winnr('$'))
1625 Xclose
1626 let save_efm = &efm
1627 set efm=%m
1628 Xgetexpr 'TestMessage'
1629 let l = g:Xgetlist()
1630 call g:Xsetlist(l)
1631 call assert_equal(1, g:Xgetlist()[0].valid)
1632 let &efm = save_efm
1633
Bram Moolenaaree85df32017-03-19 14:19:50 +01001634 " Error cases:
1635 " Refer to a non-existing buffer and pass a non-dictionary type
1636 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1637 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1638 call g:Xsetlist([[1, 2,3]])
1639 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001640 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001641endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001642
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001643func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001644 new Xtestfile | only
1645 let bnum = bufnr('%')
1646 call setline(1, range(1,5))
1647
1648 call SetXlistTests('c', bnum)
1649 call SetXlistTests('l', bnum)
1650
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001651 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001652 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001653endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001654
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001655func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001656 call s:setup_commands(a:cchar)
1657
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001658 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001659 let @/ = 'Test_'
1660 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001661 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001662 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001663 Xvimgrep empty test_quickfix.vim
1664 call assert_true(len(g:Xgetlist()) > 0)
1665 Xvimgrep matches test_quickfix.vim
1666 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001667 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001668 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001669 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001670 call g:Xsetlist([], 'r')
1671 call assert_true(len(g:Xgetlist()) == 0)
1672 Xolder
1673 call assert_equal(testlen, len(g:Xgetlist()))
1674 Xnewer
1675 Xnewer
1676 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001677endfunc
1678
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001679func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001680 call Xlist_empty_middle('c')
1681 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001682endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001683
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001684func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001685 call s:setup_commands(a:cchar)
1686
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001687 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001688 Xvimgrep one test_quickfix.vim
1689 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001690 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001691 Xvimgrep two test_quickfix.vim
1692 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001693 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001694 Xvimgrep three test_quickfix.vim
1695 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001696 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001697 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001698 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001699 call g:Xsetlist([], 'r')
1700 call assert_true(len(g:Xgetlist()) == 0)
1701 Xnewer
1702 call assert_equal(twolen, len(g:Xgetlist()))
1703 Xnewer
1704 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001705endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001706
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001707func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001708 call Xlist_empty_older('c')
1709 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001710endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001711
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001712func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001713 call s:setup_commands(a:cchar)
1714
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001715 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1716 \ {'filename': 'fnameB', 'text': 'B'}]
1717 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1718 \ {'filename': 'fnameD', 'text': 'D'},
1719 \ {'filename': 'fnameE', 'text': 'E'}]
1720
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001721 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001722 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001723 silent! Xnewer 99
1724 call g:Xsetlist(list1)
1725 call g:Xsetlist(list2)
1726 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001727 call assert_equal(3, len(li))
1728 call assert_equal('C', li[0]['text'])
1729 call assert_equal('D', li[1]['text'])
1730 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001731 silent! Xolder
1732 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001733 call assert_equal(2, len(li))
1734 call assert_equal('A', li[0]['text'])
1735 call assert_equal('B', li[1]['text'])
1736
1737 " {action} is specified ' '.
1738 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 silent! Xnewer 99
1740 call g:Xsetlist(list1)
1741 call g:Xsetlist(list2, ' ')
1742 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001743 call assert_equal(3, len(li))
1744 call assert_equal('C', li[0]['text'])
1745 call assert_equal('D', li[1]['text'])
1746 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001747 silent! Xolder
1748 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001749 call assert_equal(2, len(li))
1750 call assert_equal('A', li[0]['text'])
1751 call assert_equal('B', li[1]['text'])
1752
1753 " {action} is specified 'a'.
1754 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001755 silent! Xnewer 99
1756 call g:Xsetlist(list1)
1757 call g:Xsetlist(list2, 'a')
1758 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001759 call assert_equal(5, len(li))
1760 call assert_equal('A', li[0]['text'])
1761 call assert_equal('B', li[1]['text'])
1762 call assert_equal('C', li[2]['text'])
1763 call assert_equal('D', li[3]['text'])
1764 call assert_equal('E', li[4]['text'])
1765
1766 " {action} is specified 'r'.
1767 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001768 silent! Xnewer 99
1769 call g:Xsetlist(list1)
1770 call g:Xsetlist(list2, 'r')
1771 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001772 call assert_equal(3, len(li))
1773 call assert_equal('C', li[0]['text'])
1774 call assert_equal('D', li[1]['text'])
1775 call assert_equal('E', li[2]['text'])
1776
1777 " Test for wrong value.
1778 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001779 call assert_fails("call g:Xsetlist(0)", 'E714:')
1780 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1781 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1782 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1783 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001784endfunc
1785
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001786func Test_setqflist_invalid_nr()
1787 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001788 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001789endfunc
1790
Bram Moolenaar99234f22020-02-10 22:56:54 +01001791func Test_setqflist_user_sets_buftype()
1792 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1793 set buftype=quickfix
1794 call setqflist([], 'a')
1795 enew
1796endfunc
1797
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001798func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001799 call XquickfixSetListWithAct('c')
1800 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001801endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001802
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001803func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001804 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001805
Bram Moolenaar049cba92016-06-26 14:38:04 +02001806 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001807 call assert_equal(1, l[0].lnum)
1808 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001809 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001810 call assert_equal(2, l[1].lnum)
1811 call assert_equal(1, l[1].col)
1812 call assert_equal(4070, len(l[1].text))
1813 call assert_equal(3, l[2].lnum)
1814 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001815 call assert_equal(4070, len(l[2].text))
1816 call assert_equal(4, l[3].lnum)
1817 call assert_equal(1, l[3].col)
1818 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001819
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001820 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001821endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001822
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001823func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001824 call s:setup_commands(a:cchar)
1825
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001826 let testfile = 'samples/quickfix.txt'
1827
1828 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001829 exe 'Xgetfile' testfile
1830 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001831
1832 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 Xexpr readfile(testfile)
1834 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001835
1836 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001837 Xexpr join(readfile(testfile), "\n")
1838 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001839
1840 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001841 exe 'edit' testfile
1842 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001843 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001844endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001845
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001846func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001847 call s:long_lines_tests('c')
1848 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001849endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001850
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001851func Test_cgetfile_on_long_lines()
1852 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1853 " are read at a time.
1854 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1855 let lines = [
1856 \ '/tmp/file1:1:1:aaa',
1857 \ '/tmp/file2:1:1:%s',
1858 \ '/tmp/file3:1:1:bbb',
1859 \ '/tmp/file4:1:1:ccc',
1860 \ ]
1861 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1862 call writefile(lines, 'Xcqetfile.txt')
1863 cgetfile Xcqetfile.txt
1864 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1865 endfor
1866 call delete('Xcqetfile.txt')
1867endfunc
1868
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001869func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001870 let l = []
1871 for i in range(1, 20)
1872 call add(l, 'Line' . i)
1873 endfor
1874 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001875endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001876
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001877func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001878 call s:create_test_file('Xqftestfile1')
1879 call s:create_test_file('Xqftestfile2')
1880 call s:create_test_file('Xqftestfile3')
1881
1882 new | only
1883 edit Xqftestfile1
1884 let file1_winid = win_getid()
1885 new Xqftestfile2
1886 let file2_winid = win_getid()
1887 cgetexpr ['Xqftestfile1:5:Line5',
1888 \ 'Xqftestfile1:6:Line6',
1889 \ 'Xqftestfile2:10:Line10',
1890 \ 'Xqftestfile2:11:Line11',
1891 \ 'Xqftestfile3:15:Line15',
1892 \ 'Xqftestfile3:16:Line16']
1893
1894 new
1895 let winid = win_getid()
1896 cfirst | cnext
1897 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001898 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001899 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001900 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001901 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001902
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001903 " Test for 'switchbuf' set to search for files in windows in the current
1904 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001905 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001906 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001907 cfirst | cnext
1908 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001909 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001910 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001911 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001912 call assert_equal(file2_winid, win_getid())
1913
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001914 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1915 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001916 enew | only
1917 set switchbuf=usetab
1918 tabedit Xqftestfile1
1919 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001920 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001921 tabfirst
1922 cfirst | cnext
1923 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001924 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001925 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001926 6cnext
1927 call assert_equal(4, tabpagenr())
1928 2cpfile
1929 call assert_equal(2, tabpagenr())
1930 2cnfile
1931 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001932 tabfirst | tabonly | enew
1933
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001934 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001935 set switchbuf=split
1936 cfirst | cnext
1937 call assert_equal(1, winnr('$'))
1938 cnext | cnext
1939 call assert_equal(2, winnr('$'))
1940 cnext | cnext
1941 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001942
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001943 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001944 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001945 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001946 cfirst | cnext
1947 call assert_equal(1, tabpagenr('$'))
1948 cnext | cnext
1949 call assert_equal(2, tabpagenr('$'))
1950 cnext | cnext
1951 call assert_equal(3, tabpagenr('$'))
1952 tabfirst | enew | tabonly | only
1953
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001954 set switchbuf=uselast
1955 split
1956 let last_winid = win_getid()
1957 copen
1958 exe "normal 1G\<CR>"
1959 call assert_equal(last_winid, win_getid())
1960 enew | only
1961
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001962 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1963 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001964 set switchbuf=
1965 edit Xqftestfile1
1966 let file1_winid = win_getid()
1967 new Xqftestfile2
1968 let file2_winid = win_getid()
1969 copen
1970 exe "normal 1G\<CR>"
1971 call assert_equal(file1_winid, win_getid())
1972 copen
1973 exe "normal 3G\<CR>"
1974 call assert_equal(file2_winid, win_getid())
1975 copen | only
1976 exe "normal 5G\<CR>"
1977 call assert_equal(2, winnr('$'))
1978 call assert_equal(1, bufwinnr('Xqftestfile3'))
1979
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001980 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001981 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001982 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001983 set switchbuf=usetab
1984 tabedit Xqftestfile1
1985 tabedit Xqftestfile2
1986 tabedit Xqftestfile3
1987 tabfirst
1988 copen | only
1989 clast
1990 call assert_equal(4, tabpagenr())
1991 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001992
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001993 " Jumping to a file that is not present in any of the tabpages and the
1994 " current tabpage doesn't have any usable windows, should open it in a new
1995 " window in the current tabpage.
1996 copen | only
1997 cfirst
1998 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001999 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002000
2001 " If opening a file changes 'switchbuf', then the new value should be
2002 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002003 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002004 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
2005 enew | only
2006 set switchbuf&vim
2007 cexpr "Xqftestfile1:1:10"
2008 call assert_equal('split', &switchbuf)
2009 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2010 enew | only
2011 set switchbuf=useopen
2012 cexpr "Xqftestfile1:1:10"
2013 call assert_equal('usetab', &switchbuf)
2014 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2015 enew | only
2016 set switchbuf=useopen
2017 cexpr "Xqftestfile1:1:10"
2018 call assert_equal('', &switchbuf)
2019
Bram Moolenaar049cba92016-06-26 14:38:04 +02002020 call delete('Xqftestfile1')
2021 call delete('Xqftestfile2')
2022 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002023 set switchbuf&vim
2024
2025 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002026endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002027
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002028func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002029 call s:setup_commands(a:cchar)
2030
2031 enew | only
2032
Bram Moolenaarc1542742016-07-20 21:44:37 +02002033 let fname = 'Xqftestfile' . a:cchar
2034 call s:create_test_file(fname)
2035 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002036
Bram Moolenaarc1542742016-07-20 21:44:37 +02002037 Xgetexpr [fname . ':5:Line5',
2038 \ fname . ':10:Line10',
2039 \ fname . ':15:Line15',
2040 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002041
2042 6,14delete
2043 call append(6, ['Buffer', 'Window'])
2044
2045 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002046 call assert_equal(5, l[0].lnum)
2047 call assert_equal(6, l[2].lnum)
2048 call assert_equal(13, l[3].lnum)
2049
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002050 " If a file doesn't have any quickfix entries, then deleting lines in the
2051 " file should not update the quickfix list
2052 call g:Xsetlist([], 'f')
2053 1,2delete
2054 call assert_equal([], g:Xgetlist())
2055
Bram Moolenaar049cba92016-06-26 14:38:04 +02002056 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002057 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002058endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002059
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002060func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002061 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002062 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002063 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002064 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002065endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002066
2067" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002068func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002069 call s:setup_commands(a:cchar)
2070
2071 " The following lines are used for the grep test. Don't remove.
2072 " Grep_Test_Text: Match 1
2073 " Grep_Test_Text: Match 2
2074 " GrepAdd_Test_Text: Match 1
2075 " GrepAdd_Test_Text: Match 2
2076 enew! | only
2077 set makeef&vim
2078 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002079 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002080 Xopen
2081 call assert_true(w:quickfix_title =~ '^:grep')
2082 Xclose
2083 enew
2084 set makeef=Temp_File_##
2085 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002086 call assert_true(len(g:Xgetlist()) == 9)
2087
2088 " Try with 'grepprg' set to 'internal'
2089 set grepprg=internal
2090 silent Xgrep Grep_Test_Text: test_quickfix.vim
2091 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2092 call assert_true(len(g:Xgetlist()) == 9)
2093 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002094
2095 call writefile(['Vim'], 'XtestTempFile')
2096 set makeef=XtestTempFile
2097 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002098 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002099 call assert_false(filereadable('XtestTempFile'))
2100 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002101endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002102
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002103func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002104 " The grepprg may not be set on non-Unix systems
2105 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002106
2107 call s:test_xgrep('c')
2108 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002109endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002110
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002111func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002112 " Use one 'errorformat' for two windows. Add an expression to each of them,
2113 " make sure they each keep their own state.
2114 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2115 call mkdir('Xone/a', 'p')
2116 call mkdir('Xtwo/a', 'p')
2117 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2118 call writefile(lines, 'Xone/a/one.txt')
2119 call writefile(lines, 'Xtwo/a/two.txt')
2120
2121 new one
2122 let one_id = win_getid()
2123 lexpr ""
2124 new two
2125 let two_id = win_getid()
2126 lexpr ""
2127
2128 laddexpr "Entering dir 'Xtwo/a'"
2129 call win_gotoid(one_id)
2130 laddexpr "Entering dir 'Xone/a'"
2131 call win_gotoid(two_id)
2132 laddexpr 'two.txt:5:two two two'
2133 call win_gotoid(one_id)
2134 laddexpr 'one.txt:3:one one one'
2135
2136 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002137 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2138 call assert_equal(3, loc_one[1].lnum)
2139
2140 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002141 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2142 call assert_equal(5, loc_two[1].lnum)
2143
2144 call win_gotoid(one_id)
2145 bwipe!
2146 call win_gotoid(two_id)
2147 bwipe!
2148 call delete('Xone', 'rf')
2149 call delete('Xtwo', 'rf')
2150endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002151
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002152func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002153 call s:setup_commands(a:cchar)
2154
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002155 " Calling lbottom without any errors should fail
2156 if a:cchar == 'l'
2157 call assert_fails('lbottom', 'E776:')
2158 endif
2159
Bram Moolenaar875feea2017-06-11 16:07:51 +02002160 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002161 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002162 let wid = win_getid()
2163 call assert_equal(1, line('.'))
2164 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002165 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002166 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002167 call win_gotoid(wid)
2168 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002169 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002170endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002171
2172" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002173func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002174 call XbottomTests('c')
2175 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002176endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002177
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002178func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002179 call s:setup_commands(a:cchar)
2180
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002181 " clear all lists after the first one, then replace the first one.
2182 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002183 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002184 let entry = {'filename': 'foo', 'lnum': 42}
2185 call g:Xsetlist([entry], 'r')
2186 call g:Xsetlist([entry, entry])
2187 call g:Xsetlist([entry, entry, entry])
2188 let res = split(execute(a:cchar . 'hist'), "\n")
2189 call assert_equal(3, len(res))
2190 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2191 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2192 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2193 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002194
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002195 " Test for changing the quickfix lists
2196 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2197 exe '1' . a:cchar . 'hist'
2198 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2199 exe '3' . a:cchar . 'hist'
2200 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2201 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2202 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2203
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002204 call g:Xsetlist([], 'f')
2205 let l = split(execute(a:cchar . 'hist'), "\n")
2206 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002207 if a:cchar == 'c'
2208 call assert_fails('4chist', 'E16:')
2209 else
2210 call assert_fails('4lhist', 'E776:')
2211 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002212
2213 " An empty list should still show the stack history
2214 call g:Xsetlist([])
2215 let res = split(execute(a:cchar . 'hist'), "\n")
2216 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2217
2218 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002219endfunc
2220
2221func Test_history()
2222 call HistoryTest('c')
2223 call HistoryTest('l')
2224endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002225
2226func Test_duplicate_buf()
2227 " make sure we can get the highest buffer number
2228 edit DoesNotExist
2229 edit DoesNotExist2
2230 let last_buffer = bufnr("$")
2231
2232 " make sure only one buffer is created
2233 call writefile(['this one', 'that one'], 'Xgrepthis')
2234 vimgrep one Xgrepthis
2235 vimgrep one Xgrepthis
2236 call assert_equal(last_buffer + 1, bufnr("$"))
2237
2238 call delete('Xgrepthis')
2239endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002240
2241" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002242func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002243 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002244
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002245 " Error cases
2246 call assert_fails('call g:Xgetlist(99)', 'E715:')
2247 call assert_fails('call g:Xsetlist(99)', 'E714:')
2248 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002249
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002250 " Set and get the title
2251 call g:Xsetlist([])
2252 Xopen
2253 wincmd p
2254 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2255 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2256 call assert_equal(0, s)
2257 let d = g:Xgetlist({"title":1})
2258 call assert_equal('Sample', d.title)
2259 " Try setting title to a non-string value
2260 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2261 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2262
2263 Xopen
2264 call assert_equal('Sample', w:quickfix_title)
2265 Xclose
2266
2267 " Tests for action argument
2268 silent! Xolder 999
2269 let qfnr = g:Xgetlist({'all':1}).nr
2270 call g:Xsetlist([], 'r', {'title' : 'N1'})
2271 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2272 call g:Xsetlist([], ' ', {'title' : 'N2'})
2273 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2274
2275 let res = g:Xgetlist({'nr': 0})
2276 call assert_equal(qfnr + 1, res.nr)
2277 call assert_equal(['nr'], keys(res))
2278
2279 call g:Xsetlist([], ' ', {'title' : 'N3'})
2280 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2281
2282 " Changing the title of an earlier quickfix list
2283 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2284 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2285
2286 " Changing the title of an invalid quickfix list
2287 call assert_equal(-1, g:Xsetlist([], ' ',
2288 \ {'title' : 'SomeTitle', 'nr' : 99}))
2289 call assert_equal(-1, g:Xsetlist([], ' ',
2290 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2291
2292 if a:cchar == 'c'
2293 copen
2294 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2295 cclose
2296 endif
2297
2298 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002299 call assert_fails('call g:Xgetlist([])', 'E715:')
2300 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002301 let s = g:Xsetlist([], 'a', {'abc':1})
2302 call assert_equal(-1, s)
2303
2304 call assert_equal({}, g:Xgetlist({'abc':1}))
2305 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2306 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2307
2308 if a:cchar == 'l'
2309 call assert_equal({}, getloclist(99, {'title': 1}))
2310 endif
2311
2312 " Context related tests
2313 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2314 call assert_equal(0, s)
2315 call test_garbagecollect_now()
2316 let d = g:Xgetlist({'context':1})
2317 call assert_equal([1,2,3], d.context)
2318 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2319 let d = g:Xgetlist({'context':1})
2320 call assert_equal({'color':'green'}, d.context)
2321 call g:Xsetlist([], 'a', {'context':"Context info"})
2322 let d = g:Xgetlist({'context':1})
2323 call assert_equal("Context info", d.context)
2324 call g:Xsetlist([], 'a', {'context':246})
2325 let d = g:Xgetlist({'context':1})
2326 call assert_equal(246, d.context)
2327 " set other Vim data types as context
2328 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2329 if has('channel')
2330 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2331 endif
2332 if has('job')
2333 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2334 endif
2335 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2336 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2337 call g:Xsetlist([], 'a', {'context' : ''})
2338 call test_garbagecollect_now()
2339 if a:cchar == 'l'
2340 " Test for copying context across two different location lists
2341 new | only
2342 let w1_id = win_getid()
2343 let l = [1]
2344 call setloclist(0, [], 'a', {'context':l})
2345 new
2346 let w2_id = win_getid()
2347 call add(l, 2)
2348 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2349 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2350 unlet! l
2351 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2352 only
2353 call setloclist(0, [], 'f')
2354 call assert_equal('', getloclist(0, {'context':1}).context)
2355 endif
2356
2357 " Test for changing the context of previous quickfix lists
2358 call g:Xsetlist([], 'f')
2359 Xexpr "One"
2360 Xexpr "Two"
2361 Xexpr "Three"
2362 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2363 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2364 " Also, check for setting the context using quickfix list number zero.
2365 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2366 call test_garbagecollect_now()
2367 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2368 call assert_equal([1], l.context)
2369 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2370 call assert_equal([2], l.context)
2371 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2372 call assert_equal([3], l.context)
2373
2374 " Test for changing the context through reference and for garbage
2375 " collection of quickfix context
2376 let l = ["red"]
2377 call g:Xsetlist([], ' ', {'context' : l})
2378 call add(l, "blue")
2379 let x = g:Xgetlist({'context' : 1})
2380 call add(x.context, "green")
2381 call assert_equal(["red", "blue", "green"], l)
2382 call assert_equal(["red", "blue", "green"], x.context)
2383 unlet l
2384 call test_garbagecollect_now()
2385 let m = g:Xgetlist({'context' : 1})
2386 call assert_equal(["red", "blue", "green"], m.context)
2387
2388 " Test for setting/getting items
2389 Xexpr ""
2390 let qfprev = g:Xgetlist({'nr':0})
2391 let s = g:Xsetlist([], ' ', {'title':'Green',
2392 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2393 call assert_equal(0, s)
2394 let qfcur = g:Xgetlist({'nr':0})
2395 call assert_true(qfcur.nr == qfprev.nr + 1)
2396 let l = g:Xgetlist({'items':1})
2397 call assert_equal('F1', bufname(l.items[0].bufnr))
2398 call assert_equal(10, l.items[0].lnum)
2399 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2400 \ {'filename':'F2', 'lnum':30}]})
2401 let l = g:Xgetlist({'items':1})
2402 call assert_equal('F2', bufname(l.items[2].bufnr))
2403 call assert_equal(30, l.items[2].lnum)
2404 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2405 let l = g:Xgetlist({'items':1})
2406 call assert_equal('F3', bufname(l.items[0].bufnr))
2407 call assert_equal(40, l.items[0].lnum)
2408 call g:Xsetlist([], 'r', {'items' : []})
2409 let l = g:Xgetlist({'items':1})
2410 call assert_equal(0, len(l.items))
2411
2412 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2413 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2414 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2415 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2416
2417 " Test for getting id of window associated with a location list window
2418 if a:cchar == 'l'
2419 only
2420 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2421 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002422 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002423 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2424 wincmd w
2425 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2426 only
2427 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002428
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002429 " The following used to crash Vim with address sanitizer
2430 call g:Xsetlist([], 'f')
2431 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2432 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002433
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002434 " Try setting the items using a string
2435 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002436
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002437 " Save and restore the quickfix stack
2438 call g:Xsetlist([], 'f')
2439 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2440 Xexpr "File1:10:Line1"
2441 Xexpr "File2:20:Line2"
2442 Xexpr "File3:30:Line3"
2443 let last_qf = g:Xgetlist({'nr':'$'}).nr
2444 call assert_equal(3, last_qf)
2445 let qstack = []
2446 for i in range(1, last_qf)
2447 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2448 endfor
2449 call g:Xsetlist([], 'f')
2450 for i in range(len(qstack))
2451 call g:Xsetlist([], ' ', qstack[i])
2452 endfor
2453 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2454 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2455 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2456 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2457 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002458
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002459 " Swap two quickfix lists
2460 Xexpr "File1:10:Line10"
2461 Xexpr "File2:20:Line20"
2462 Xexpr "File3:30:Line30"
2463 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2464 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2465 let l1=g:Xgetlist({'nr':1,'all':1})
2466 let l2=g:Xgetlist({'nr':2,'all':1})
2467 let save_id = l1.id
2468 let l1.id=l2.id
2469 let l2.id=save_id
2470 call g:Xsetlist([], 'r', l1)
2471 call g:Xsetlist([], 'r', l2)
2472 let newl1=g:Xgetlist({'nr':1,'all':1})
2473 let newl2=g:Xgetlist({'nr':2,'all':1})
2474 call assert_equal('Fruits', newl1.title)
2475 call assert_equal(['Fruits'], newl1.context)
2476 call assert_equal('Line20', newl1.items[0].text)
2477 call assert_equal('Colors', newl2.title)
2478 call assert_equal(['Colors'], newl2.context)
2479 call assert_equal('Line10', newl2.items[0].text)
2480 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002481
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002482 " Cannot specify both a non-empty list argument and a dict argument
2483 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002484endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002485
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002486func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002487 call Xproperty_tests('c')
2488 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002489endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002490
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002491" Test for setting the current index in the location/quickfix list
2492func Xtest_setqfidx(cchar)
2493 call s:setup_commands(a:cchar)
2494
2495 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2496 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2497 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2498
2499 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2500 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2501 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2502 Xolder 2
2503 Xopen
2504 call assert_equal(3, line('.'))
2505 Xnewer
2506 call assert_equal(2, line('.'))
2507 Xnewer
2508 call assert_equal(2, line('.'))
2509 " Update the current index with the quickfix window open
2510 wincmd w
2511 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2512 Xopen
2513 call assert_equal(3, line('.'))
2514 Xclose
2515
2516 " Set the current index to the last entry
2517 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2518 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2519 " A large value should set the index to the last index
2520 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2521 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2522 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2523 " Invalid index values
2524 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2525 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2526 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2527 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2528 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2529 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2530 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2531
2532 call g:Xsetlist([], 'f')
2533 new | only
2534endfunc
2535
2536func Test_setqfidx()
2537 call Xtest_setqfidx('c')
2538 call Xtest_setqfidx('l')
2539endfunc
2540
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002541" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002542func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002543 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002544endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002545
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002546func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002547 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2548 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2549
2550 let g:acmds = []
2551 cexpr "F1:10:Line 10"
2552 caddexpr "F1:20:Line 20"
2553 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002554 cexpr ""
2555 caddexpr ""
2556 cgetexpr ""
2557 silent! cexpr non_existing_func()
2558 silent! caddexpr non_existing_func()
2559 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002560 let l = ['precexpr',
2561 \ 'postcexpr',
2562 \ 'precaddexpr',
2563 \ 'postcaddexpr',
2564 \ 'precgetexpr',
2565 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002566 \ 'precexpr',
2567 \ 'postcexpr',
2568 \ 'precaddexpr',
2569 \ 'postcaddexpr',
2570 \ 'precgetexpr',
2571 \ 'postcgetexpr',
2572 \ 'precexpr',
2573 \ 'precaddexpr',
2574 \ 'precgetexpr']
2575 call assert_equal(l, g:acmds)
2576
2577 let g:acmds = []
2578 enew! | call append(0, "F2:10:Line 10")
2579 cbuffer!
2580 enew! | call append(0, "F2:20:Line 20")
2581 cgetbuffer
2582 enew! | call append(0, "F2:30:Line 30")
2583 caddbuffer
2584 new
2585 let bnum = bufnr('%')
2586 bunload
2587 exe 'silent! cbuffer! ' . bnum
2588 exe 'silent! cgetbuffer ' . bnum
2589 exe 'silent! caddbuffer ' . bnum
2590 enew!
2591 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002592 \ 'postcbuffer',
2593 \ 'precgetbuffer',
2594 \ 'postcgetbuffer',
2595 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002596 \ 'postcaddbuffer',
2597 \ 'precbuffer',
2598 \ 'precgetbuffer',
2599 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002600 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002601
2602 call writefile(['Xtest:1:Line1'], 'Xtest')
2603 call writefile([], 'Xempty')
2604 let g:acmds = []
2605 cfile Xtest
2606 caddfile Xtest
2607 cgetfile Xtest
2608 cfile Xempty
2609 caddfile Xempty
2610 cgetfile Xempty
2611 silent! cfile do_not_exist
2612 silent! caddfile do_not_exist
2613 silent! cgetfile do_not_exist
2614 let l = ['precfile',
2615 \ 'postcfile',
2616 \ 'precaddfile',
2617 \ 'postcaddfile',
2618 \ 'precgetfile',
2619 \ 'postcgetfile',
2620 \ 'precfile',
2621 \ 'postcfile',
2622 \ 'precaddfile',
2623 \ 'postcaddfile',
2624 \ 'precgetfile',
2625 \ 'postcgetfile',
2626 \ 'precfile',
2627 \ 'postcfile',
2628 \ 'precaddfile',
2629 \ 'postcaddfile',
2630 \ 'precgetfile',
2631 \ 'postcgetfile']
2632 call assert_equal(l, g:acmds)
2633
2634 let g:acmds = []
2635 helpgrep quickfix
2636 silent! helpgrep non_existing_help_topic
2637 vimgrep test Xtest
2638 vimgrepadd test Xtest
2639 silent! vimgrep non_existing_test Xtest
2640 silent! vimgrepadd non_existing_test Xtest
2641 set makeprg=
2642 silent! make
2643 set makeprg&
2644 let l = ['prehelpgrep',
2645 \ 'posthelpgrep',
2646 \ 'prehelpgrep',
2647 \ 'posthelpgrep',
2648 \ 'previmgrep',
2649 \ 'postvimgrep',
2650 \ 'previmgrepadd',
2651 \ 'postvimgrepadd',
2652 \ 'previmgrep',
2653 \ 'postvimgrep',
2654 \ 'previmgrepadd',
2655 \ 'postvimgrepadd',
2656 \ 'premake',
2657 \ 'postmake']
2658 call assert_equal(l, g:acmds)
2659
2660 if has('unix')
2661 " Run this test only on Unix-like systems. The grepprg may not be set on
2662 " non-Unix systems.
2663 " The following lines are used for the grep test. Don't remove.
2664 " Grep_Autocmd_Text: Match 1
2665 " GrepAdd_Autocmd_Text: Match 2
2666 let g:acmds = []
2667 silent grep Grep_Autocmd_Text test_quickfix.vim
2668 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2669 silent grep abc123def Xtest
2670 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002671 set grepprg=internal
2672 silent grep Grep_Autocmd_Text test_quickfix.vim
2673 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2674 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2675 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2676 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002677 let l = ['pregrep',
2678 \ 'postgrep',
2679 \ 'pregrepadd',
2680 \ 'postgrepadd',
2681 \ 'pregrep',
2682 \ 'postgrep',
2683 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002684 \ 'postgrepadd',
2685 \ 'pregrep',
2686 \ 'postgrep',
2687 \ 'pregrepadd',
2688 \ 'postgrepadd',
2689 \ 'prelgrep',
2690 \ 'postlgrep',
2691 \ 'prelgrepadd',
2692 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002693 call assert_equal(l, g:acmds)
2694 endif
2695
2696 call delete('Xtest')
2697 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002698 au! QuickFixCmdPre
2699 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002700endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002701
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002702func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002703 set efm=%m
2704 lgetexpr '?'
2705
2706 try
2707 call DoesNotExit()
2708 catch
2709 lgetexpr '1'
2710 finally
2711 lgetexpr '1'
2712 endtry
2713
2714 call assert_equal('1', getloclist(0)[0].text)
2715
2716 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002717endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002718
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002719func Test_caddbuffer_wrong()
2720 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002721 let save_efm = &efm
2722 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2723 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2724 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002725 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002726 bwipe!
2727endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002728
2729func Test_caddexpr_wrong()
2730 " This used to cause a memory access in freed memory.
2731 cbuffer
2732 cbuffer
2733 copen
2734 let save_efm = &efm
2735 set efm=%
2736 call assert_fails('caddexpr ""', 'E376:')
2737 let &efm = save_efm
2738endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002739
2740func Test_dirstack_cleanup()
2741 " This used to cause a memory access in freed memory.
2742 let save_efm = &efm
2743 lexpr '0'
2744 lopen
2745 fun X(c)
2746 let save_efm=&efm
2747 set efm=%D%f
2748 if a:c == 'c'
2749 caddexpr '::'
2750 else
2751 laddexpr ':0:0'
2752 endif
2753 let &efm=save_efm
2754 endfun
2755 call X('c')
2756 call X('l')
2757 call setqflist([], 'r')
2758 caddbuffer
2759 let &efm = save_efm
2760endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002761
2762" Tests for jumping to entries from the location list window and quickfix
2763" window
2764func Test_cwindow_jump()
2765 set efm=%f%%%l%%%m
2766 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2767 lopen | only
2768 lfirst
2769 call assert_true(winnr('$') == 2)
2770 call assert_true(winnr() == 1)
2771 " Location list for the new window should be set
2772 call assert_true(getloclist(0)[2].text == 'Line 30')
2773
2774 " Open a scratch buffer
2775 " Open a new window and create a location list
2776 " Open the location list window and close the other window
2777 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002778 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002779 " should not be used.
2780 enew | only
2781 set buftype=nofile
2782 below new
2783 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2784 lopen
2785 2wincmd c
2786 lnext
2787 call assert_true(winnr('$') == 3)
2788 call assert_true(winnr() == 2)
2789
2790 " Open two windows with two different location lists
2791 " Open the location list window and close the previous window
2792 " Jump to an entry in the location list window
2793 " Should open the file in the first window and not set the location list.
2794 enew | only
2795 lgetexpr ["F1%5%Line 5"]
2796 below new
2797 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2798 lopen
2799 2wincmd c
2800 lnext
2801 call assert_true(winnr() == 1)
2802 call assert_true(getloclist(0)[0].text == 'Line 5')
2803
2804 enew | only
2805 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2806 copen
2807 cnext
2808 call assert_true(winnr('$') == 2)
2809 call assert_true(winnr() == 1)
2810
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002811 " open the quickfix buffer in two windows and jump to an entry. Should open
2812 " the file in the first quickfix window.
2813 enew | only
2814 copen
2815 let bnum = bufnr('')
2816 exe 'sbuffer ' . bnum
2817 wincmd b
2818 cfirst
2819 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002820 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002821 enew | only
2822 exe 'sb' bnum
2823 exe 'botright sb' bnum
2824 wincmd t
2825 clast
2826 call assert_equal(2, winnr())
2827 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2828 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2829
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002830 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002831 " window by wrapping around the window list.
2832 enew | only
2833 call setloclist(0, [], 'f')
2834 new | new
2835 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2836 lopen
2837 1close
2838 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2839 lnext
2840 call assert_equal(3, winnr())
2841 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2842
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002843 enew | only
2844 set efm&vim
2845endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002846
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002847func Test_cwindow_highlight()
2848 CheckScreendump
2849
2850 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002851 call setline(1, ['some', 'text', 'with', 'matches'])
2852 write XCwindow
2853 vimgrep e XCwindow
2854 redraw
2855 cwindow 4
2856 END
2857 call writefile(lines, 'XtestCwindow')
2858 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2859 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2860
2861 call term_sendkeys(buf, ":cnext\<CR>")
2862 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2863
2864 " clean up
2865 call StopVimInTerminal(buf)
2866 call delete('XtestCwindow')
2867 call delete('XCwindow')
2868endfunc
2869
Bram Moolenaaree85df32017-03-19 14:19:50 +01002870func XvimgrepTests(cchar)
2871 call s:setup_commands(a:cchar)
2872
2873 call writefile(['Editor:VIM vim',
2874 \ 'Editor:Emacs EmAcS',
2875 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002876 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002877
2878 " Error cases
2879 call assert_fails('Xvimgrep /abc *', 'E682:')
2880
2881 let @/=''
2882 call assert_fails('Xvimgrep // *', 'E35:')
2883
2884 call assert_fails('Xvimgrep abc', 'E683:')
2885 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2886 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2887
2888 Xexpr ""
2889 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002890 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002891 let l = g:Xgetlist()
2892 call assert_equal(2, len(l))
2893 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2894
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002895 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002896 let l = g:Xgetlist()
2897 call assert_equal(2, len(l))
2898 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002899 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002900 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002901 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002902
2903 1Xvimgrep ?Editor? Xtestfile*
2904 let l = g:Xgetlist()
2905 call assert_equal(1, len(l))
2906 call assert_equal('Editor:VIM vim', l[0].text)
2907
2908 edit +3 Xtestfile2
2909 Xvimgrep +\cemacs+j Xtestfile1
2910 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002911 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002912 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2913
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002914 " Test for unloading a buffer after vimgrep searched the buffer
2915 %bwipe
2916 Xvimgrep /Editor/j Xtestfile*
2917 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2918 call assert_equal([], getbufinfo('Xtestfile2'))
2919
Bram Moolenaaree85df32017-03-19 14:19:50 +01002920 call delete('Xtestfile1')
2921 call delete('Xtestfile2')
2922endfunc
2923
2924" Tests for the :vimgrep command
2925func Test_vimgrep()
2926 call XvimgrepTests('c')
2927 call XvimgrepTests('l')
2928endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002929
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002930func Test_vimgrep_wildcards_expanded_once()
2931 new X[id-01] file.txt
2932 call setline(1, 'some text to search for')
2933 vimgrep text %
2934 bwipe!
2935endfunc
2936
Bram Moolenaar1c299432018-10-28 14:36:09 +01002937" Test for incsearch highlighting of the :vimgrep pattern
2938" This test used to cause "E315: ml_get: invalid lnum" errors.
2939func Test_vimgrep_incsearch()
2940 enew
2941 set incsearch
2942 call test_override("char_avail", 1)
2943
2944 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2945 let l = getqflist()
2946 call assert_equal(2, len(l))
2947
2948 call test_override("ALL", 0)
2949 set noincsearch
2950endfunc
2951
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002952" Test vimgrep with the last search pattern not set
2953func Test_vimgrep_with_no_last_search_pat()
2954 let lines =<< trim [SCRIPT]
2955 call assert_fails('vimgrep // *', 'E35:')
2956 call writefile(v:errors, 'Xresult')
2957 qall!
2958 [SCRIPT]
2959 call writefile(lines, 'Xscript')
2960 if RunVim([], [], '--clean -S Xscript')
2961 call assert_equal([], readfile('Xresult'))
2962 endif
2963 call delete('Xscript')
2964 call delete('Xresult')
2965endfunc
2966
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002967" Test vimgrep without swap file
2968func Test_vimgrep_without_swap_file()
2969 let lines =<< trim [SCRIPT]
2970 vimgrep grep test_c*
2971 call writefile(['done'], 'Xresult')
2972 qall!
2973 [SCRIPT]
2974 call writefile(lines, 'Xscript')
2975 if RunVim([], [], '--clean -n -S Xscript Xscript')
2976 call assert_equal(['done'], readfile('Xresult'))
2977 endif
2978 call delete('Xscript')
2979 call delete('Xresult')
2980endfunc
2981
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002982func Test_vimgrep_existing_swapfile()
2983 call writefile(['match apple with apple'], 'Xapple')
2984 call writefile(['swapfile'], '.Xapple.swp')
2985 let g:foundSwap = 0
2986 let g:ignoreSwapExists = 1
2987 augroup grep
2988 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2989 augroup END
2990 vimgrep apple Xapple
2991 call assert_equal(1, g:foundSwap)
2992 call assert_match('.Xapple.swo', swapname(''))
2993
2994 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002995 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002996 augroup grep
2997 au! SwapExists
2998 augroup END
2999 unlet g:ignoreSwapExists
3000endfunc
3001
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003002func XfreeTests(cchar)
3003 call s:setup_commands(a:cchar)
3004
3005 enew | only
3006
3007 " Deleting the quickfix stack should work even When the current list is
3008 " somewhere in the middle of the stack
3009 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3010 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3011 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3012 Xolder
3013 call g:Xsetlist([], 'f')
3014 call assert_equal(0, len(g:Xgetlist()))
3015
3016 " After deleting the stack, adding a new list should create a stack with a
3017 " single list.
3018 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3019 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3020
3021 " Deleting the stack from a quickfix window should update/clear the
3022 " quickfix/location list window.
3023 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3024 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3025 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3026 Xolder
3027 Xwindow
3028 call g:Xsetlist([], 'f')
3029 call assert_equal(2, winnr('$'))
3030 call assert_equal(1, line('$'))
3031 Xclose
3032
3033 " Deleting the stack from a non-quickfix window should update/clear the
3034 " quickfix/location list window.
3035 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3036 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3037 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3038 Xolder
3039 Xwindow
3040 wincmd p
3041 call g:Xsetlist([], 'f')
3042 call assert_equal(0, len(g:Xgetlist()))
3043 wincmd p
3044 call assert_equal(2, winnr('$'))
3045 call assert_equal(1, line('$'))
3046
3047 " After deleting the location list stack, if the location list window is
3048 " opened, then a new location list should be created. So opening the
3049 " location list window again should not create a new window.
3050 if a:cchar == 'l'
3051 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3052 wincmd p
3053 lopen
3054 call assert_equal(2, winnr('$'))
3055 endif
3056 Xclose
3057endfunc
3058
Bram Moolenaar74240d32017-12-10 15:26:15 +01003059" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003060func Test_qf_free()
3061 call XfreeTests('c')
3062 call XfreeTests('l')
3063endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003064
3065" Test for buffer overflow when parsing lines and adding new entries to
3066" the quickfix list.
3067func Test_bufoverflow()
3068 set efm=%f:%l:%m
3069 cgetexpr ['File1:100:' . repeat('x', 1025)]
3070
3071 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3072 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3073
3074 set efm=%DEntering\ directory\ %f,%f:%l:%m
3075 cgetexpr ['Entering directory ' . repeat('a', 1006),
3076 \ 'File1:10:Hello World']
3077 set efm&vim
3078endfunc
3079
Bram Moolenaar875feea2017-06-11 16:07:51 +02003080" Tests for getting the quickfix stack size
3081func XsizeTests(cchar)
3082 call s:setup_commands(a:cchar)
3083
3084 call g:Xsetlist([], 'f')
3085 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003086 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3087 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003088
3089 Xexpr "File1:10:Line1"
3090 Xexpr "File2:20:Line2"
3091 Xexpr "File3:30:Line3"
3092 Xolder | Xolder
3093 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3094 call g:Xsetlist([], 'f')
3095
3096 Xexpr "File1:10:Line1"
3097 Xexpr "File2:20:Line2"
3098 Xexpr "File3:30:Line3"
3099 Xolder | Xolder
3100 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3101 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3102endfunc
3103
3104func Test_Qf_Size()
3105 call XsizeTests('c')
3106 call XsizeTests('l')
3107endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003108
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003109func Test_cclose_from_copen()
3110 augroup QF_Test
3111 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003112 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003113 augroup END
3114 copen
3115 augroup QF_Test
3116 au!
3117 augroup END
3118 augroup! QF_Test
3119endfunc
3120
Bram Moolenaar18141832017-06-25 21:17:25 +02003121func Test_cclose_in_autocmd()
3122 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3123 " event will be triggered.
3124 call test_override('starting', 1)
3125 augroup QF_Test
3126 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003127 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003128 augroup END
3129 copen
3130 augroup QF_Test
3131 au!
3132 augroup END
3133 augroup! QF_Test
3134 call test_override('starting', 0)
3135endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003136
Bram Moolenaar379fb762018-08-30 15:58:28 +02003137" Check that ":file" without an argument is possible even when "curbuf_lock"
3138" is set.
3139func Test_file_from_copen()
3140 " Works without argument.
3141 augroup QF_Test
3142 au!
3143 au FileType qf file
3144 augroup END
3145 copen
3146
3147 augroup QF_Test
3148 au!
3149 augroup END
3150 cclose
3151
3152 " Fails with argument.
3153 augroup QF_Test
3154 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003155 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003156 augroup END
3157 copen
3158 augroup QF_Test
3159 au!
3160 augroup END
3161 cclose
3162
3163 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003164endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003165
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003166func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003167 augroup QF_Test
3168 au!
3169 au FileType qf resize 5
3170 augroup END
3171 try
3172 " This should succeed without any exception. No other buffers are
3173 " involved in the autocmd.
3174 copen
3175 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003176 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003177 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003178 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003179 augroup! QF_Test
3180 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003181endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003182
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003183func Test_vimgrep_with_textlock()
3184 new
3185
3186 " Simple way to execute something with "textwinlock" set.
3187 " Check that vimgrep without jumping can be executed.
3188 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3189 normal ax
3190 let qflist = getqflist()
3191 call assert_true(len(qflist) > 0)
3192 call assert_match('RunTheTest', qflist[0].text)
3193 call setqflist([], 'r')
3194 au! InsertCharPre
3195
3196 " Check that vimgrepadd without jumping can be executed.
3197 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3198 normal ax
3199 let qflist = getqflist()
3200 call assert_true(len(qflist) > 0)
3201 call assert_match('RunTheTest', qflist[0].text)
3202 call setqflist([], 'r')
3203 au! InsertCharPre
3204
3205 " Check that lvimgrep without jumping can be executed.
3206 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3207 normal ax
3208 let qflist = getloclist(0)
3209 call assert_true(len(qflist) > 0)
3210 call assert_match('RunTheTest', qflist[0].text)
3211 call setloclist(0, [], 'r')
3212 au! InsertCharPre
3213
3214 " Check that lvimgrepadd without jumping can be executed.
3215 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3216 normal ax
3217 let qflist = getloclist(0)
3218 call assert_true(len(qflist) > 0)
3219 call assert_match('RunTheTest', qflist[0].text)
3220 call setloclist(0, [], 'r')
3221 au! InsertCharPre
3222
3223 " trying to jump will give an error
3224 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3225 call assert_fails('normal ax', 'E565:')
3226 au! InsertCharPre
3227
3228 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3229 call assert_fails('normal ax', 'E565:')
3230 au! InsertCharPre
3231
3232 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3233 call assert_fails('normal ax', 'E565:')
3234 au! InsertCharPre
3235
3236 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3237 call assert_fails('normal ax', 'E565:')
3238 au! InsertCharPre
3239
3240 bwipe!
3241endfunc
3242
Bram Moolenaara8788f42017-07-19 17:06:20 +02003243" Tests for the quickfix buffer b:changedtick variable
3244func Xchangedtick_tests(cchar)
3245 call s:setup_commands(a:cchar)
3246
3247 new | only
3248
3249 Xexpr "" | Xexpr "" | Xexpr ""
3250
3251 Xopen
3252 Xolder
3253 Xolder
3254 Xaddexpr "F1:10:Line10"
3255 Xaddexpr "F2:20:Line20"
3256 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3257 call g:Xsetlist([], 'f')
3258 call assert_equal(8, getbufvar('%', 'changedtick'))
3259 Xclose
3260endfunc
3261
3262func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003263 call Xchangedtick_tests('c')
3264 call Xchangedtick_tests('l')
3265endfunc
3266
3267" Tests for parsing an expression using setqflist()
3268func Xsetexpr_tests(cchar)
3269 call s:setup_commands(a:cchar)
3270
3271 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003272 call g:Xsetlist([], ' ', {'lines' : t})
3273 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003274
3275 let l = g:Xgetlist()
3276 call assert_equal(3, len(l))
3277 call assert_equal(20, l[1].lnum)
3278 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003279 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003280 let l = g:Xgetlist()
3281 call assert_equal(1, len(l))
3282 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003283 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3284 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003285
3286 call g:Xsetlist([], 'f')
3287 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003288 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3289 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3290 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3291 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003292 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3293 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003294
3295 " Adding entries using a custom efm
3296 set efm&
3297 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3298 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3299 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3300 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3301 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3302 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3303 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3304 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003305endfunc
3306
3307func Test_setexpr()
3308 call Xsetexpr_tests('c')
3309 call Xsetexpr_tests('l')
3310endfunc
3311
3312" Tests for per quickfix/location list directory stack
3313func Xmultidirstack_tests(cchar)
3314 call s:setup_commands(a:cchar)
3315
3316 call g:Xsetlist([], 'f')
3317 Xexpr "" | Xexpr ""
3318
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003319 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3320 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3321 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3322 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003323
3324 let l1 = g:Xgetlist({'nr':1, 'items':1})
3325 let l2 = g:Xgetlist({'nr':2, 'items':1})
3326 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3327 call assert_equal(3, l1.items[1].lnum)
3328 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3329 call assert_equal(5, l2.items[1].lnum)
3330endfunc
3331
3332func Test_multidirstack()
3333 call mkdir('Xone/a', 'p')
3334 call mkdir('Xtwo/a', 'p')
3335 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3336 call writefile(lines, 'Xone/a/one.txt')
3337 call writefile(lines, 'Xtwo/a/two.txt')
3338 let save_efm = &efm
3339 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3340
3341 call Xmultidirstack_tests('c')
3342 call Xmultidirstack_tests('l')
3343
3344 let &efm = save_efm
3345 call delete('Xone', 'rf')
3346 call delete('Xtwo', 'rf')
3347endfunc
3348
3349" Tests for per quickfix/location list file stack
3350func Xmultifilestack_tests(cchar)
3351 call s:setup_commands(a:cchar)
3352
3353 call g:Xsetlist([], 'f')
3354 Xexpr "" | Xexpr ""
3355
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003356 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3357 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3358 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3359 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003360
3361 let l1 = g:Xgetlist({'nr':1, 'items':1})
3362 let l2 = g:Xgetlist({'nr':2, 'items':1})
3363 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3364 call assert_equal(3, l1.items[1].lnum)
3365 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3366 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003367
3368 " Test for start of a new error line in the same line where a previous
3369 " error line ends with a file stack.
3370 let efm_val = 'Error\ l%l\ in\ %f,'
3371 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3372 let l = g:Xgetlist({'lines' : [
3373 \ '(one.txt',
3374 \ 'Error l4 in one.txt',
3375 \ ') (two.txt',
3376 \ 'Error l6 in two.txt',
3377 \ ')',
3378 \ 'Error l8 in one.txt'
3379 \ ], 'efm' : efm_val})
3380 call assert_equal(3, len(l.items))
3381 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3382 call assert_equal(4, l.items[0].lnum)
3383 call assert_equal('one.txt', l.items[0].text)
3384 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3385 call assert_equal(6, l.items[1].lnum)
3386 call assert_equal('two.txt', l.items[1].text)
3387 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3388 call assert_equal(8, l.items[2].lnum)
3389 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003390endfunc
3391
3392func Test_multifilestack()
3393 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3394 call writefile(lines, 'one.txt')
3395 call writefile(lines, 'two.txt')
3396 let save_efm = &efm
3397 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3398
3399 call Xmultifilestack_tests('c')
3400 call Xmultifilestack_tests('l')
3401
3402 let &efm = save_efm
3403 call delete('one.txt')
3404 call delete('two.txt')
3405endfunc
3406
3407" Tests for per buffer 'efm' setting
3408func Test_perbuf_efm()
3409 call writefile(["File1-10-Line10"], 'one.txt')
3410 call writefile(["File2#20#Line20"], 'two.txt')
3411 set efm=%f#%l#%m
3412 new | only
3413 new
3414 setlocal efm=%f-%l-%m
3415 cfile one.txt
3416 wincmd w
3417 caddfile two.txt
3418
3419 let l = getqflist()
3420 call assert_equal(10, l[0].lnum)
3421 call assert_equal('Line20', l[1].text)
3422
3423 set efm&
3424 new | only
3425 call delete('one.txt')
3426 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003427endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003428
3429" Open multiple help windows using ":lhelpgrep
3430" This test used to crash Vim
3431func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003432 new | only
3433 lhelpgrep window
3434 lopen
3435 e#
3436 lhelpgrep buffer
3437 call assert_equal(3, winnr('$'))
3438 call assert_true(len(getloclist(1)) != 0)
3439 call assert_true(len(getloclist(2)) != 0)
3440 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003441endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003442
3443" Tests for adding new quickfix lists using setqflist()
3444func XaddQf_tests(cchar)
3445 call s:setup_commands(a:cchar)
3446
3447 " Create a new list using ' ' for action
3448 call g:Xsetlist([], 'f')
3449 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3450 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3451 call assert_equal(1, l.nr)
3452 call assert_equal('Test1', l.title)
3453
3454 " Create a new list using ' ' for action and '$' for 'nr'
3455 call g:Xsetlist([], 'f')
3456 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3457 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3458 call assert_equal(1, l.nr)
3459 call assert_equal('Test2', l.title)
3460
3461 " Create a new list using 'a' for action
3462 call g:Xsetlist([], 'f')
3463 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3464 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3465 call assert_equal(1, l.nr)
3466 call assert_equal('Test3', l.title)
3467
3468 " Create a new list using 'a' for action and '$' for 'nr'
3469 call g:Xsetlist([], 'f')
3470 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3471 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3472 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3473 call assert_equal(1, l.nr)
3474 call assert_equal('Test4', l.title)
3475
3476 " Adding a quickfix list should remove all the lists following the current
3477 " list.
3478 Xexpr "" | Xexpr "" | Xexpr ""
3479 silent! 10Xolder
3480 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3481 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3482 call assert_equal(2, l.nr)
3483 call assert_equal('Test5', l.title)
3484
3485 " Add a quickfix list using '$' as the list number.
3486 let lastqf = g:Xgetlist({'nr':'$'}).nr
3487 silent! 99Xolder
3488 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3489 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3490 call assert_equal(lastqf + 1, l.nr)
3491 call assert_equal('Test6', l.title)
3492
3493 " Add a quickfix list using 'nr' set to one more than the quickfix
3494 " list size.
3495 let lastqf = g:Xgetlist({'nr':'$'}).nr
3496 silent! 99Xolder
3497 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3498 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3499 call assert_equal(lastqf + 1, l.nr)
3500 call assert_equal('Test7', l.title)
3501
3502 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3503 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3504 silent! 99Xolder
3505 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3506 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3507 call assert_equal(10, l.nr)
3508 call assert_equal('Test8', l.title)
3509
3510 " Add a quickfix list using 'nr' set to a value greater than 10
3511 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3512
3513 " Try adding a quickfix list with 'nr' set to a value greater than the
3514 " quickfix list size but less than 10.
3515 call g:Xsetlist([], 'f')
3516 Xexpr "" | Xexpr "" | Xexpr ""
3517 silent! 99Xolder
3518 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3519
3520 " Add a quickfix list using 'nr' set to a some string or list
3521 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3522endfunc
3523
3524func Test_add_qf()
3525 call XaddQf_tests('c')
3526 call XaddQf_tests('l')
3527endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003528
3529" Test for getting the quickfix list items from some text without modifying
3530" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003531func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003532 call s:setup_commands(a:cchar)
3533 call g:Xsetlist([], 'f')
3534
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003535 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003536 call assert_equal(2, len(l))
3537 call assert_equal(30, l[1].lnum)
3538
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003539 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3540 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3541 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3542 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003543
Bram Moolenaar36538222017-09-02 19:51:44 +02003544 " Parse text using a custom efm
3545 set efm&
3546 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3547 call assert_equal('Line30', l[0].text)
3548 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3549 call assert_equal('File3:30:Line30', l[0].text)
3550 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3551 call assert_equal({}, l)
3552 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3553 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3554
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003555 " Make sure that the quickfix stack is not modified
3556 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3557endfunc
3558
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003559func Test_get_list_from_lines()
3560 call XgetListFromLines('c')
3561 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003562endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003563
3564" Tests for the quickfix list id
3565func Xqfid_tests(cchar)
3566 call s:setup_commands(a:cchar)
3567
3568 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003569 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003570 Xexpr ''
3571 let start_id = g:Xgetlist({'id' : 0}).id
3572 Xexpr '' | Xexpr ''
3573 Xolder
3574 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3575 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3576 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003577 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003578 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003579 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3580 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003581
3582 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3583 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003584 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003585 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3586 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3587 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3588
3589 let qfid = g:Xgetlist({'id':0, 'nr':0})
3590 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003591 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003592endfunc
3593
3594func Test_qf_id()
3595 call Xqfid_tests('c')
3596 call Xqfid_tests('l')
3597endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003598
3599func Xqfjump_tests(cchar)
3600 call s:setup_commands(a:cchar)
3601
3602 call writefile(["Line1\tFoo", "Line2"], 'F1')
3603 call writefile(["Line1\tBar", "Line2"], 'F2')
3604 call writefile(["Line1\tBaz", "Line2"], 'F3')
3605
3606 call g:Xsetlist([], 'f')
3607
3608 " Tests for
3609 " Jumping to a line using a pattern
3610 " Jumping to a column greater than the last column in a line
3611 " Jumping to a line greater than the last line in the file
3612 let l = []
3613 for i in range(1, 7)
3614 call add(l, {})
3615 endfor
3616 let l[0].filename='F1'
3617 let l[0].pattern='Line1'
3618 let l[1].filename='F2'
3619 let l[1].pattern='Line1'
3620 let l[2].filename='F3'
3621 let l[2].pattern='Line1'
3622 let l[3].filename='F3'
3623 let l[3].lnum=1
3624 let l[3].col=9
3625 let l[3].vcol=1
3626 let l[4].filename='F3'
3627 let l[4].lnum=99
3628 let l[5].filename='F3'
3629 let l[5].lnum=1
3630 let l[5].col=99
3631 let l[5].vcol=1
3632 let l[6].filename='F3'
3633 let l[6].pattern='abcxyz'
3634
3635 call g:Xsetlist([], ' ', {'items' : l})
3636 Xopen | only
3637 2Xnext
3638 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003639 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003640 Xnext
3641 call assert_equal(7, col('.'))
3642 Xnext
3643 call assert_equal(2, line('.'))
3644 Xnext
3645 call assert_equal(9, col('.'))
3646 2
3647 Xnext
3648 call assert_equal(2, line('.'))
3649
3650 if a:cchar == 'l'
3651 " When jumping to a location list entry in the location list window and
3652 " no usable windows are available, then a new window should be opened.
3653 enew! | new | only
3654 call g:Xsetlist([], 'f')
3655 setlocal buftype=nofile
3656 new
3657 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']})
3658 Xopen
3659 let winid = win_getid()
3660 wincmd p
3661 close
3662 call win_gotoid(winid)
3663 Xnext
3664 call assert_equal(3, winnr('$'))
3665 call assert_equal(1, winnr())
3666 call assert_equal(2, line('.'))
3667
3668 " When jumping to an entry in the location list window and the window
3669 " associated with the location list is not present and a window containing
3670 " the file is already present, then that window should be used.
3671 close
3672 belowright new
3673 call g:Xsetlist([], 'f')
3674 edit F3
3675 call win_gotoid(winid)
3676 Xlast
3677 call assert_equal(3, winnr())
3678 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3679 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3680 endif
3681
3682 " Cleanup
3683 enew!
3684 new | only
3685
3686 call delete('F1')
3687 call delete('F2')
3688 call delete('F3')
3689endfunc
3690
3691func Test_qfjump()
3692 call Xqfjump_tests('c')
3693 call Xqfjump_tests('l')
3694endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003695
3696" Tests for the getqflist() and getloclist() functions when the list is not
3697" present or is empty
3698func Xgetlist_empty_tests(cchar)
3699 call s:setup_commands(a:cchar)
3700
3701 " Empty quickfix stack
3702 call g:Xsetlist([], 'f')
3703 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3704 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3705 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3706 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3707 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3708 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3709 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3710 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003711 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003712 if a:cchar == 'c'
3713 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003714 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003715 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3716 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003717 else
3718 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3719 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003720 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003721 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003722 \ g:Xgetlist({'all' : 0}))
3723 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003724
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003725 " Quickfix window with empty stack
3726 silent! Xopen
3727 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003728 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003729 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3730 Xclose
3731
Bram Moolenaara6d48492017-12-12 22:45:31 +01003732 " Empty quickfix list
3733 Xexpr ""
3734 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3735 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3736 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3737 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3738 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3739 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3740 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3741 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003742 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003743
3744 let qfid = g:Xgetlist({'id' : 0}).id
3745 call g:Xsetlist([], 'f')
3746
3747 " Non-existing quickfix identifier
3748 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3749 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3750 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3751 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3752 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3753 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3754 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3755 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003756 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003757 if a:cchar == 'c'
3758 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3759 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003760 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003761 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3762 else
3763 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3764 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003765 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3766 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003767 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3768 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003769
3770 " Non-existing quickfix list number
3771 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3772 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3773 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3774 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3775 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3776 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3777 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3778 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003779 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003780 if a:cchar == 'c'
3781 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3782 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003783 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3784 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003785 else
3786 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3787 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003788 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3789 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003790 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003791endfunc
3792
3793func Test_getqflist()
3794 call Xgetlist_empty_tests('c')
3795 call Xgetlist_empty_tests('l')
3796endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003797
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003798func Test_getqflist_invalid_nr()
3799 " The following commands used to crash Vim
3800 cexpr ""
3801 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3802
3803 " Cleanup
3804 call setqflist([], 'r')
3805endfunc
3806
Bram Moolenaarb254af32017-12-18 19:48:58 +01003807" Tests for the quickfix/location list changedtick
3808func Xqftick_tests(cchar)
3809 call s:setup_commands(a:cchar)
3810
3811 call g:Xsetlist([], 'f')
3812
3813 Xexpr "F1:10:Line10"
3814 let qfid = g:Xgetlist({'id' : 0}).id
3815 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3816 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3817 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3818 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3819 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3820 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3821 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3822 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3823 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3824
3825 enew!
3826 call append(0, ["F5:50:L50", "F6:60:L60"])
3827 Xaddbuffer
3828 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3829 enew!
3830
3831 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3832 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3833 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3834 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3835 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3836 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3837 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3838 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3839 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3840 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3841 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3842
3843 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3844 Xfile Xone
3845 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3846 Xaddfile Xone
3847 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3848
3849 " Test case for updating a non-current quickfix list
3850 call g:Xsetlist([], 'f')
3851 Xexpr "F1:1:L1"
3852 Xexpr "F2:2:L2"
3853 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3854 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3855 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3856
3857 call delete("Xone")
3858endfunc
3859
3860func Test_qf_tick()
3861 call Xqftick_tests('c')
3862 call Xqftick_tests('l')
3863endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003864
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003865" Test helpgrep with lang specifier
3866func Xtest_helpgrep_with_lang_specifier(cchar)
3867 call s:setup_commands(a:cchar)
3868 Xhelpgrep Vim@en
3869 call assert_equal('help', &filetype)
3870 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3871 new | only
3872endfunc
3873
3874func Test_helpgrep_with_lang_specifier()
3875 call Xtest_helpgrep_with_lang_specifier('c')
3876 call Xtest_helpgrep_with_lang_specifier('l')
3877endfunc
3878
Bram Moolenaar12237442017-12-19 12:38:52 +01003879" The following test used to crash Vim.
3880" Open the location list window and close the regular window associated with
3881" the location list. When the garbage collection runs now, it incorrectly
3882" marks the location list context as not in use and frees the context.
3883func Test_ll_window_ctx()
3884 call setloclist(0, [], 'f')
3885 call setloclist(0, [], 'a', {'context' : []})
3886 lopen | only
3887 call test_garbagecollect_now()
3888 echo getloclist(0, {'context' : 1}).context
3889 enew | only
3890endfunc
3891
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003892" The following test used to crash vim
3893func Test_lfile_crash()
3894 sp Xtest
3895 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003896 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003897 au! QuickFixCmdPre
3898endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003899
3900" The following test used to crash vim
3901func Test_lbuffer_crash()
3902 sv Xtest
3903 augroup QF_Test
3904 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003905 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003906 augroup END
3907 lbuffer
3908 augroup QF_Test
3909 au!
3910 augroup END
3911endfunc
3912
3913" The following test used to crash vim
3914func Test_lexpr_crash()
3915 augroup QF_Test
3916 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003917 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003918 augroup END
3919 lexpr ""
3920 augroup QF_Test
3921 au!
3922 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003923
Bram Moolenaar3c097222017-12-21 20:54:49 +01003924 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003925 augroup QF_Test
3926 au!
3927 au BufNew * call setloclist(0, [], 'f')
3928 augroup END
3929 lexpr 'x:1:x'
3930 augroup QF_Test
3931 au!
3932 augroup END
3933
3934 enew | only
3935 lexpr ''
3936 lopen
3937 augroup QF_Test
3938 au!
3939 au FileType * call setloclist(0, [], 'f')
3940 augroup END
3941 lexpr ''
3942 augroup QF_Test
3943 au!
3944 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003945endfunc
3946
3947" The following test used to crash Vim
3948func Test_lvimgrep_crash()
3949 sv Xtest
3950 augroup QF_Test
3951 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003952 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003953 augroup END
3954 lvimgrep quickfix test_quickfix.vim
3955 augroup QF_Test
3956 au!
3957 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003958
3959 new | only
3960 augroup QF_Test
3961 au!
3962 au BufEnter * call setloclist(0, [], 'r')
3963 augroup END
3964 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3965 augroup QF_Test
3966 au!
3967 augroup END
3968
Bram Moolenaar3c097222017-12-21 20:54:49 +01003969 enew | only
3970endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003971
Bram Moolenaar2573af32020-03-14 17:21:34 +01003972func Test_lvimgrep_crash2()
3973 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003974 call assert_fails('lvimgrep x x', 'E471:')
3975 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003976
3977 au! BufNewFile
3978endfunc
3979
Bram Moolenaarde046542017-12-26 13:53:11 +01003980" Test for the position of the quickfix and location list window
3981func Test_qfwin_pos()
3982 " Open two windows
3983 new | only
3984 new
3985 cexpr ['F1:10:L10']
3986 copen
3987 " Quickfix window should be the bottom most window
3988 call assert_equal(3, winnr())
3989 close
3990 " Open at the very top
3991 wincmd t
3992 topleft copen
3993 call assert_equal(1, winnr())
3994 close
3995 " open left of the current window
3996 wincmd t
3997 below new
3998 leftabove copen
3999 call assert_equal(2, winnr())
4000 close
4001 " open right of the current window
4002 rightbelow copen
4003 call assert_equal(3, winnr())
4004 close
4005endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004006
4007" Tests for quickfix/location lists changed by autocommands when
4008" :vimgrep/:lvimgrep commands are running.
4009func Test_vimgrep_autocmd()
4010 call setqflist([], 'f')
4011 call writefile(['stars'], 'Xtest1.txt')
4012 call writefile(['stars'], 'Xtest2.txt')
4013
4014 " Test 1:
4015 " When searching for a pattern using :vimgrep, if the quickfix list is
4016 " changed by an autocmd, the results should be added to the correct quickfix
4017 " list.
4018 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4019 silent vimgrep stars Xtest*.txt
4020 call assert_equal(1, getqflist({'nr' : 0}).nr)
4021 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4022 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4023 au! BufRead Xtest2.txt
4024
4025 " Test 2:
4026 " When searching for a pattern using :vimgrep, if the quickfix list is
4027 " freed, then a error should be given.
4028 silent! %bwipe!
4029 call setqflist([], 'f')
4030 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4031 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4032 au! BufRead Xtest2.txt
4033
4034 " Test 3:
4035 " When searching for a pattern using :lvimgrep, if the location list is
4036 " freed, then the command should error out.
4037 silent! %bwipe!
4038 let g:save_winid = win_getid()
4039 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4040 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4041 au! BufRead Xtest2.txt
4042
4043 call delete('Xtest1.txt')
4044 call delete('Xtest2.txt')
4045 call setqflist([], 'f')
4046endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004047
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004048" Test for an autocmd changing the current directory when running vimgrep
4049func Xvimgrep_autocmd_cd(cchar)
4050 call s:setup_commands(a:cchar)
4051
4052 %bwipe
4053 let save_cwd = getcwd()
4054
4055 augroup QF_Test
4056 au!
4057 autocmd BufRead * silent cd %:p:h
4058 augroup END
4059
4060 10Xvimgrep /vim/ Xdir/**
4061 let l = g:Xgetlist()
4062 call assert_equal('f1.txt', bufname(l[0].bufnr))
4063 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4064
4065 augroup QF_Test
4066 au!
4067 augroup END
4068
4069 exe 'cd ' . save_cwd
4070endfunc
4071
4072func Test_vimgrep_autocmd_cd()
4073 call mkdir('Xdir/a', 'p')
4074 call mkdir('Xdir/b', 'p')
4075 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4076 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4077 call Xvimgrep_autocmd_cd('c')
4078 call Xvimgrep_autocmd_cd('l')
4079 %bwipe
4080 call delete('Xdir', 'rf')
4081endfunc
4082
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004083" The following test used to crash Vim
4084func Test_lhelpgrep_autocmd()
4085 lhelpgrep quickfix
4086 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4087 lhelpgrep buffer
4088 call assert_equal('help', &filetype)
4089 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4090 lhelpgrep tabpage
4091 call assert_equal('help', &filetype)
4092 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4093 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004094
4095 new | only
4096 augroup QF_Test
4097 au!
4098 au BufEnter * call setqflist([], 'f')
4099 augroup END
4100 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004101 " run the test with a help window already open
4102 help
4103 wincmd w
4104 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004105 augroup QF_Test
4106 au! BufEnter
4107 augroup END
4108
4109 new | only
4110 augroup QF_Test
4111 au!
4112 au BufEnter * call setqflist([], 'r')
4113 augroup END
4114 call assert_fails('helpgrep quickfix', 'E925:')
4115 augroup QF_Test
4116 au! BufEnter
4117 augroup END
4118
4119 new | only
4120 augroup QF_Test
4121 au!
4122 au BufEnter * call setloclist(0, [], 'r')
4123 augroup END
4124 call assert_fails('lhelpgrep quickfix', 'E926:')
4125 augroup QF_Test
4126 au! BufEnter
4127 augroup END
4128
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004129 new | only
4130endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004131
4132" Test for shortening/simplifying the file name when opening the
4133" quickfix window or when displaying the quickfix list
4134func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004135 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004136 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004137 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004138 let fname = getcwd() . '/test_quickfix.vim'
4139 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4140 call assert_equal(fname, bufname('test_quickfix.vim'))
4141 " Opening the quickfix window should simplify the file path
4142 cwindow
4143 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4144 cclose
4145 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004146 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004147 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4148 call assert_equal(fname, bufname('test_quickfix.vim'))
4149 " Displaying the quickfix list should simplify the file path
4150 silent! clist
4151 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004152 " Add a few entries for the same file with different paths and check whether
4153 " the buffer name is shortened
4154 %bwipe
4155 call setqflist([], 'f')
4156 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4157 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4158 \ {'filename' : fname, 'lnum' : 30}], ' ')
4159 copen
4160 call assert_equal(['test_quickfix.vim|10| ',
4161 \ 'test_quickfix.vim|20| ',
4162 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4163 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004164endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004165
4166" Quickfix title tests
4167" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4168" Otherwise due to indentation, the title is set with spaces at the beginning
4169" of the command.
4170func Test_qftitle()
4171 call writefile(["F1:1:Line1"], 'Xerr')
4172
4173 " :cexpr
4174 exe "cexpr readfile('Xerr')"
4175 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4176
4177 " :cgetexpr
4178 exe "cgetexpr readfile('Xerr')"
4179 call assert_equal(":cgetexpr readfile('Xerr')",
4180 \ getqflist({'title' : 1}).title)
4181
4182 " :caddexpr
4183 call setqflist([], 'f')
4184 exe "caddexpr readfile('Xerr')"
4185 call assert_equal(":caddexpr readfile('Xerr')",
4186 \ getqflist({'title' : 1}).title)
4187
4188 " :cbuffer
4189 new Xerr
4190 exe "cbuffer"
4191 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4192
4193 " :cgetbuffer
4194 edit Xerr
4195 exe "cgetbuffer"
4196 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4197
4198 " :caddbuffer
4199 call setqflist([], 'f')
4200 edit Xerr
4201 exe "caddbuffer"
4202 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4203
4204 " :cfile
4205 exe "cfile Xerr"
4206 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4207
4208 " :cgetfile
4209 exe "cgetfile Xerr"
4210 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4211
4212 " :caddfile
4213 call setqflist([], 'f')
4214 exe "caddfile Xerr"
4215 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4216
4217 " :grep
4218 set grepprg=internal
4219 exe "grep F1 Xerr"
4220 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4221
4222 " :grepadd
4223 call setqflist([], 'f')
4224 exe "grepadd F1 Xerr"
4225 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4226 set grepprg&vim
4227
4228 " :vimgrep
4229 exe "vimgrep F1 Xerr"
4230 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4231
4232 " :vimgrepadd
4233 call setqflist([], 'f')
4234 exe "vimgrepadd F1 Xerr"
4235 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4236
4237 call setqflist(['F1:10:L10'], ' ')
4238 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4239
4240 call setqflist([], 'f')
4241 call setqflist(['F1:10:L10'], 'a')
4242 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4243
4244 call setqflist([], 'f')
4245 call setqflist(['F1:10:L10'], 'r')
4246 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4247
4248 close
4249 call delete('Xerr')
4250
4251 call setqflist([], ' ', {'title' : 'Errors'})
4252 copen
4253 call assert_equal('Errors', w:quickfix_title)
4254 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4255 call assert_equal('Errors', w:quickfix_title)
4256 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004257
4258 " Switching to another quickfix list in one tab page should update the
4259 " quickfix window title and statusline in all the other tab pages also
4260 call setqflist([], 'f')
4261 %bw!
4262 cgetexpr ['file_one:1:1: error in the first quickfix list']
4263 call setqflist([], 'a', {'title': 'first quickfix list'})
4264 cgetexpr ['file_two:2:1: error in the second quickfix list']
4265 call setqflist([], 'a', {'title': 'second quickfix list'})
4266 copen
4267 wincmd t
4268 tabnew two
4269 copen
4270 wincmd t
4271 colder
4272 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4273 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4274 call assert_equal(1, tabpagewinnr(1))
4275 call assert_equal(1, tabpagewinnr(2))
4276 tabnew
4277 call setqflist([], 'a', {'title': 'new quickfix title'})
4278 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4279 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4280 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004281endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004282
4283func Test_lbuffer_with_bwipe()
4284 new
4285 new
4286 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004287 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004288 augroup END
4289 lbuffer
4290 augroup nasty
4291 au!
4292 augroup END
4293endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004294
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004295" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4296" running
4297func Xexpr_acmd_freelist(cchar)
4298 call s:setup_commands(a:cchar)
4299
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004300 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004301 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004302 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004303 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004304 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004305 augroup nasty
4306 au!
4307 augroup END
4308endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004309
4310func Test_cexpr_acmd_freelist()
4311 call Xexpr_acmd_freelist('c')
4312 call Xexpr_acmd_freelist('l')
4313endfunc
4314
4315" Test for commands that create a new quickfix/location list and jump to the
4316" first error automatically.
4317func Xjumpto_first_error_test(cchar)
4318 call s:setup_commands(a:cchar)
4319
4320 call s:create_test_file('Xtestfile1')
4321 call s:create_test_file('Xtestfile2')
4322 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4323
4324 " Test for cexpr/lexpr
4325 enew
4326 Xexpr l
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 cfile/lfile
4331 enew
4332 call writefile(l, 'Xerr')
4333 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004334 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004335 call assert_equal(2, line('.'))
4336
4337 " Test for cbuffer/lbuffer
4338 edit Xerr
4339 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004340 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004341 call assert_equal(2, line('.'))
4342
4343 call delete('Xerr')
4344 call delete('Xtestfile1')
4345 call delete('Xtestfile2')
4346endfunc
4347
4348func Test_jumpto_first_error()
4349 call Xjumpto_first_error_test('c')
4350 call Xjumpto_first_error_test('l')
4351endfunc
4352
4353" Test for a quickfix autocmd changing the quickfix/location list before
4354" jumping to the first error in the new list.
4355func Xautocmd_changelist(cchar)
4356 call s:setup_commands(a:cchar)
4357
4358 " Test for cfile/lfile
4359 call s:create_test_file('Xtestfile1')
4360 call s:create_test_file('Xtestfile2')
4361 Xexpr 'Xtestfile1:2:Line2'
4362 autocmd QuickFixCmdPost * Xolder
4363 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4364 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004365 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004366 call assert_equal(4, line('.'))
4367 autocmd! QuickFixCmdPost
4368
4369 " Test for cbuffer/lbuffer
4370 call g:Xsetlist([], 'f')
4371 Xexpr 'Xtestfile1:2:Line2'
4372 autocmd QuickFixCmdPost * Xolder
4373 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4374 edit Xerr
4375 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004376 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004377 call assert_equal(4, line('.'))
4378 autocmd! QuickFixCmdPost
4379
4380 " Test for cexpr/lexpr
4381 call g:Xsetlist([], 'f')
4382 Xexpr 'Xtestfile1:2:Line2'
4383 autocmd QuickFixCmdPost * Xolder
4384 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004385 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004386 call assert_equal(4, line('.'))
4387 autocmd! QuickFixCmdPost
4388
Bram Moolenaar851332e2018-07-03 19:16:00 +02004389 " The grepprg may not be set on non-Unix systems
4390 if has('unix')
4391 " Test for grep/lgrep
4392 call g:Xsetlist([], 'f')
4393 Xexpr 'Xtestfile1:2:Line2'
4394 autocmd QuickFixCmdPost * Xolder
4395 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004396 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004397 call assert_equal(5, line('.'))
4398 autocmd! QuickFixCmdPost
4399 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004400
4401 " Test for vimgrep/lvimgrep
4402 call g:Xsetlist([], 'f')
4403 Xexpr 'Xtestfile1:2:Line2'
4404 autocmd QuickFixCmdPost * Xolder
4405 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004406 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004407 call assert_equal(5, line('.'))
4408 autocmd! QuickFixCmdPost
4409
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004410 " Test for autocommands clearing the quickfix list before jumping to the
4411 " first error. This should not result in an error
4412 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4413 let v:errmsg = ''
4414 " Test for cfile/lfile
4415 Xfile Xerr
4416 call assert_true(v:errmsg !~# 'E42:')
4417 " Test for cbuffer/lbuffer
4418 edit Xerr
4419 Xbuffer
4420 call assert_true(v:errmsg !~# 'E42:')
4421 " Test for cexpr/lexpr
4422 Xexpr 'Xtestfile2:4:Line4'
4423 call assert_true(v:errmsg !~# 'E42:')
4424 " Test for grep/lgrep
4425 " The grepprg may not be set on non-Unix systems
4426 if has('unix')
4427 silent Xgrep Line5 Xtestfile2
4428 call assert_true(v:errmsg !~# 'E42:')
4429 endif
4430 " Test for vimgrep/lvimgrep
4431 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4432 autocmd! QuickFixCmdPost
4433
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004434 call delete('Xerr')
4435 call delete('Xtestfile1')
4436 call delete('Xtestfile2')
4437endfunc
4438
4439func Test_autocmd_changelist()
4440 call Xautocmd_changelist('c')
4441 call Xautocmd_changelist('l')
4442endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004443
4444" Tests for the ':filter /pat/ clist' command
4445func Test_filter_clist()
4446 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4447 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4448 \ split(execute('filter /Line 15/ clist'), "\n"))
4449 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4450 \ split(execute('filter /Xfile1/ clist'), "\n"))
4451 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4452
4453 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4454 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4455 call assert_equal([' 2 pqr:pat2: '],
4456 \ split(execute('filter /pqr/ clist'), "\n"))
4457 call assert_equal([' 1 abc:pat1: '],
4458 \ split(execute('filter /pat1/ clist'), "\n"))
4459endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004460
4461" Tests for the "CTRL-W <CR>" command.
4462func Xview_result_split_tests(cchar)
4463 call s:setup_commands(a:cchar)
4464
4465 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4466 call g:Xsetlist([])
4467 Xopen
4468 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004469 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004470 call assert_equal(l:win_count, winnr('$'))
4471 Xclose
4472endfunc
4473
4474func Test_view_result_split()
4475 call Xview_result_split_tests('c')
4476 call Xview_result_split_tests('l')
4477endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004478
4479" Test that :cc sets curswant
4480func Test_curswant()
4481 helpgrep quickfix
4482 normal! llll
4483 1cc
4484 call assert_equal(getcurpos()[4], virtcol('.'))
4485 cclose | helpclose
4486endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004487
4488" Test for opening a file from the quickfix window using CTRL-W <Enter>
4489" doesn't leave an empty buffer around.
4490func Test_splitview()
4491 call s:create_test_file('Xtestfile1')
4492 call s:create_test_file('Xtestfile2')
4493 new | only
4494 let last_bufnr = bufnr('Test_sv_1', 1)
4495 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4496 cgetexpr l
4497 copen
4498 let numbufs = len(getbufinfo())
4499 exe "normal \<C-W>\<CR>"
4500 copen
4501 exe "normal j\<C-W>\<CR>"
4502 " Make sure new empty buffers are not created
4503 call assert_equal(numbufs, len(getbufinfo()))
4504 " Creating a new buffer should use the next available buffer number
4505 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4506 bwipe Test_sv_1
4507 bwipe Test_sv_2
4508 new | only
4509
4510 " When split opening files from location list window, make sure that two
4511 " windows doesn't refer to the same location list
4512 lgetexpr l
4513 let locid = getloclist(0, {'id' : 0}).id
4514 lopen
4515 exe "normal \<C-W>\<CR>"
4516 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4517 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4518 new | only
4519
4520 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004521 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004522 lhelpgrep window
4523 let locid = getloclist(0, {'id' : 0}).id
4524 lwindow
4525 exe "normal j\<C-W>\<CR>"
4526 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4527 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4528 new | only
4529
Bram Moolenaar406cd902020-02-18 21:54:41 +01004530 " Using :split or :vsplit from a quickfix window should behave like a :new
4531 " or a :vnew command
4532 copen
4533 split
4534 call assert_equal(3, winnr('$'))
4535 let l = getwininfo()
4536 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4537 close
4538 copen
4539 vsplit
4540 let l = getwininfo()
4541 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4542 new | only
4543
Bram Moolenaarb2443732018-11-11 22:50:27 +01004544 call delete('Xtestfile1')
4545 call delete('Xtestfile2')
4546endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004547
4548" Test for parsing entries using visual screen column
4549func Test_viscol()
4550 enew
4551 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4552 edit Xfile1
4553
4554 " Use byte offset for column number
4555 set efm&
4556 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4557 call assert_equal([5, 8], [col('.'), virtcol('.')])
4558 cnext
4559 call assert_equal([9, 12], [col('.'), virtcol('.')])
4560 cnext
4561 call assert_equal([14, 20], [col('.'), virtcol('.')])
4562
4563 " Use screen column offset for column number
4564 set efm=%f:%l:%v:%m
4565 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4566 call assert_equal([5, 8], [col('.'), virtcol('.')])
4567 cnext
4568 call assert_equal([9, 12], [col('.'), virtcol('.')])
4569 cnext
4570 call assert_equal([14, 20], [col('.'), virtcol('.')])
4571 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4572 call assert_equal([5, 8], [col('.'), virtcol('.')])
4573 cnext
4574 call assert_equal([10, 16], [col('.'), virtcol('.')])
4575 cnext
4576 call assert_equal([14, 20], [col('.'), virtcol('.')])
4577
4578 enew
4579 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4580
4581 " Use byte offset for column number
4582 set efm&
4583 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4584 call assert_equal([8, 10], [col('.'), virtcol('.')])
4585 cnext
4586 call assert_equal([11, 17], [col('.'), virtcol('.')])
4587 cnext
4588 call assert_equal([16, 25], [col('.'), virtcol('.')])
4589
4590 " Use screen column offset for column number
4591 set efm=%f:%l:%v:%m
4592 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4593 call assert_equal([8, 10], [col('.'), virtcol('.')])
4594 cnext
4595 call assert_equal([11, 17], [col('.'), virtcol('.')])
4596 cnext
4597 call assert_equal([16, 25], [col('.'), virtcol('.')])
4598
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004599 " Use screen column number with a multi-line error message
4600 enew
4601 call writefile(["à test"], 'Xfile1')
4602 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4603 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4604 call assert_equal('Xfile1', @%)
4605 call assert_equal([0, 1, 4, 0], getpos('.'))
4606
4607 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4608 " does not break this
4609 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4610 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4611 call assert_equal('Xfile1', @%)
4612 call assert_equal([0, 1, 3, 0], getpos('.'))
4613
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004614 enew | only
4615 set efm&
4616 call delete('Xfile1')
4617endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004618
4619" Test for the quickfix window buffer
4620func Xqfbuf_test(cchar)
4621 call s:setup_commands(a:cchar)
4622
4623 " Quickfix buffer should be reused across closing and opening a quickfix
4624 " window
4625 Xexpr "F1:10:Line10"
4626 Xopen
4627 let qfbnum = bufnr('')
4628 Xclose
4629 " Even after the quickfix window is closed, the buffer should be loaded
4630 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004631 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004632 Xopen
4633 " Buffer should be reused when opening the window again
4634 call assert_equal(qfbnum, bufnr(''))
4635 Xclose
4636
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004637 " When quickfix buffer is wiped out, getqflist() should return 0
4638 %bw!
4639 Xexpr ""
4640 Xopen
4641 bw!
4642 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4643
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004644 if a:cchar == 'l'
4645 %bwipe
4646 " For a location list, when both the file window and the location list
4647 " window for the list are closed, then the buffer should be freed.
4648 new | only
4649 lexpr "F1:10:Line10"
4650 let wid = win_getid()
4651 lopen
4652 let qfbnum = bufnr('')
4653 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4654 close
4655 " When the location list window is closed, the buffer name should not
4656 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004657 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004658 call assert_true(bufloaded(qfbnum))
4659
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004660 " After deleting a location list buffer using ":bdelete", opening the
4661 " location list window should mark the buffer as a location list buffer.
4662 exe "bdelete " . qfbnum
4663 lopen
4664 call assert_equal("quickfix", &buftype)
4665 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4666 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4667 call assert_false(&swapfile)
4668 lclose
4669
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004670 " When the location list is cleared for the window, the buffer should be
4671 " removed
4672 call setloclist(0, [], 'f')
4673 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004674 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004675
4676 " When the location list is freed with the location list window open, the
4677 " location list buffer should not be lost. It should be reused when the
4678 " location list is again populated.
4679 lexpr "F1:10:Line10"
4680 lopen
4681 let wid = win_getid()
4682 let qfbnum = bufnr('')
4683 wincmd p
4684 call setloclist(0, [], 'f')
4685 lexpr "F1:10:Line10"
4686 lopen
4687 call assert_equal(wid, win_getid())
4688 call assert_equal(qfbnum, bufnr(''))
4689 lclose
4690
4691 " When the window with the location list is closed, the buffer should be
4692 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004693 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004694 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004695 endif
4696endfunc
4697
4698func Test_qfbuf()
4699 call Xqfbuf_test('c')
4700 call Xqfbuf_test('l')
4701endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004702
4703" If there is an autocmd to use only one window, then opening the location
4704" list window used to crash Vim.
4705func Test_winonly_autocmd()
4706 call s:create_test_file('Xtest1')
4707 " Autocmd to show only one Vim window at a time
4708 autocmd WinEnter * only
4709 new
4710 " Load the location list
4711 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4712 let loclistid = getloclist(0, {'id' : 0}).id
4713 " Open the location list window. Only this window will be shown and the file
4714 " window is closed.
4715 lopen
4716 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4717 " Jump to an entry in the location list and make sure that the cursor is
4718 " positioned correctly.
4719 ll 3
4720 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004721 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004722 call assert_equal(15, line('.'))
4723 " Cleanup
4724 autocmd! WinEnter
4725 new | only
4726 call delete('Xtest1')
4727endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004728
4729" Test to make sure that an empty quickfix buffer is not reused for loading
4730" a normal buffer.
4731func Test_empty_qfbuf()
4732 enew | only
4733 call writefile(["Test"], 'Xfile1')
4734 call setqflist([], 'f')
4735 copen | only
4736 let qfbuf = bufnr('')
4737 edit Xfile1
4738 call assert_notequal(qfbuf, bufnr(''))
4739 enew
4740 call delete('Xfile1')
4741endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004742
4743" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004744" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004745func Xtest_below(cchar)
4746 call s:setup_commands(a:cchar)
4747
4748 " No quickfix/location list
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 " Empty quickfix/location list
4755 call g:Xsetlist([])
4756 call assert_fails('Xbelow', 'E42:')
4757 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004758 call assert_fails('Xbefore', 'E42:')
4759 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004760
4761 call s:create_test_file('X1')
4762 call s:create_test_file('X2')
4763 call s:create_test_file('X3')
4764 call s:create_test_file('X4')
4765
4766 " Invalid entries
4767 edit X1
4768 call g:Xsetlist(["E1", "E2"])
4769 call assert_fails('Xbelow', 'E42:')
4770 call assert_fails('Xabove', 'E42:')
4771 call assert_fails('3Xbelow', 'E42:')
4772 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004773 call assert_fails('Xbefore', 'E42:')
4774 call assert_fails('Xafter', 'E42:')
4775 call assert_fails('3Xbefore', 'E42:')
4776 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004777
4778 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004779 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 +02004780 edit +7 X2
4781 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004782 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004783 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004784 normal 7G
4785 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004786 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004787 call assert_fails('Xbefore', 'E553:')
4788
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004789 normal 2j
4790 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004791 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004792 normal 7G
4793 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004794 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004795
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004796 " Last error in this file
4797 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004798 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004799 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004800 normal gg
4801 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004802 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004803 call assert_fails('Xafter', 'E553:')
4804
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004805 " First error in this file
4806 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004807 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004808 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004809 normal G
4810 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004811 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004812 call assert_fails('Xbefore', 'E553:')
4813
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004814 normal gg
4815 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004816 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004817 normal gg
4818 Xafter 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 normal G
4822 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004823 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004824 normal G
4825 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004826 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004827
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004828 edit X4
4829 call assert_fails('Xabove', 'E42:')
4830 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004831 call assert_fails('Xbefore', 'E42:')
4832 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004833 if a:cchar == 'l'
4834 " If a buffer has location list entries from some other window but not
4835 " from the current window, then the commands should fail.
4836 edit X1 | split | call setloclist(0, [], 'f')
4837 call assert_fails('Xabove', 'E776:')
4838 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004839 call assert_fails('Xbefore', 'E776:')
4840 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004841 close
4842 endif
4843
4844 " Test for lines with multiple quickfix entries
4845 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4846 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4847 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4848 edit +1 X2
4849 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004850 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004851 normal 1G
4852 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004853 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004854
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004855 normal gg
4856 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004857 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004858 normal gg
4859 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004860 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004861
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004862 normal G
4863 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004864 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004865 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004866 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004867 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004868
4869 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004870 Xabove 99
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 G
4873 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004874 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004875
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004876 normal 10G
4877 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004878 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004879 normal 10G$
4880 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004881 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004882
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004883 normal 10G
4884 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004885 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004886 normal 9G
4887 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004888 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004889
4890 " Invalid range
4891 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004892 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004893 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004894 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004895 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004896 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004897 endif
4898
4899 call delete('X1')
4900 call delete('X2')
4901 call delete('X3')
4902 call delete('X4')
4903endfunc
4904
4905func Test_cbelow()
4906 call Xtest_below('c')
4907 call Xtest_below('l')
4908endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004909
4910func Test_quickfix_count()
4911 let commands = [
4912 \ 'cNext',
4913 \ 'cNfile',
4914 \ 'cabove',
4915 \ 'cbelow',
4916 \ 'cfirst',
4917 \ 'clast',
4918 \ 'cnewer',
4919 \ 'cnext',
4920 \ 'cnfile',
4921 \ 'colder',
4922 \ 'cprevious',
4923 \ 'crewind',
4924 \
4925 \ 'lNext',
4926 \ 'lNfile',
4927 \ 'labove',
4928 \ 'lbelow',
4929 \ 'lfirst',
4930 \ 'llast',
4931 \ 'lnewer',
4932 \ 'lnext',
4933 \ 'lnfile',
4934 \ 'lolder',
4935 \ 'lprevious',
4936 \ 'lrewind',
4937 \ ]
4938 for cmd in commands
4939 call assert_fails('-1' .. cmd, 'E16:')
4940 call assert_fails('.' .. cmd, 'E16:')
4941 call assert_fails('%' .. cmd, 'E16:')
4942 call assert_fails('$' .. cmd, 'E16:')
4943 endfor
4944endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004945
4946" Test for aborting quickfix commands using QuickFixCmdPre
4947func Xtest_qfcmd_abort(cchar)
4948 call s:setup_commands(a:cchar)
4949
4950 call g:Xsetlist([], 'f')
4951
4952 " cexpr/lexpr
4953 let e = ''
4954 try
4955 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4956 catch /.*/
4957 let e = v:exception
4958 endtry
4959 call assert_equal('AbortCmd', e)
4960 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4961
4962 " cfile/lfile
4963 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4964 let e = ''
4965 try
4966 Xfile Xfile1
4967 catch /.*/
4968 let e = v:exception
4969 endtry
4970 call assert_equal('AbortCmd', e)
4971 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4972 call delete('Xfile1')
4973
4974 " cgetbuffer/lgetbuffer
4975 enew!
4976 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4977 let e = ''
4978 try
4979 Xgetbuffer
4980 catch /.*/
4981 let e = v:exception
4982 endtry
4983 call assert_equal('AbortCmd', e)
4984 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4985 enew!
4986
4987 " vimgrep/lvimgrep
4988 let e = ''
4989 try
4990 Xvimgrep /func/ test_quickfix.vim
4991 catch /.*/
4992 let e = v:exception
4993 endtry
4994 call assert_equal('AbortCmd', e)
4995 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4996
4997 " helpgrep/lhelpgrep
4998 let e = ''
4999 try
5000 Xhelpgrep quickfix
5001 catch /.*/
5002 let e = v:exception
5003 endtry
5004 call assert_equal('AbortCmd', e)
5005 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5006
5007 " grep/lgrep
5008 if has('unix')
5009 let e = ''
5010 try
5011 silent Xgrep func test_quickfix.vim
5012 catch /.*/
5013 let e = v:exception
5014 endtry
5015 call assert_equal('AbortCmd', e)
5016 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5017 endif
5018endfunc
5019
5020func Test_qfcmd_abort()
5021 augroup QF_Test
5022 au!
5023 autocmd QuickFixCmdPre * throw "AbortCmd"
5024 augroup END
5025
5026 call Xtest_qfcmd_abort('c')
5027 call Xtest_qfcmd_abort('l')
5028
5029 augroup QF_Test
5030 au!
5031 augroup END
5032endfunc
5033
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005034" Test for using a file in one of the parent directories.
5035func Test_search_in_dirstack()
5036 call mkdir('Xtestdir/a/b/c', 'p')
5037 let save_cwd = getcwd()
5038 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5039 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5040 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5041 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5042
5043 let lines = "Entering dir Xtestdir\n" .
5044 \ "Entering dir a\n" .
5045 \ "Entering dir b\n" .
5046 \ "Xfile2:2:X2_L2\n" .
5047 \ "Leaving dir a\n" .
5048 \ "Xfile1:2:X1_L2\n" .
5049 \ "Xfile3:1:X3_L1\n" .
5050 \ "Entering dir c\n" .
5051 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005052 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005053 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005054 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005055 call assert_equal(11, getqflist({'size' : 0}).size)
5056 call assert_equal(4, getqflist({'idx' : 0}).idx)
5057 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005058 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005059 cnext
5060 call assert_equal(6, getqflist({'idx' : 0}).idx)
5061 call assert_equal('X1_L2', getline('.'))
5062 cnext
5063 call assert_equal(7, getqflist({'idx' : 0}).idx)
5064 call assert_equal(1, line('$'))
5065 call assert_equal('', getline(1))
5066 cnext
5067 call assert_equal(9, getqflist({'idx' : 0}).idx)
5068 call assert_equal(1, line('$'))
5069 call assert_equal('', getline(1))
5070
5071 set efm&
5072 exe 'cd ' . save_cwd
5073 call delete('Xtestdir', 'rf')
5074endfunc
5075
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005076" Test for :cquit
5077func Test_cquit()
5078 " Exit Vim with a non-zero value
5079 if RunVim([], ["cquit 7"], '')
5080 call assert_equal(7, v:shell_error)
5081 endif
5082
5083 if RunVim([], ["50cquit"], '')
5084 call assert_equal(50, v:shell_error)
5085 endif
5086
5087 " Exit Vim with default value
5088 if RunVim([], ["cquit"], '')
5089 call assert_equal(1, v:shell_error)
5090 endif
5091
5092 " Exit Vim with zero value
5093 if RunVim([], ["cquit 0"], '')
5094 call assert_equal(0, v:shell_error)
5095 endif
5096
5097 " Exit Vim with negative value
5098 call assert_fails('-3cquit', 'E16:')
5099endfunc
5100
Bram Moolenaar858ba062020-05-31 23:11:59 +02005101" Test for getting a specific item from a quickfix list
5102func Xtest_getqflist_by_idx(cchar)
5103 call s:setup_commands(a:cchar)
5104 " Empty list
5105 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5106 Xexpr ['F1:10:L10', 'F1:20:L20']
5107 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5108 call assert_equal(bufnr('F1'), l[0].bufnr)
5109 call assert_equal(20, l[0].lnum)
5110 call assert_equal('L20', l[0].text)
5111 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5112 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5113 %bwipe!
5114endfunc
5115
5116func Test_getqflist_by_idx()
5117 call Xtest_getqflist_by_idx('c')
5118 call Xtest_getqflist_by_idx('l')
5119endfunc
5120
5121" Test for the 'quickfixtextfunc' setting
5122func Tqfexpr(info)
5123 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005124 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005125 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005126 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005127 endif
5128
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005129 let l = []
5130 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5131 let e = qfl[idx]
5132 let s = ''
5133 if e.bufnr != 0
5134 let bname = bufname(e.bufnr)
5135 let s ..= fnamemodify(bname, ':.')
5136 endif
5137 let s ..= '-'
5138 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5139 let s ..= e.text
5140 call add(l, s)
5141 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005142
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005143 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005144endfunc
5145
5146func Xtest_qftextfunc(cchar)
5147 call s:setup_commands(a:cchar)
5148
5149 set efm=%f:%l:%c:%m
5150 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005151 call assert_equal('Tqfexpr', &quickfixtextfunc)
5152 call assert_equal('',
5153 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005154 call g:Xsetlist([
5155 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5156 \ 'end_col': 7, 'text': 'green'},
5157 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5158 \ 'end_col': 8, 'text': 'blue'},
5159 \ ])
5160
Bram Moolenaar858ba062020-05-31 23:11:59 +02005161 Xwindow
5162 call assert_equal('F1-L10C2-green', getline(1))
5163 call assert_equal('F1-L20C4-blue', getline(2))
5164 Xclose
5165 set quickfixtextfunc&vim
5166 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005167 call assert_equal('F1|10 col 2-7| green', getline(1))
5168 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005169 Xclose
5170 set efm&
5171 set quickfixtextfunc&
5172
5173 " Test for per list 'quickfixtextfunc' setting
5174 func PerQfText(info)
5175 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005176 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005177 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005178 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005179 endif
5180 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005181 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005182 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005183 let l = []
5184 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5185 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5186 endfor
5187 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005188 endfunc
5189 set quickfixtextfunc=Tqfexpr
5190 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5191 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5192 Xwindow
5193 call assert_equal('Line 10, Col 2', getline(1))
5194 call assert_equal('Line 20, Col 4', getline(2))
5195 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005196 call assert_equal(function('PerQfText'),
5197 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005198 " Add entries to the list when the quickfix buffer is hidden
5199 Xaddexpr ['F1:30:6:red']
5200 Xwindow
5201 call assert_equal('Line 30, Col 6', getline(3))
5202 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005203 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005204 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005205 set quickfixtextfunc&
5206 delfunc PerQfText
5207
5208 " Non-existing function
5209 set quickfixtextfunc=Tabc
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 non-function
5216 set quickfixtextfunc=[10,\ 20]
5217 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5218 call assert_fails("Xwindow", 'E117:')
5219 Xclose
5220 set quickfixtextfunc&
5221
5222 " set option to a function with different set of arguments
5223 func Xqftext(a, b, c)
5224 return a:a .. a:b .. a:c
5225 endfunc
5226 set quickfixtextfunc=Xqftext
5227 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5228 call assert_fails("Xwindow", 'E119:')
5229 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005230
5231 " set option to a function that returns a list with non-strings
5232 func Xqftext2(d)
5233 return ['one', [], 'two']
5234 endfunc
5235 set quickfixtextfunc=Xqftext2
5236 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5237 \ 'E730:')
5238 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005239 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5240 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005241 Xclose
5242
Bram Moolenaar858ba062020-05-31 23:11:59 +02005243 set quickfixtextfunc&
5244 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005245 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005246
5247 " set the global option to a lambda function
5248 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5249 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5250 Xwindow
5251 call assert_equal(['green', 'blue'], getline(1, '$'))
5252 Xclose
5253 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)
5254 set quickfixtextfunc&
5255
5256 " use a lambda function that returns an empty list
5257 set quickfixtextfunc={d\ ->\ []}
5258 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5259 Xwindow
5260 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5261 \ getline(1, '$'))
5262 Xclose
5263 set quickfixtextfunc&
5264
5265 " use a lambda function that returns a list with empty strings
5266 set quickfixtextfunc={d\ ->\ ['',\ '']}
5267 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5268 Xwindow
5269 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5270 \ getline(1, '$'))
5271 Xclose
5272 set quickfixtextfunc&
5273
5274 " set the per-quickfix list text function to a lambda function
5275 call g:Xsetlist([], ' ',
5276 \ {'quickfixtextfunc' :
5277 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5278 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5279 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5280 Xwindow
5281 call assert_equal('Line 10, Col 2', getline(1))
5282 call assert_equal('Line 20, Col 4', getline(2))
5283 Xclose
5284 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5285 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005286endfunc
5287
5288func Test_qftextfunc()
5289 call Xtest_qftextfunc('c')
5290 call Xtest_qftextfunc('l')
5291endfunc
5292
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005293func Test_qftextfunc_callback()
5294 let lines =<< trim END
5295 set efm=%f:%l:%c:%m
5296
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005297 #" Test for using a function name
5298 LET &qftf = 'g:Tqfexpr'
5299 cexpr "F0:0:0:L0"
5300 copen
5301 call assert_equal('F0-L0C0-L0', getline(1))
5302 cclose
5303
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005304 #" Test for using a function()
5305 set qftf=function('g:Tqfexpr')
5306 cexpr "F1:1:1:L1"
5307 copen
5308 call assert_equal('F1-L1C1-L1', getline(1))
5309 cclose
5310
5311 #" Using a funcref variable to set 'quickfixtextfunc'
5312 VAR Fn = function('g:Tqfexpr')
5313 LET &qftf = Fn
5314 cexpr "F2:2:2:L2"
5315 copen
5316 call assert_equal('F2-L2C2-L2', getline(1))
5317 cclose
5318
5319 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5320 LET Fn = function('g:Tqfexpr')
5321 LET &qftf = string(Fn)
5322 cexpr "F3:3:3:L3"
5323 copen
5324 call assert_equal('F3-L3C3-L3', getline(1))
5325 cclose
5326
5327 #" Test for using a funcref()
5328 set qftf=funcref('g:Tqfexpr')
5329 cexpr "F4:4:4:L4"
5330 copen
5331 call assert_equal('F4-L4C4-L4', getline(1))
5332 cclose
5333
5334 #" Using a funcref variable to set 'quickfixtextfunc'
5335 LET Fn = funcref('g:Tqfexpr')
5336 LET &qftf = Fn
5337 cexpr "F5:5:5:L5"
5338 copen
5339 call assert_equal('F5-L5C5-L5', getline(1))
5340 cclose
5341
5342 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5343 LET Fn = funcref('g:Tqfexpr')
5344 LET &qftf = string(Fn)
5345 cexpr "F5:5:5:L5"
5346 copen
5347 call assert_equal('F5-L5C5-L5', getline(1))
5348 cclose
5349
5350 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005351 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005352 LET optval = substitute(optval, ' ', '\\ ', 'g')
5353 exe "set qftf=" .. optval
5354 cexpr "F6:6:6:L6"
5355 copen
5356 call assert_equal('F6-L6C6-L6', getline(1))
5357 cclose
5358
5359 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005360 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005361 cexpr "F7:7:7:L7"
5362 copen
5363 call assert_equal('F7-L7C7-L7', getline(1))
5364 cclose
5365
5366 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005367 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005368 cexpr "F8:8:8:L8"
5369 copen
5370 call assert_equal('F8-L8C8-L8', getline(1))
5371 cclose
5372
5373 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005374 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005375 LET &qftf = Lambda
5376 cexpr "F9:9:9:L9"
5377 copen
5378 call assert_equal('F9-L9C9-L9', getline(1))
5379 cclose
5380
5381 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005382 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005383 LET &qftf = string(Lambda)
5384 cexpr "F9:9:9:L9"
5385 copen
5386 call assert_equal('F9-L9C9-L9', getline(1))
5387 cclose
5388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005389 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005390
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005391 " Test for using a script-local function name
5392 func s:TqfFunc2(info)
5393 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5394 return ''
5395 endfunc
5396 let g:TqfFunc2Args = []
5397 set quickfixtextfunc=s:TqfFunc2
5398 cexpr "F10:10:10:L10"
5399 cclose
5400 call assert_equal([1, 1], g:TqfFunc2Args)
5401
5402 let &quickfixtextfunc = 's:TqfFunc2'
5403 cexpr "F11:11:11:L11"
5404 cclose
5405 call assert_equal([1, 1], g:TqfFunc2Args)
5406 delfunc s:TqfFunc2
5407
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005408 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5409 func SetQftfFunc()
5410 let params = {'qftf': function('g:DictQftfFunc')}
5411 let &quickfixtextfunc = params.qftf
5412 endfunc
5413 func g:DictQftfFunc(_) dict
5414 endfunc
5415 call SetQftfFunc()
5416 new
5417 call SetQftfFunc()
5418 bw
5419 call test_garbagecollect_now()
5420 new
5421 set qftf=
5422 wincmd w
5423 set qftf=
5424 :%bw!
5425
5426 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5427 " to cause a crash.
5428 let &qftf = ''
5429 func SetLocalQftfFunc()
5430 let params = {'qftf': function('g:DictQftfFunc')}
5431 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5432 endfunc
5433 call SetLocalQftfFunc()
5434 call test_garbagecollect_now()
5435 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5436 delfunc g:DictQftfFunc
5437 delfunc SetQftfFunc
5438 delfunc SetLocalQftfFunc
5439 set efm&
5440endfunc
5441
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005442" Test for updating a location list for some other window and check that
5443" 'qftextfunc' uses the correct location list.
5444func Test_qftextfunc_other_loclist()
5445 %bw!
5446 call setloclist(0, [], 'f')
5447
5448 " create a window and a location list for it and open the location list
5449 " window
5450 lexpr ['F1:10:12:one', 'F1:20:14:two']
5451 let w1_id = win_getid()
5452 call setloclist(0, [], ' ',
5453 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5454 \ 'quickfixtextfunc':
5455 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5456 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5457 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5458 lwindow
5459 let w2_id = win_getid()
5460
5461 " create another window and a location list for it and open the location
5462 " list window
5463 topleft new
5464 let w3_id = win_getid()
5465 call setloclist(0, [], ' ',
5466 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5467 \ 'quickfixtextfunc':
5468 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5469 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5470 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5471 lwindow
5472 let w4_id = win_getid()
5473
5474 topleft new
5475 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5476 let w5_id = win_getid()
5477
5478 " change the location list for some other window
5479 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5480 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5481 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5482 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5483 \ getbufline(winbufnr(w2_id), 1, '$'))
5484 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5485 \ getbufline(winbufnr(w4_id), 1, '$'))
5486 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5487 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5488 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5489 \ getbufline(winbufnr(w2_id), 1, '$'))
5490 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5491 \ getbufline(winbufnr(w4_id), 1, '$'))
5492
5493 call win_gotoid(w5_id)
5494 lwindow
5495 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5496 \ getline(1, '$'))
5497 %bw!
5498endfunc
5499
Bram Moolenaarec98e932020-06-08 19:35:59 +02005500" Running :lhelpgrep command more than once in a help window, doesn't jump to
5501" the help topic
5502func Test_lhelpgrep_from_help_window()
5503 call mkdir('Xtestdir/doc', 'p')
5504 call writefile(['window'], 'Xtestdir/doc/a.txt')
5505 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5506 let save_rtp = &rtp
5507 let &rtp = 'Xtestdir'
5508 lhelpgrep window
5509 lhelpgrep buffer
5510 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5511 lhelpgrep window
5512 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5513 let &rtp = save_rtp
5514 call delete('Xtestdir', 'rf')
5515 new | only!
5516endfunc
5517
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005518" Test for the crash fixed by 7.3.715
5519func Test_setloclist_crash()
5520 %bw!
5521 let g:BufNum = bufnr()
5522 augroup QF_Test
5523 au!
5524 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5525 augroup END
5526
5527 try
5528 lvimgrep /.*/ *.mak
5529 catch /E926:/
5530 endtry
5531 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5532 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5533
5534 augroup QF_Test
5535 au!
5536 augroup END
5537 unlet g:BufNum
5538 %bw!
5539endfunc
5540
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005541" Test for adding an invalid entry with the quickfix window open and making
5542" sure that the window contents are not changed
5543func Test_add_invalid_entry_with_qf_window()
5544 call setqflist([], 'f')
5545 cexpr "Xfile1:10:aa"
5546 copen
5547 call setqflist(['bb'], 'a')
5548 call assert_equal(1, line('$'))
5549 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005550 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())
5551
5552 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5553 call assert_equal(1 , line('$'))
5554 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5555 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())
5556
5557 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')
5558 call assert_equal(1 , line('$'))
5559 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5560 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())
5561
5562 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')
5563 call assert_equal(1 , line('$'))
5564 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5565 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())
5566
5567 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')
5568 call assert_equal(1 , line('$'))
5569 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5570 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())
5571
5572 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')
5573 call assert_equal(1 , line('$'))
5574 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5575 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())
5576
5577 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')
5578 call assert_equal(1 , line('$'))
5579 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5580 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())
5581
5582 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')
5583 call assert_equal(1 , line('$'))
5584 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5585 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 +01005586 cclose
5587endfunc
5588
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005589" Test for very weird problem: autocommand causes a failure, resulting opening
5590" the quickfix window to fail. This still splits the window, but otherwise
5591" should not mess up buffers.
5592func Test_quickfix_window_fails_to_open()
5593 CheckScreendump
5594
5595 let lines =<< trim END
5596 anything
5597 try
5598 anything
5599 endtry
5600 END
5601 call writefile(lines, 'XquickfixFails')
5602
5603 let lines =<< trim END
5604 split XquickfixFails
5605 silent vimgrep anything %
5606 normal o
5607 au BufLeave * ++once source XquickfixFails
5608 " This will trigger the autocommand, which causes an error, what follows
5609 " is aborted but the window was already split.
5610 silent! cwindow
5611 END
5612 call writefile(lines, 'XtestWinFails')
5613 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5614 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5615
5616 " clean up
5617 call term_sendkeys(buf, ":bwipe!\<CR>")
5618 call term_wait(buf)
5619 call StopVimInTerminal(buf)
5620 call delete('XtestWinFails')
5621 call delete('XquickfixFails')
5622endfunc
5623
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005624" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005625" is changed.
5626func Xqfbuf_update(cchar)
5627 call s:setup_commands(a:cchar)
5628
5629 Xexpr "F1:1:line1"
5630 Xopen
5631 call assert_equal(['F1|1| line1'], getline(1, '$'))
5632 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5633
5634 " Test setqflist() using the 'lines' key in 'what'
5635 " add a new entry
5636 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5637 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5638 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5639 " replace all the entries with a single entry
5640 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5641 call assert_equal(['F3|3| line3'], getline(1, '$'))
5642 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5643 " remove all the entries
5644 call g:Xsetlist([], 'r', {'lines' : []})
5645 call assert_equal([''], getline(1, '$'))
5646 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5647 " add a new list
5648 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5649 call assert_equal(['F4|4| line4'], getline(1, '$'))
5650 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5651
5652 " Test setqflist() using the 'items' key in 'what'
5653 " add a new entry
5654 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5655 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5656 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5657 " replace all the entries with a single entry
5658 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5659 call assert_equal(['F6|6| line6'], getline(1, '$'))
5660 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5661 " remove all the entries
5662 call g:Xsetlist([], 'r', {'items' : []})
5663 call assert_equal([''], getline(1, '$'))
5664 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5665 " add a new list
5666 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5667 call assert_equal(['F7|7| line7'], getline(1, '$'))
5668 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5669
5670 call g:Xsetlist([], ' ', {})
5671 call assert_equal([''], getline(1, '$'))
5672 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5673
5674 Xclose
5675endfunc
5676
5677func Test_qfbuf_update()
5678 call Xqfbuf_update('c')
5679 call Xqfbuf_update('l')
5680endfunc
5681
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005682func Test_vimgrep_noswapfile()
5683 set noswapfile
5684 call writefile(['one', 'two', 'three'], 'Xgreppie')
5685 vimgrep two Xgreppie
5686 call assert_equal('two', getline('.'))
5687
5688 call delete('Xgreppie')
5689 set swapfile
5690endfunc
5691
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005692" Test for the :vimgrep 'f' flag (fuzzy match)
5693func Xvimgrep_fuzzy_match(cchar)
5694 call s:setup_commands(a:cchar)
5695
5696 Xvimgrep /three one/f Xfile*
5697 let l = g:Xgetlist()
5698 call assert_equal(2, len(l))
5699 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5700 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5701 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5702 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5703
5704 Xvimgrep /the/f Xfile*
5705 let l = g:Xgetlist()
5706 call assert_equal(3, len(l))
5707 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5708 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5709 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5710 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5711 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5712 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5713
5714 Xvimgrep /aaa/fg Xfile*
5715 let l = g:Xgetlist()
5716 call assert_equal(4, len(l))
5717 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5718 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5719 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5720 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5721 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5722 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5723 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5724 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5725
5726 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5727endfunc
5728
5729func Test_vimgrep_fuzzy_match()
5730 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5731 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5732 call Xvimgrep_fuzzy_match('c')
5733 call Xvimgrep_fuzzy_match('l')
5734 call delete('Xfile1')
5735 call delete('Xfile2')
5736endfunc
5737
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005738func Test_locationlist_open_in_newtab()
5739 call s:create_test_file('Xqftestfile1')
5740 call s:create_test_file('Xqftestfile2')
5741 call s:create_test_file('Xqftestfile3')
5742
5743 %bwipe!
5744
5745 lgetexpr ['Xqftestfile1:5:Line5',
5746 \ 'Xqftestfile2:10:Line10',
5747 \ 'Xqftestfile3:16:Line16']
5748
5749 silent! llast
5750 call assert_equal(1, tabpagenr('$'))
5751 call assert_equal('Xqftestfile3', bufname())
5752
5753 set switchbuf=newtab
5754
5755 silent! lfirst
5756 call assert_equal(2, tabpagenr('$'))
5757 call assert_equal('Xqftestfile1', bufname())
5758
5759 silent! lnext
5760 call assert_equal(3, tabpagenr('$'))
5761 call assert_equal('Xqftestfile2', bufname())
5762
5763 call delete('Xqftestfile1')
5764 call delete('Xqftestfile2')
5765 call delete('Xqftestfile3')
5766 set switchbuf&vim
5767
5768 %bwipe!
5769endfunc
5770
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005771" Test for win_gettype() in quickfix and location list windows
5772func Test_win_gettype()
5773 copen
5774 call assert_equal("quickfix", win_gettype())
5775 let wid = win_getid()
5776 wincmd p
5777 call assert_equal("quickfix", win_gettype(wid))
5778 cclose
5779 lexpr ''
5780 lopen
5781 call assert_equal("loclist", win_gettype())
5782 let wid = win_getid()
5783 wincmd p
5784 call assert_equal("loclist", win_gettype(wid))
5785 lclose
5786endfunc
5787
Christian Brabandt0b226f62021-12-01 10:54:24 +00005788fun Test_vimgrep_nomatch()
5789 call XexprTests('c')
5790 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5791 copen
5792 if has("win32")
5793 call assert_fails('vimgrep foo *.zzz', 'E479:')
5794 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'}]
5795 else
5796 call assert_fails('vimgrep foo *.zzz', 'E480:')
5797 let expected = []
5798 endif
5799 call assert_equal(expected, getqflist())
5800 cclose
5801endfunc
5802
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005803" Test for opening the quickfix window in two tab pages and then closing one
5804" of the quickfix windows. This should not make the quickfix buffer unlisted.
5805" (github issue #9300).
5806func Test_two_qf_windows()
5807 cexpr "F1:1:line1"
5808 copen
5809 tabnew
5810 copen
5811 call assert_true(&buflisted)
5812 cclose
5813 tabfirst
5814 call assert_true(&buflisted)
5815 let bnum = bufnr()
5816 cclose
5817 " if all the quickfix windows are closed, then buffer should be unlisted.
5818 call assert_false(buflisted(bnum))
5819 %bw!
5820
5821 " Repeat the test for a location list
5822 lexpr "F2:2:line2"
5823 lopen
5824 let bnum = bufnr()
5825 tabnew
5826 exe "buffer" bnum
5827 tabfirst
5828 lclose
5829 tablast
5830 call assert_true(buflisted(bnum))
5831 tabclose
5832 lopen
5833 call assert_true(buflisted(bnum))
5834 lclose
5835 call assert_false(buflisted(bnum))
5836 %bw!
5837endfunc
5838
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005839" Weird sequence of commands that caused entering a wiped-out buffer
5840func Test_lopen_bwipe()
5841 func R()
5842 silent! tab lopen
5843 e x
5844 silent! lfile
5845 endfunc
5846
5847 cal R()
5848 cal R()
5849 cal R()
5850 bw!
5851 delfunc R
5852endfunc
5853
5854
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005855" vim: shiftwidth=2 sts=2 expandtab