blob: 5dd72177753433fa9a25cebcc167c0c62e2da9ee [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:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000257 call assert_fails('lwindow', 'E776:')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200258 endif
259
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100260 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200261 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100262
263 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200264 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100265 call assert_true(winnr('$') == 1)
266
267 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200268 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
269 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100270
271 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200272 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100273 call assert_true(winnr('$') == 2 && winnr() == 2 &&
274 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200275 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200278 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100279 call assert_true(winnr('$') == 1)
280
281 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200282 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100283
284 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200285 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100286 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200287 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100288
289 " Opening the window again, should move the cursor to that window
290 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200291 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100292 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200293 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100294 \ getline('.') ==# '|| non-error 1')
295
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100296 " :cnext in quickfix window should move to the next entry
297 Xnext
298 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100299
300 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200301 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100302 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200303
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100304 " Specifying the width should adjust the width for a vertically split
305 " quickfix window.
306 vert Xopen
307 call assert_equal(10, winwidth(0))
308 vert Xopen 12
309 call assert_equal(12, winwidth(0))
310 Xclose
311
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200312 " Horizontally or vertically splitting the quickfix window should create a
313 " normal window/buffer
314 Xopen
315 wincmd s
316 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
317 call assert_equal(0, getwininfo(win_getid())[0].loclist)
318 call assert_notequal('quickfix', &buftype)
319 close
320 Xopen
321 wincmd v
322 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
323 call assert_equal(0, getwininfo(win_getid())[0].loclist)
324 call assert_notequal('quickfix', &buftype)
325 close
326 Xopen
327 Xclose
328
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200329 if a:cchar == 'c'
330 " Opening the quickfix window in multiple tab pages should reuse the
331 " quickfix buffer
332 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
333 \ 'Xtestfile3:3:1:Line3']
334 Xopen
335 let qfbufnum = bufnr('%')
336 tabnew
337 Xopen
338 call assert_equal(qfbufnum, bufnr('%'))
339 new | only | tabonly
340 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100341endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100342
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100343func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100344 call XwindowTests('c')
345 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100346endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100347
Bram Moolenaar36d50222019-05-02 20:17:40 +0200348func Test_copenHeight()
349 copen
350 wincmd H
351 let height = winheight(0)
352 copen 10
353 call assert_equal(height, winheight(0))
354 quit
355endfunc
356
Bram Moolenaar1142a312019-10-16 14:51:39 +0200357func Test_copenHeight_tabline()
358 set tabline=foo showtabline=2
359 copen
360 wincmd H
361 let height = winheight(0)
362 copen 10
363 call assert_equal(height, winheight(0))
364 quit
365 set tabline& showtabline&
366endfunc
367
368
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100369" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
370" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100371func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200372 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373
374 call writefile(['Xtestfile1:700:10:Line 700',
375 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
376
377 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200378 Xfile Xqftestfile1
379 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100380 call assert_true(len(l) == 2 &&
381 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
382 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
383
Bram Moolenaar049cba92016-06-26 14:38:04 +0200384 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200385 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200386
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100387 " Run cfile/lfile from a modified buffer
388 enew!
389 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200390 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100391 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
392
393 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200394 Xaddfile Xqftestfile1
395 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100396 call assert_true(len(l) == 3 &&
397 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
398
399 call writefile(['Xtestfile1:222:77:Line 222',
400 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
401
402 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200403 Xgetfile Xqftestfile1
404 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100405 call assert_true(len(l) == 2 &&
406 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
407 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
408
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100409 " Test for a file with a long line and without a newline at the end
410 let text = repeat('x', 1024)
411 let t = 'a.txt:18:' . text
412 call writefile([t], 'Xqftestfile1', 'b')
413 silent! Xfile Xqftestfile1
414 call assert_equal(text, g:Xgetlist()[0].text)
415
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100416 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100417endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100418
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100419func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420 call XfileTests('c')
421 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100422endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100423
424" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
425" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100426func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200427 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100428
429 enew!
430 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
431 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200432 Xbuffer!
433 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434 call assert_true(len(l) == 2 &&
435 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
436 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
437
438 enew!
439 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
440 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200441 Xgetbuffer
442 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100443 call assert_true(len(l) == 2 &&
444 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
445 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
446
447 enew!
448 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
449 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200450 Xaddbuffer
451 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100452 call assert_true(len(l) == 4 &&
453 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
454 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
455 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200456 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100457
Bram Moolenaaree85df32017-03-19 14:19:50 +0100458 " Check for invalid buffer
459 call assert_fails('Xbuffer 199', 'E474:')
460
461 " Check for unloaded buffer
462 edit Xtestfile1
463 let bnr = bufnr('%')
464 enew!
465 call assert_fails('Xbuffer ' . bnr, 'E681:')
466
467 " Check for invalid range
468 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
469 " commands. So directly call the commands.
470 if (a:cchar == 'c')
471 call assert_fails('900,999cbuffer', 'E16:')
472 else
473 call assert_fails('900,999lbuffer', 'E16:')
474 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100475endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100476
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100477func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100478 call XbufferTests('c')
479 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100480endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100481
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100482func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200483 call s:setup_commands(a:cchar)
484
485 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100486endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200487
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100488func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200489 call XexprTests('c')
490 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100491endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200492
493" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100494func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200495 call s:setup_commands(a:cchar)
496
Bram Moolenaar74240d32017-12-10 15:26:15 +0100497 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200498 " Jumping to first or next location list entry without any error should
499 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100500 if a:cchar == 'c'
501 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100502 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100503 else
504 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100505 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200506 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100507 call assert_fails('Xnext', err)
508 call assert_fails('Xprev', err)
509 call assert_fails('Xnfile', err)
510 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100511 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200512
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100513 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100514 call assert_fails(cmd, 'E42:')
515
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200516 call s:create_test_file('Xqftestfile1')
517 call s:create_test_file('Xqftestfile2')
518
519 Xgetexpr ['Xqftestfile1:5:Line5',
520 \ 'Xqftestfile1:6:Line6',
521 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200522 \ 'Xqftestfile2:11:Line11',
523 \ 'RegularLine1',
524 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525
526 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100527 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200528 call assert_fails('Xprev', 'E553:')
529 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200530 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200531 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200532 call assert_equal(10, line('.'))
533 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200534 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200535 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100536 5Xcc
537 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
538 2Xcc
539 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100540 if a:cchar == 'c'
541 cc
542 else
543 ll
544 endif
545 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100546 10Xcc
547 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200548 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200549 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200550 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200551 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200552 call assert_fails('Xnext', 'E553:')
553 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100554 " To process the range using quickfix list entries, directly use the
555 " quickfix commands (don't use the user defined commands)
556 if a:cchar == 'c'
557 $cc
558 else
559 $ll
560 endif
561 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200562 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200563 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200564 call assert_equal(5, line('.'))
565
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200566 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200567 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200568 call assert_equal(11, line('.'))
569 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200570 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200571 call assert_equal(5, line('.'))
572
Bram Moolenaar74240d32017-12-10 15:26:15 +0100573 " Jumping to an error from the error window using cc command
574 Xgetexpr ['Xqftestfile1:5:Line5',
575 \ 'Xqftestfile1:6:Line6',
576 \ 'Xqftestfile2:10:Line10',
577 \ 'Xqftestfile2:11:Line11']
578 Xopen
579 10Xcc
580 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200581 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100582 Xopen
583 call cursor(2, 1)
584 if a:cchar == 'c'
585 .cc
586 else
587 .ll
588 endif
589 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200590 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100591
592 " Jumping to an error from the error window (when only the error window is
593 " present)
594 Xopen | only
595 Xlast 1
596 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200597 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100598
Bram Moolenaaree85df32017-03-19 14:19:50 +0100599 Xexpr ""
600 call assert_fails('Xnext', 'E42:')
601
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200602 call delete('Xqftestfile1')
603 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200604
605 " Should be able to use next/prev with invalid entries
606 Xexpr ""
607 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
608 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100609 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200610 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
611 Xlast
612 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
613 Xfirst
614 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
615 2Xnext
616 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100617endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200618
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100619func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200620 call Xtest_browse('c')
621 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100622endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200623
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100624func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200625 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100626 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100627
Bram Moolenaarce90e362019-09-08 18:58:44 +0200628 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100629 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100630
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200631 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100632 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100633
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200634 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100635 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100636
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200637 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100638 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100639
640endfunc
641
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100642func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200643 call s:setup_commands(a:cchar)
644 Xhelpgrep quickfix
645 Xopen
646 if a:cchar == 'c'
647 let title_text = ':helpgrep quickfix'
648 else
649 let title_text = ':lhelpgrep quickfix'
650 endif
651 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200652
653 " Jumping to a help topic should open the help window
654 only
655 Xnext
656 call assert_true(&buftype == 'help')
657 call assert_true(winnr('$') == 2)
658 " Jumping to the next match should reuse the help window
659 Xnext
660 call assert_true(&buftype == 'help')
661 call assert_true(winnr() == 1)
662 call assert_true(winnr('$') == 2)
663 " Jumping to the next match from the quickfix window should reuse the help
664 " window
665 Xopen
666 Xnext
667 call assert_true(&buftype == 'help')
668 call assert_true(winnr() == 1)
669 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200670 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200671
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100672 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200673 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100674
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100675 " When the current window is vertically split, jumping to a help match
676 " should open the help window at the top.
677 only | enew
678 let w1 = win_getid()
679 vert new
680 let w2 = win_getid()
681 Xnext
682 let w3 = win_getid()
683 call assert_true(&buftype == 'help')
684 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100685 " See jump_to_help_window() for details
686 let w2_width = winwidth(w2)
687 if w2_width != &columns && w2_width < 80
688 call assert_equal(['col', [['leaf', w3],
689 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
690 else
691 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
692 \ ['leaf', w1]]] , winlayout())
693 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100694
695 new | only
696 set buftype=help
697 set modified
698 call assert_fails('Xnext', 'E37:')
699 set nomodified
700 new | only
701
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200702 if a:cchar == 'l'
703 " When a help window is present, running :lhelpgrep should reuse the
704 " help window and not the current window
705 new | only
706 call g:Xsetlist([], 'f')
707 help index.txt
708 wincmd w
709 lhelpgrep quickfix
710 call assert_equal(1, winnr())
711 call assert_notequal([], getloclist(1))
712 call assert_equal([], getloclist(2))
713 endif
714
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200715 new | only
716
Bram Moolenaaree85df32017-03-19 14:19:50 +0100717 " Search for non existing help string
718 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200719 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200720 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100721endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200722
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100723func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200724 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200725 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200726 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100727endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100728
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100729def Test_helpgrep_vim9_restore_cpo()
730 assert_equal('aABceFs', &cpo)
731
732 var rtp_save = &rtp
733 var dir = 'Xruntime/after'
734 &rtp ..= ',' .. dir
735 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100736 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100737 filetype plugin on
738 silent helpgrep grail
739 cwindow
740 silent helpgrep grail
741
742 assert_equal('aABceFs', &cpo)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000743 delete('Xruntime', 'rf')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100744 &rtp = rtp_save
745 cclose
746 helpclose
747enddef
748
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +0000749" When running the :helpgrep command, if an autocmd modifies the 'cpoptions'
750" value, then Vim crashes. (issue fixed by 7.2b-004 and 8.2.4453)
Bram Moolenaar4791fcd2022-02-23 12:06:00 +0000751func Test_helpgrep_restore_cpo_aucmd()
752 let save_cpo = &cpo
753 augroup QF_Test
754 au!
755 autocmd BufNew * set cpo=acd
756 augroup END
757
758 helpgrep quickfix
759 call assert_equal('acd', &cpo)
760 %bw!
761
762 set cpo&vim
763 augroup QF_Test
764 au!
765 autocmd BufReadPost * set cpo=
766 augroup END
767
768 helpgrep buffer
769 call assert_equal('', &cpo)
770
771 augroup QF_Test
772 au!
773 augroup END
774 %bw!
775 let &cpo = save_cpo
776endfunc
777
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200778def Test_vim9_cexpr()
779 var text = 'somefile:95:error'
780 cexpr text
781 var l = getqflist()
782 assert_equal(1, l->len())
783 assert_equal(95, l[0].lnum)
784 assert_equal('error', l[0].text)
785
786 text = 'somefile:77:warning'
787 caddexpr text
788 l = getqflist()
789 assert_equal(2, l->len())
790 assert_equal(77, l[1].lnum)
791 assert_equal('warning', l[1].text)
792enddef
793
Bram Moolenaar6920c722016-01-22 22:44:10 +0100794func Test_errortitle()
795 augroup QfBufWinEnter
796 au!
797 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
798 augroup END
799 copen
800 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'')'}]
801 call setqflist(a)
802 call assert_equal(':setqflist()', g:a)
803 augroup QfBufWinEnter
804 au!
805 augroup END
806 augroup! QfBufWinEnter
807endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100808
Bram Moolenaar5584df62016-03-18 21:00:51 +0100809func Test_vimgreptitle()
810 augroup QfBufWinEnter
811 au!
812 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
813 augroup END
814 try
815 vimgrep /pattern/j file
816 catch /E480/
817 endtry
818 copen
819 call assert_equal(': vimgrep /pattern/j file', g:a)
820 augroup QfBufWinEnter
821 au!
822 augroup END
823 augroup! QfBufWinEnter
824endfunc
825
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100826func Test_bufwinenter_once()
827 augroup QfBufWinEnter
828 au!
829 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
830 augroup END
831 let g:got_afile = ''
832 copen
833 call assert_equal('got quickfix', g:got_afile)
834
835 cclose
836 unlet g:got_afile
837 augroup QfBufWinEnter
838 au!
839 augroup END
840 augroup! QfBufWinEnter
841endfunc
842
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100843func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200844 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100845
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200846 Xgetexpr ['file:1:1:message']
847 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100848 if a:cchar == 'c'
849 call setqflist(l, 'r')
850 else
851 call setloclist(0, l, 'r')
852 endif
853
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200854 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100855 if a:cchar == 'c'
856 let title = ':setqflist()'
857 else
858 let title = ':setloclist()'
859 endif
860 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200861 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100862endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100863
864" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100865func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200866 call XqfTitleTests('c')
867 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100868endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100869
870" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100871func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100872 let save_efm = &efm
873 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
874 cgetexpr ['WWWW', 'EEEE', 'CCCC']
875 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
876 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
877 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
878 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
879 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
880 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
881 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
882 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
883 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100884endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100885
886" This will test for problems in quickfix:
887" A. incorrectly copying location lists which caused the location list to show
888" a different name than the file that was actually being displayed.
889" B. not reusing the window for which the location list window is opened but
890" instead creating new windows.
891" C. make sure that the location list window is not reused instead of the
892" window it belongs to.
893"
894" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100895func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100896 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
897 let word = substitute(base, '\v(.*)\..*', '\1', '')
898
899 setl modifiable
900 setl noreadonly
901 setl noswapfile
902 setl bufhidden=delete
903 %del _
904 " For problem 2:
905 " 'buftype' has to be set to reproduce the constant opening of new windows
906 setl buftype=nofile
907
908 call setline(1, word)
909
910 setl nomodified
911 setl nomodifiable
912 setl readonly
913 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100914endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100915
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100916func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200917 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100918
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200919 augroup testgroup
920 au!
921 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
922 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100923
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200924 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100925
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200926 let qflist = []
927 for word in words
928 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
929 " NOTE: problem 1:
930 " intentionally not setting 'lnum' so that the quickfix entries are not
931 " valid
932 eval qflist->setloclist(0, ' ')
933 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100934
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200935 " Test A
936 lrewind
937 enew
938 lopen
939 4lnext
940 vert split
941 wincmd L
942 lopen
943 wincmd p
944 lnext
945 let fileName = expand("%")
946 wincmd p
947 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
948 let fileName = substitute(fileName, '\\', '/', 'g')
949 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
950 call assert_equal("test://bar.txt", fileName)
951 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100952
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200953 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100954
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200955 " Test B:
956 lrewind
957 lopen
958 2
959 exe "normal \<CR>"
960 wincmd p
961 3
962 exe "normal \<CR>"
963 wincmd p
964 4
965 exe "normal \<CR>"
966 call assert_equal(2, winnr('$'))
967 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100968
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200969 " Test C:
970 lrewind
971 lopen
972 " Let's move the location list window to the top to check whether it (the
973 " first window found) will be reused when we try to open new windows:
974 wincmd K
975 2
976 exe "normal \<CR>"
977 wincmd p
978 3
979 exe "normal \<CR>"
980 wincmd p
981 4
982 exe "normal \<CR>"
983 1wincmd w
984 call assert_equal('quickfix', &buftype)
985 2wincmd w
986 let bufferName = expand("%")
987 let bufferName = substitute(bufferName, '\\', '/', 'g')
988 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100989
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200990 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100991
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200992 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100993endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100994
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100995func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200996 augroup testgroup
997 au!
998 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
999 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +01001000
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001001 func! R(n)
1002 quit
1003 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001004
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001005 new
1006 let q = []
1007 call add(q, {'filename': 'test_curwin.txt' })
1008 call setloclist(0, q)
1009 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001010
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001011 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001012 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001013endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001014
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001015func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001016 call writefile(['loclistfoo'], 'loclistfoo')
1017 call writefile(['loclistbar'], 'loclistbar')
1018 set switchbuf=usetab
1019
1020 edit loclistfoo
1021 tabedit loclistbar
1022 silent lgrep loclistfoo loclist*
1023 call assert_equal(1, tabpagenr())
1024
1025 enew | only | tabonly
1026 set switchbuf&vim
1027 call delete('loclistfoo')
1028 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001029endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001030
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001031" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001032func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001033 " The 'errorformat' setting is different on non-Unix systems.
1034 " This test works only on Unix-like systems.
1035 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001036
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001037 let l =<< trim [DATA]
1038 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1039 "Xtestfile", line 6 col 19; this is an error
1040 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1041 Xtestfile:9: parse error before `asd'
1042 make: *** [vim] Error 1
1043 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001044
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001045 2 returned
1046 "Xtestfile", line 11 col 1; this is an error
1047 "Xtestfile", line 12 col 2; this is another error
1048 "Xtestfile", line 14:10; this is an error in column 10
1049 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1050 "Xtestfile", linenr 16: yet another problem
1051 Error in "Xtestfile" at line 17:
1052 x should be a dot
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1054 ^
1055 Error in "Xtestfile" at line 18:
1056 x should be a dot
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1058 .............^
1059 Error in "Xtestfile" at line 19:
1060 x should be a dot
1061 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1062 --------------^
1063 Error in "Xtestfile" at line 20:
1064 x should be a dot
1065 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1066 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001067
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001068 Does anyone know what is the problem and how to correction it?
1069 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1070 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1071 [DATA]
1072
1073 call writefile(l, 'Xerrorfile1')
1074 call writefile(l[:-2], 'Xerrorfile2')
1075
1076 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001077 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1078 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1079 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1080 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1081 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1082 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1083 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1084 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1085 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1086 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1087 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1088 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1089 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1090 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1091 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1092 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1093 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1094 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1095 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1096 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1097 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1098[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001099 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001100
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001101 let save_efm = &efm
1102 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1103 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001104
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001105 exe 'cf Xerrorfile2'
1106 clast
1107 copen
1108 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1109 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001110
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001111 exe 'cf Xerrorfile1'
1112 call assert_equal([4, 12], [line('.'), col('.')])
1113 cn
1114 call assert_equal([6, 19], [line('.'), col('.')])
1115 cn
1116 call assert_equal([9, 2], [line('.'), col('.')])
1117 cn
1118 call assert_equal([10, 2], [line('.'), col('.')])
1119 cn
1120 call assert_equal([11, 1], [line('.'), col('.')])
1121 cn
1122 call assert_equal([12, 2], [line('.'), col('.')])
1123 cn
1124 call assert_equal([14, 10], [line('.'), col('.')])
1125 cn
1126 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1127 cn
1128 call assert_equal([16, 2], [line('.'), col('.')])
1129 cn
1130 call assert_equal([17, 6], [line('.'), col('.')])
1131 cn
1132 call assert_equal([18, 7], [line('.'), col('.')])
1133 cn
1134 call assert_equal([19, 8], [line('.'), col('.')])
1135 cn
1136 call assert_equal([20, 9], [line('.'), col('.')])
1137 clast
1138 cprev
1139 cprev
1140 wincmd w
1141 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1142 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001143
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001144 let &efm = save_efm
1145 call delete('Xerrorfile1')
1146 call delete('Xerrorfile2')
1147 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001148endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001149
Bram Moolenaarab47c612016-06-14 22:02:26 +02001150" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001151func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001152 call s:setup_commands(a:cchar)
1153
Bram Moolenaarab47c612016-06-14 22:02:26 +02001154 let save_efm=&efm
1155 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1156
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001157 let lines = ["Entering dir 'dir1/a'",
1158 \ 'habits2.txt:1:Nine Healthy Habits',
1159 \ "Entering dir 'b'",
1160 \ 'habits3.txt:2:0 Hours of television',
1161 \ 'habits2.txt:7:5 Small meals',
1162 \ "Entering dir 'dir1/c'",
1163 \ 'habits4.txt:3:1 Hour of exercise',
1164 \ "Leaving dir 'dir1/c'",
1165 \ "Leaving dir 'dir1/a'",
1166 \ 'habits1.txt:4:2 Liters of water',
1167 \ "Entering dir 'dir2'",
1168 \ 'habits5.txt:5:3 Cups of hot green tea',
1169 \ "Leaving dir 'dir2'"
1170 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001171
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001172 Xexpr ""
1173 for l in lines
1174 Xaddexpr l
1175 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001176
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001177 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001178
1179 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1180 call assert_equal(1, qf[1].lnum)
1181 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1182 call assert_equal(2, qf[3].lnum)
1183 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1184 call assert_equal(7, qf[4].lnum)
1185 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1186 call assert_equal(3, qf[6].lnum)
1187 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1188 call assert_equal(4, qf[9].lnum)
1189 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1190 call assert_equal(5, qf[11].lnum)
1191
1192 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001193endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001194
1195" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001196func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001197 " Create the directory stack and files
1198 call mkdir('dir1')
1199 call mkdir('dir1/a')
1200 call mkdir('dir1/a/b')
1201 call mkdir('dir1/c')
1202 call mkdir('dir2')
1203
1204 let lines = ["Nine Healthy Habits",
1205 \ "0 Hours of television",
1206 \ "1 Hour of exercise",
1207 \ "2 Liters of water",
1208 \ "3 Cups of hot green tea",
1209 \ "4 Short mental breaks",
1210 \ "5 Small meals",
1211 \ "6 AM wake up time",
1212 \ "7 Minutes of laughter",
1213 \ "8 Hours of sleep (at least)",
1214 \ "9 PM end of the day and off to bed"
1215 \ ]
1216 call writefile(lines, 'habits1.txt')
1217 call writefile(lines, 'dir1/a/habits2.txt')
1218 call writefile(lines, 'dir1/a/b/habits3.txt')
1219 call writefile(lines, 'dir1/c/habits4.txt')
1220 call writefile(lines, 'dir2/habits5.txt')
1221
1222 call s:dir_stack_tests('c')
1223 call s:dir_stack_tests('l')
1224
1225 call delete('dir1', 'rf')
1226 call delete('dir2', 'rf')
1227 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001228endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001229
Bram Moolenaar9b457942016-10-09 16:10:05 +02001230" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001231func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001232 call s:setup_commands(a:cchar)
1233
1234 let save_efm = &efm
1235
1236 let &efm =
1237 \ '%Eerror %m %l,' .
1238 \ '%-Wignored %m %l,' .
1239 \ '%+Cmore ignored %m %l,' .
1240 \ '%Zignored end'
1241 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1242 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1243 call assert_equal([['resync', 1, 4, 'E']], l)
1244
1245 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001246endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001247
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001248func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001249 call Xefm_ignore_continuations('c')
1250 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001251endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001252
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001253" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001254func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001255 call s:setup_commands(a:cchar)
1256
Bram Moolenaar049cba92016-06-26 14:38:04 +02001257 let save_efm = &efm
1258
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001259 set efm=%f:%l:%m,%f:%f:%l:%m
1260 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1261
1262 set efm=%f:%l:%m,%f:%l:%r:%m
1263 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1264
1265 set efm=%f:%l:%m,%O:%f:%l:%m
1266 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1267
1268 set efm=%f:%l:%m,%f:%l:%*[^a-z
1269 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1270
1271 set efm=%f:%l:%m,%f:%l:%*c
1272 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1273
1274 set efm=%f:%l:%m,%L%M%N
1275 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1276
1277 set efm=%f:%l:%m,%f:%l:%m:%R
1278 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1279
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001280 " Invalid regular expression
1281 set efm=%\\%%k
1282 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1283
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001284 set efm=
1285 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1286
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001287 " Empty directory name. When there is an error in parsing new entries, make
1288 " sure the previous quickfix list is made the current list.
1289 set efm&
1290 cexpr ["one", "two"]
1291 let qf_id = getqflist(#{id: 0}).id
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001292 set efm=%DEntering\ dir\ abc,%f:%l:%m
1293 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001294 call assert_equal(qf_id, getqflist(#{id: 0}).id)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001295
1296 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001297endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001298
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001299func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001300 call Xinvalid_efm_Tests('c')
1301 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001302endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001303
1304" TODO:
1305" Add tests for the following formats in 'errorformat'
1306" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001307func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001308 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001309
1310 " Test for %s format in efm
1311 set efm=%f:%s
1312 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001313 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001314 call assert_equal('^\VLine search text\$', l[0].pattern)
1315 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001316
Bram Moolenaaree85df32017-03-19 14:19:50 +01001317 let l = split(execute('clist', ''), "\n")
1318 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1319
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001320 " Test for a long line
1321 cexpr 'Xtestfile:' . repeat('a', 1026)
1322 let l = getqflist()
1323 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1324
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001325 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001326 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001327 [Xtestfile1]
1328 (1,17) error: ';' missing
1329 (21,2) warning: variable 'z' not defined
1330 (67,3) error: end of file found before string ended
1331 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001332
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001333 [Xtestfile2]
1334 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001335
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001336 [Xtestfile3]
1337 NEW compiler v1.1
1338 (2,2) warning: variable 'x' not defined
1339 (67,3) warning: 's' already defined
1340 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001341 [DATA]
1342
Bram Moolenaaree85df32017-03-19 14:19:50 +01001343 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001344 " To exercise the push/pop file functionality in quickfix, the test files
1345 " need to be created.
1346 call writefile(['Line1'], 'Xtestfile1')
1347 call writefile(['Line2'], 'Xtestfile2')
1348 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001349 cexpr ""
1350 for l in lines
1351 caddexpr l
1352 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001353 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001354 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001355 call assert_equal(21, l[2].lnum)
1356 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001357 call assert_equal('w', l[2].type)
1358 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001359 call delete('Xtestfile1')
1360 call delete('Xtestfile2')
1361 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001362
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001363 " Test for %P, %Q with non-existing files
1364 cexpr lines
1365 let l = getqflist()
1366 call assert_equal(14, len(l))
1367 call assert_equal('[Xtestfile1]', l[0].text)
1368 call assert_equal('[Xtestfile2]', l[6].text)
1369 call assert_equal('[Xtestfile3]', l[9].text)
1370
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001371 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001372 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001373 Error 275
1374 line 42
1375 column 3
1376 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001377 [DATA]
1378
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001379 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1380 cgetexpr lines
1381 let l = getqflist()
1382 call assert_equal(275, l[0].nr)
1383 call assert_equal(42, l[0].lnum)
1384 call assert_equal(3, l[0].col)
1385 call assert_equal('E', l[0].type)
1386 call assert_equal("\n' ' expected after '--'", l[0].text)
1387
1388 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001389 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001390 Error in line 147 of foo.c:
1391 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001392 [DATA]
1393
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001394 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1395 cgetexpr lines
1396 let l = getqflist()
1397 call assert_equal(147, l[0].lnum)
1398 call assert_equal('E', l[0].type)
1399 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001400
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001401 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001402 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001403 ==============================================================
1404 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1405 --------------------------------------------------------------
1406 Traceback (most recent call last):
1407 File "unittests/dbfacadeTest.py", line 89, in testFoo
1408 self.assertEquals(34, dtid)
1409 File "/usr/lib/python2.2/unittest.py", line 286, in
1410 failUnlessEqual
1411 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001412 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001413
1414 --------------------------------------------------------------
1415 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001416 [DATA]
1417
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001418 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001419 cgetexpr lines
1420 let l = getqflist()
1421 call assert_equal(8, len(l))
1422 call assert_equal(89, l[4].lnum)
1423 call assert_equal(1, l[4].valid)
1424 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001425 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001426
Bram Moolenaard76ce852018-05-01 15:02:04 +02001427 " Test for %o
1428 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001429 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1430 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001431 let l = getqflist()
1432 call assert_equal(1, len(l), string(l))
1433 call assert_equal('Language.PureScript.Types', l[0].module)
1434 copen
1435 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1436 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001437 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001438 cclose
1439 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001440 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001441
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001442 " Test for a long module name
1443 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1444 let l = getqflist()
1445 call assert_equal(repeat('m', 1024), l[0].module)
1446 call assert_equal(15, l[0].lnum)
1447 call assert_equal('message', l[0].text)
1448
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001449 " The following sequence of commands used to crash Vim
1450 set efm=%W%m
1451 cgetexpr ['msg1']
1452 let l = getqflist()
1453 call assert_equal(1, len(l), string(l))
1454 call assert_equal('msg1', l[0].text)
1455 set efm=%C%m
1456 lexpr 'msg2'
1457 let l = getloclist(0)
1458 call assert_equal(1, len(l), string(l))
1459 call assert_equal('msg2', l[0].text)
1460 lopen
1461 call setqflist([], 'r')
1462 caddbuf
1463 let l = getqflist()
1464 call assert_equal(1, len(l), string(l))
1465 call assert_equal('|| msg2', l[0].text)
1466
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001467 " When matching error lines, case should be ignored. Test for this.
1468 set noignorecase
1469 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1470 call assert_equal(10, l.items[0].lnum)
1471 call assert_equal('Line 20', l.items[0].text)
1472 set ignorecase&
1473
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001474 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001475 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001476endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001477
Bram Moolenaare9283662020-06-07 14:10:47 +02001478" Test for '%t' (error type) field in 'efm'
1479func Test_efm_error_type()
1480 let save_efm = &efm
1481
1482 " error type
1483 set efm=%f:%l:%t:%m
1484 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1485 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1486 let output = split(execute('clist'), "\n")
1487 call assert_equal([
1488 \ ' 1 Xfile1:10 error: msg1',
1489 \ ' 2 Xfile1:20 warning: msg2',
1490 \ ' 3 Xfile1:30 info: msg3',
1491 \ ' 4 Xfile1:40 note: msg4',
1492 \ ' 5 Xfile1:50 R: msg5'], output)
1493
1494 " error type and a error number
1495 set efm=%f:%l:%t:%n:%m
1496 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1497 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1498 let output = split(execute('clist'), "\n")
1499 call assert_equal([
1500 \ ' 1 Xfile1:10 error 2: msg1',
1501 \ ' 2 Xfile1:20 warning 4: msg2',
1502 \ ' 3 Xfile1:30 info 6: msg3',
1503 \ ' 4 Xfile1:40 note 8: msg4',
1504 \ ' 5 Xfile1:50 R 3: msg5'], output)
1505 let &efm = save_efm
1506endfunc
1507
haya14busae023d492022-02-08 18:09:29 +00001508" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1509func Test_efm_end_lnum_col()
1510 let save_efm = &efm
1511
1512 " single line
1513 set efm=%f:%l-%e:%c-%k:%t:%m
1514 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1515 let output = split(execute('clist'), "\n")
1516 call assert_equal([
1517 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1518 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1519
1520 " multiple lines
1521 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
1522 cexpr ["1)msg1", "Xfile1:14-24:1-2",
1523 \ "2)msg2", "Xfile1:24-34:3-4"]
1524 let output = split(execute('clist'), "\n")
1525 call assert_equal([
1526 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1527 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1528 let &efm = save_efm
1529endfunc
1530
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001531func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001532 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001533 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001534 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001535 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001536 colder
1537 cgetexpr []
1538 endfunc
1539 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001540 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001541 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001542 lolder
1543 lgetexpr []
1544 endfunc
1545 endif
1546
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001547 augroup QF_Test
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001548 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001549 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001550 augroup END
1551
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001552 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001553 let words = [ "a", "b" ]
1554 let qflist = []
1555 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001556 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001557 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001558 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001560
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001561 augroup QF_Test
1562 au!
1563 augroup END
1564
1565 if a:cchar == 'c'
1566 cexpr ["Xtest1:1:Line"]
1567 cwindow
1568 only
1569 augroup QF_Test
1570 au!
1571 autocmd WinEnter * call setqflist([], 'f')
1572 augroup END
1573 call assert_fails('exe "normal \<CR>"', 'E925:')
1574 augroup QF_Test
1575 au!
1576 augroup END
1577 endif
1578 %bw!
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001579endfunc
1580
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001581func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001582 call XquickfixChangedByAutocmd('c')
1583 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001584endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001585
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001586func Test_setloclist_in_autocommand()
1587 call writefile(['test1', 'test2'], 'Xfile')
1588 edit Xfile
1589 let s:bufnr = bufnr()
1590 call setloclist(1,
1591 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1592 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1593
1594 augroup Test_LocList
1595 au!
1596 autocmd BufEnter * call setloclist(1,
1597 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1598 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1599 augroup END
1600
1601 lopen
1602 call assert_fails('exe "normal j\<CR>"', 'E926:')
1603
1604 augroup Test_LocList
1605 au!
1606 augroup END
1607 call delete('Xfile')
1608endfunc
1609
Bram Moolenaar8b201792016-03-25 15:01:10 +01001610func Test_caddbuffer_to_empty()
1611 helpgr quickfix
1612 call setqflist([], 'r')
1613 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001614 try
1615 cn
1616 catch
1617 " number of matches is unknown
1618 call assert_true(v:exception =~ 'E553:')
1619 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001620 quit!
1621endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001622
1623func Test_cgetexpr_works()
1624 " this must not crash Vim
1625 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001626 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001627endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001628
1629" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001630func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001631 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001632
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001633 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001634 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001635 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001636 call assert_equal(2, len(l))
1637 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001638 call assert_equal(3, l[1].end_lnum)
1639 call assert_equal(4, l[1].col)
1640 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001641
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001642 Xnext
1643 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1644 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001645 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001646 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001647 call assert_equal(3, line('.'))
1648
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001649 " Appending entries to the list should not change the cursor position
1650 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001651 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001652 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001654 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1655 call assert_equal(1, line('.'))
1656 close
1657
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001658 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001659 \ {'bufnr': a:bnum, 'lnum': 4},
1660 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001661 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001662 call assert_equal(3, len(l))
1663 call assert_equal(5, l[2].lnum)
1664
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001665 call g:Xsetlist([])
1666 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001667 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001668
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001669 " Tests for setting the 'valid' flag
1670 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1671 Xwindow
1672 call assert_equal(1, winnr('$'))
1673 let l = g:Xgetlist()
1674 call g:Xsetlist(l)
1675 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001676 " Adding a non-valid entry should not mark the list as having valid entries
1677 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1678 Xwindow
1679 call assert_equal(1, winnr('$'))
1680
1681 " :cnext/:cprev should still work even with invalid entries in the list
1682 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1683 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1684 call g:Xsetlist(l)
1685 Xnext
1686 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1687 Xprev
1688 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1689 " :cnext/:cprev should still work after appending invalid entries to an
1690 " empty list
1691 call g:Xsetlist([])
1692 call g:Xsetlist(l, 'a')
1693 Xnext
1694 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1695 Xprev
1696 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1697
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001698 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1699 Xwindow
1700 call assert_equal(2, winnr('$'))
1701 Xclose
1702 let save_efm = &efm
1703 set efm=%m
1704 Xgetexpr 'TestMessage'
1705 let l = g:Xgetlist()
1706 call g:Xsetlist(l)
1707 call assert_equal(1, g:Xgetlist()[0].valid)
1708 let &efm = save_efm
1709
Bram Moolenaaree85df32017-03-19 14:19:50 +01001710 " Error cases:
1711 " Refer to a non-existing buffer and pass a non-dictionary type
1712 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1713 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1714 call g:Xsetlist([[1, 2,3]])
1715 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001716 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00001717 call g:Xsetlist([test_null_dict()])
1718 call assert_equal([], g:Xgetlist())
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001719endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001720
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001721func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001722 new Xtestfile | only
1723 let bnum = bufnr('%')
1724 call setline(1, range(1,5))
1725
1726 call SetXlistTests('c', bnum)
1727 call SetXlistTests('l', bnum)
1728
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001729 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001730 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001731endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001732
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001733func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001734 call s:setup_commands(a:cchar)
1735
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001736 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001737 let @/ = 'Test_'
1738 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001740 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001741 Xvimgrep empty test_quickfix.vim
1742 call assert_true(len(g:Xgetlist()) > 0)
1743 Xvimgrep matches test_quickfix.vim
1744 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001745 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001746 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001747 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001748 call g:Xsetlist([], 'r')
1749 call assert_true(len(g:Xgetlist()) == 0)
1750 Xolder
1751 call assert_equal(testlen, len(g:Xgetlist()))
1752 Xnewer
1753 Xnewer
1754 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001755endfunc
1756
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001758 call Xlist_empty_middle('c')
1759 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001760endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001761
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001762func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001763 call s:setup_commands(a:cchar)
1764
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001765 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001766 Xvimgrep one test_quickfix.vim
1767 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001768 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001769 Xvimgrep two test_quickfix.vim
1770 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001771 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001772 Xvimgrep three test_quickfix.vim
1773 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001774 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001775 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001776 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001777 call g:Xsetlist([], 'r')
1778 call assert_true(len(g:Xgetlist()) == 0)
1779 Xnewer
1780 call assert_equal(twolen, len(g:Xgetlist()))
1781 Xnewer
1782 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001783endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001784
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001785func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001786 call Xlist_empty_older('c')
1787 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001788endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001789
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001790func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001791 call s:setup_commands(a:cchar)
1792
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001793 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1794 \ {'filename': 'fnameB', 'text': 'B'}]
1795 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1796 \ {'filename': 'fnameD', 'text': 'D'},
1797 \ {'filename': 'fnameE', 'text': 'E'}]
1798
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001799 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001800 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001801 silent! Xnewer 99
1802 call g:Xsetlist(list1)
1803 call g:Xsetlist(list2)
1804 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001805 call assert_equal(3, len(li))
1806 call assert_equal('C', li[0]['text'])
1807 call assert_equal('D', li[1]['text'])
1808 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001809 silent! Xolder
1810 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001811 call assert_equal(2, len(li))
1812 call assert_equal('A', li[0]['text'])
1813 call assert_equal('B', li[1]['text'])
1814
1815 " {action} is specified ' '.
1816 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001817 silent! Xnewer 99
1818 call g:Xsetlist(list1)
1819 call g:Xsetlist(list2, ' ')
1820 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001821 call assert_equal(3, len(li))
1822 call assert_equal('C', li[0]['text'])
1823 call assert_equal('D', li[1]['text'])
1824 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001825 silent! Xolder
1826 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001827 call assert_equal(2, len(li))
1828 call assert_equal('A', li[0]['text'])
1829 call assert_equal('B', li[1]['text'])
1830
1831 " {action} is specified 'a'.
1832 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 silent! Xnewer 99
1834 call g:Xsetlist(list1)
1835 call g:Xsetlist(list2, 'a')
1836 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001837 call assert_equal(5, len(li))
1838 call assert_equal('A', li[0]['text'])
1839 call assert_equal('B', li[1]['text'])
1840 call assert_equal('C', li[2]['text'])
1841 call assert_equal('D', li[3]['text'])
1842 call assert_equal('E', li[4]['text'])
1843
1844 " {action} is specified 'r'.
1845 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001846 silent! Xnewer 99
1847 call g:Xsetlist(list1)
1848 call g:Xsetlist(list2, 'r')
1849 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001850 call assert_equal(3, len(li))
1851 call assert_equal('C', li[0]['text'])
1852 call assert_equal('D', li[1]['text'])
1853 call assert_equal('E', li[2]['text'])
1854
1855 " Test for wrong value.
1856 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001857 call assert_fails("call g:Xsetlist(0)", 'E714:')
1858 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1859 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1860 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1861 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001862endfunc
1863
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001864func Test_setqflist_invalid_nr()
1865 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001866 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001867endfunc
1868
Bram Moolenaar99234f22020-02-10 22:56:54 +01001869func Test_setqflist_user_sets_buftype()
1870 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1871 set buftype=quickfix
1872 call setqflist([], 'a')
1873 enew
1874endfunc
1875
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001876func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001877 call XquickfixSetListWithAct('c')
1878 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001879endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001880
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001881func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001882 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001883
Bram Moolenaar049cba92016-06-26 14:38:04 +02001884 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001885 call assert_equal(1, l[0].lnum)
1886 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001887 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001888 call assert_equal(2, l[1].lnum)
1889 call assert_equal(1, l[1].col)
1890 call assert_equal(4070, len(l[1].text))
1891 call assert_equal(3, l[2].lnum)
1892 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001893 call assert_equal(4070, len(l[2].text))
1894 call assert_equal(4, l[3].lnum)
1895 call assert_equal(1, l[3].col)
1896 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001897
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001898 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001899endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001900
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001901func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001902 call s:setup_commands(a:cchar)
1903
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001904 let testfile = 'samples/quickfix.txt'
1905
1906 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001907 exe 'Xgetfile' testfile
1908 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001909
1910 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001911 Xexpr readfile(testfile)
1912 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001913
1914 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001915 Xexpr join(readfile(testfile), "\n")
1916 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001917
1918 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001919 exe 'edit' testfile
1920 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001921 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001922endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001923
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001924func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001925 call s:long_lines_tests('c')
1926 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001927endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001928
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001929func Test_cgetfile_on_long_lines()
1930 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1931 " are read at a time.
1932 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1933 let lines = [
1934 \ '/tmp/file1:1:1:aaa',
1935 \ '/tmp/file2:1:1:%s',
1936 \ '/tmp/file3:1:1:bbb',
1937 \ '/tmp/file4:1:1:ccc',
1938 \ ]
1939 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1940 call writefile(lines, 'Xcqetfile.txt')
1941 cgetfile Xcqetfile.txt
1942 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1943 endfor
1944 call delete('Xcqetfile.txt')
1945endfunc
1946
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001947func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001948 let l = []
1949 for i in range(1, 20)
1950 call add(l, 'Line' . i)
1951 endfor
1952 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001953endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001954
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001955func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001956 call s:create_test_file('Xqftestfile1')
1957 call s:create_test_file('Xqftestfile2')
1958 call s:create_test_file('Xqftestfile3')
1959
1960 new | only
1961 edit Xqftestfile1
1962 let file1_winid = win_getid()
1963 new Xqftestfile2
1964 let file2_winid = win_getid()
1965 cgetexpr ['Xqftestfile1:5:Line5',
1966 \ 'Xqftestfile1:6:Line6',
1967 \ 'Xqftestfile2:10:Line10',
1968 \ 'Xqftestfile2:11:Line11',
1969 \ 'Xqftestfile3:15:Line15',
1970 \ 'Xqftestfile3:16:Line16']
1971
1972 new
1973 let winid = win_getid()
1974 cfirst | cnext
1975 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001976 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001977 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001978 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001979 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001980
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001981 " Test for 'switchbuf' set to search for files in windows in the current
1982 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001983 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001984 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001985 cfirst | cnext
1986 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001987 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001988 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001989 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001990 call assert_equal(file2_winid, win_getid())
1991
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001992 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1993 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001994 enew | only
1995 set switchbuf=usetab
1996 tabedit Xqftestfile1
1997 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001998 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001999 tabfirst
2000 cfirst | cnext
2001 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02002002 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02002003 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01002004 6cnext
2005 call assert_equal(4, tabpagenr())
2006 2cpfile
2007 call assert_equal(2, tabpagenr())
2008 2cnfile
2009 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02002010 tabfirst | tabonly | enew
2011
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002012 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002013 set switchbuf=split
2014 cfirst | cnext
2015 call assert_equal(1, winnr('$'))
2016 cnext | cnext
2017 call assert_equal(2, winnr('$'))
2018 cnext | cnext
2019 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02002020
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002021 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02002022 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002023 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002024 cfirst | cnext
2025 call assert_equal(1, tabpagenr('$'))
2026 cnext | cnext
2027 call assert_equal(2, tabpagenr('$'))
2028 cnext | cnext
2029 call assert_equal(3, tabpagenr('$'))
2030 tabfirst | enew | tabonly | only
2031
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002032 set switchbuf=uselast
2033 split
2034 let last_winid = win_getid()
2035 copen
2036 exe "normal 1G\<CR>"
2037 call assert_equal(last_winid, win_getid())
2038 enew | only
2039
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002040 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2041 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002042 set switchbuf=
2043 edit Xqftestfile1
2044 let file1_winid = win_getid()
2045 new Xqftestfile2
2046 let file2_winid = win_getid()
2047 copen
2048 exe "normal 1G\<CR>"
2049 call assert_equal(file1_winid, win_getid())
2050 copen
2051 exe "normal 3G\<CR>"
2052 call assert_equal(file2_winid, win_getid())
2053 copen | only
2054 exe "normal 5G\<CR>"
2055 call assert_equal(2, winnr('$'))
2056 call assert_equal(1, bufwinnr('Xqftestfile3'))
2057
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002058 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002059 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002060 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002061 set switchbuf=usetab
2062 tabedit Xqftestfile1
2063 tabedit Xqftestfile2
2064 tabedit Xqftestfile3
2065 tabfirst
2066 copen | only
2067 clast
2068 call assert_equal(4, tabpagenr())
2069 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002070
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002071 " Jumping to a file that is not present in any of the tabpages and the
2072 " current tabpage doesn't have any usable windows, should open it in a new
2073 " window in the current tabpage.
2074 copen | only
2075 cfirst
2076 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002077 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002078
2079 " If opening a file changes 'switchbuf', then the new value should be
2080 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002081 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002082 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
2083 enew | only
2084 set switchbuf&vim
2085 cexpr "Xqftestfile1:1:10"
2086 call assert_equal('split', &switchbuf)
2087 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2088 enew | only
2089 set switchbuf=useopen
2090 cexpr "Xqftestfile1:1:10"
2091 call assert_equal('usetab', &switchbuf)
2092 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2093 enew | only
2094 set switchbuf=useopen
2095 cexpr "Xqftestfile1:1:10"
2096 call assert_equal('', &switchbuf)
2097
Bram Moolenaar049cba92016-06-26 14:38:04 +02002098 call delete('Xqftestfile1')
2099 call delete('Xqftestfile2')
2100 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002101 set switchbuf&vim
2102
2103 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002104endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002105
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002106func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002107 call s:setup_commands(a:cchar)
2108
2109 enew | only
2110
Bram Moolenaarc1542742016-07-20 21:44:37 +02002111 let fname = 'Xqftestfile' . a:cchar
2112 call s:create_test_file(fname)
2113 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002114
Bram Moolenaarc1542742016-07-20 21:44:37 +02002115 Xgetexpr [fname . ':5:Line5',
2116 \ fname . ':10:Line10',
2117 \ fname . ':15:Line15',
2118 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002119
2120 6,14delete
2121 call append(6, ['Buffer', 'Window'])
2122
2123 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002124 call assert_equal(5, l[0].lnum)
2125 call assert_equal(6, l[2].lnum)
2126 call assert_equal(13, l[3].lnum)
2127
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002128 " If a file doesn't have any quickfix entries, then deleting lines in the
2129 " file should not update the quickfix list
2130 call g:Xsetlist([], 'f')
2131 1,2delete
2132 call assert_equal([], g:Xgetlist())
2133
Bram Moolenaar049cba92016-06-26 14:38:04 +02002134 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002135 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002136endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002137
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002138func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002139 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002140 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002141 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002142 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002143endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002144
2145" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002146func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002147 call s:setup_commands(a:cchar)
2148
2149 " The following lines are used for the grep test. Don't remove.
2150 " Grep_Test_Text: Match 1
2151 " Grep_Test_Text: Match 2
2152 " GrepAdd_Test_Text: Match 1
2153 " GrepAdd_Test_Text: Match 2
2154 enew! | only
2155 set makeef&vim
2156 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002157 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002158 Xopen
2159 call assert_true(w:quickfix_title =~ '^:grep')
2160 Xclose
2161 enew
2162 set makeef=Temp_File_##
2163 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002164 call assert_true(len(g:Xgetlist()) == 9)
2165
2166 " Try with 'grepprg' set to 'internal'
2167 set grepprg=internal
2168 silent Xgrep Grep_Test_Text: test_quickfix.vim
2169 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2170 call assert_true(len(g:Xgetlist()) == 9)
2171 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002172
2173 call writefile(['Vim'], 'XtestTempFile')
2174 set makeef=XtestTempFile
2175 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002176 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002177 call assert_false(filereadable('XtestTempFile'))
2178 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002179endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002180
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002181func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002182 " The grepprg may not be set on non-Unix systems
2183 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002184
2185 call s:test_xgrep('c')
2186 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002187endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002188
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002189func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002190 " Use one 'errorformat' for two windows. Add an expression to each of them,
2191 " make sure they each keep their own state.
2192 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2193 call mkdir('Xone/a', 'p')
2194 call mkdir('Xtwo/a', 'p')
2195 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2196 call writefile(lines, 'Xone/a/one.txt')
2197 call writefile(lines, 'Xtwo/a/two.txt')
2198
2199 new one
2200 let one_id = win_getid()
2201 lexpr ""
2202 new two
2203 let two_id = win_getid()
2204 lexpr ""
2205
2206 laddexpr "Entering dir 'Xtwo/a'"
2207 call win_gotoid(one_id)
2208 laddexpr "Entering dir 'Xone/a'"
2209 call win_gotoid(two_id)
2210 laddexpr 'two.txt:5:two two two'
2211 call win_gotoid(one_id)
2212 laddexpr 'one.txt:3:one one one'
2213
2214 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002215 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2216 call assert_equal(3, loc_one[1].lnum)
2217
2218 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002219 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2220 call assert_equal(5, loc_two[1].lnum)
2221
2222 call win_gotoid(one_id)
2223 bwipe!
2224 call win_gotoid(two_id)
2225 bwipe!
2226 call delete('Xone', 'rf')
2227 call delete('Xtwo', 'rf')
2228endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002229
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002230func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002231 call s:setup_commands(a:cchar)
2232
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002233 " Calling lbottom without any errors should fail
2234 if a:cchar == 'l'
2235 call assert_fails('lbottom', 'E776:')
2236 endif
2237
Bram Moolenaar875feea2017-06-11 16:07:51 +02002238 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002239 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002240 let wid = win_getid()
2241 call assert_equal(1, line('.'))
2242 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002243 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002244 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002245 call win_gotoid(wid)
2246 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002247 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002248endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002249
2250" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002251func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002252 call XbottomTests('c')
2253 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002254endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002255
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002256func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002257 call s:setup_commands(a:cchar)
2258
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002259 " clear all lists after the first one, then replace the first one.
2260 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002261 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002262 let entry = {'filename': 'foo', 'lnum': 42}
2263 call g:Xsetlist([entry], 'r')
2264 call g:Xsetlist([entry, entry])
2265 call g:Xsetlist([entry, entry, entry])
2266 let res = split(execute(a:cchar . 'hist'), "\n")
2267 call assert_equal(3, len(res))
2268 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2269 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2270 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2271 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002272
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002273 " Test for changing the quickfix lists
2274 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2275 exe '1' . a:cchar . 'hist'
2276 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2277 exe '3' . a:cchar . 'hist'
2278 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2279 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2280 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2281
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002282 call g:Xsetlist([], 'f')
2283 let l = split(execute(a:cchar . 'hist'), "\n")
2284 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002285 if a:cchar == 'c'
2286 call assert_fails('4chist', 'E16:')
2287 else
2288 call assert_fails('4lhist', 'E776:')
2289 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002290
2291 " An empty list should still show the stack history
2292 call g:Xsetlist([])
2293 let res = split(execute(a:cchar . 'hist'), "\n")
2294 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2295
2296 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002297endfunc
2298
2299func Test_history()
2300 call HistoryTest('c')
2301 call HistoryTest('l')
2302endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002303
2304func Test_duplicate_buf()
2305 " make sure we can get the highest buffer number
2306 edit DoesNotExist
2307 edit DoesNotExist2
2308 let last_buffer = bufnr("$")
2309
2310 " make sure only one buffer is created
2311 call writefile(['this one', 'that one'], 'Xgrepthis')
2312 vimgrep one Xgrepthis
2313 vimgrep one Xgrepthis
2314 call assert_equal(last_buffer + 1, bufnr("$"))
2315
2316 call delete('Xgrepthis')
2317endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002318
2319" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002320func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002321 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002322
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002323 " Error cases
2324 call assert_fails('call g:Xgetlist(99)', 'E715:')
2325 call assert_fails('call g:Xsetlist(99)', 'E714:')
2326 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002327
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002328 " Set and get the title
2329 call g:Xsetlist([])
2330 Xopen
2331 wincmd p
2332 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2333 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2334 call assert_equal(0, s)
2335 let d = g:Xgetlist({"title":1})
2336 call assert_equal('Sample', d.title)
2337 " Try setting title to a non-string value
2338 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2339 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2340
2341 Xopen
2342 call assert_equal('Sample', w:quickfix_title)
2343 Xclose
2344
2345 " Tests for action argument
2346 silent! Xolder 999
2347 let qfnr = g:Xgetlist({'all':1}).nr
2348 call g:Xsetlist([], 'r', {'title' : 'N1'})
2349 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2350 call g:Xsetlist([], ' ', {'title' : 'N2'})
2351 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2352
2353 let res = g:Xgetlist({'nr': 0})
2354 call assert_equal(qfnr + 1, res.nr)
2355 call assert_equal(['nr'], keys(res))
2356
2357 call g:Xsetlist([], ' ', {'title' : 'N3'})
2358 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2359
2360 " Changing the title of an earlier quickfix list
2361 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2362 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2363
2364 " Changing the title of an invalid quickfix list
2365 call assert_equal(-1, g:Xsetlist([], ' ',
2366 \ {'title' : 'SomeTitle', 'nr' : 99}))
2367 call assert_equal(-1, g:Xsetlist([], ' ',
2368 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2369
2370 if a:cchar == 'c'
2371 copen
2372 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2373 cclose
2374 endif
2375
2376 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002377 call assert_fails('call g:Xgetlist([])', 'E715:')
2378 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002379 let s = g:Xsetlist([], 'a', {'abc':1})
2380 call assert_equal(-1, s)
2381
2382 call assert_equal({}, g:Xgetlist({'abc':1}))
2383 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2384 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2385
2386 if a:cchar == 'l'
2387 call assert_equal({}, getloclist(99, {'title': 1}))
2388 endif
2389
2390 " Context related tests
2391 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2392 call assert_equal(0, s)
2393 call test_garbagecollect_now()
2394 let d = g:Xgetlist({'context':1})
2395 call assert_equal([1,2,3], d.context)
2396 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2397 let d = g:Xgetlist({'context':1})
2398 call assert_equal({'color':'green'}, d.context)
2399 call g:Xsetlist([], 'a', {'context':"Context info"})
2400 let d = g:Xgetlist({'context':1})
2401 call assert_equal("Context info", d.context)
2402 call g:Xsetlist([], 'a', {'context':246})
2403 let d = g:Xgetlist({'context':1})
2404 call assert_equal(246, d.context)
2405 " set other Vim data types as context
2406 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2407 if has('channel')
2408 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2409 endif
2410 if has('job')
2411 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2412 endif
2413 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2414 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2415 call g:Xsetlist([], 'a', {'context' : ''})
2416 call test_garbagecollect_now()
2417 if a:cchar == 'l'
2418 " Test for copying context across two different location lists
2419 new | only
2420 let w1_id = win_getid()
2421 let l = [1]
2422 call setloclist(0, [], 'a', {'context':l})
2423 new
2424 let w2_id = win_getid()
2425 call add(l, 2)
2426 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2427 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2428 unlet! l
2429 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2430 only
2431 call setloclist(0, [], 'f')
2432 call assert_equal('', getloclist(0, {'context':1}).context)
2433 endif
2434
2435 " Test for changing the context of previous quickfix lists
2436 call g:Xsetlist([], 'f')
2437 Xexpr "One"
2438 Xexpr "Two"
2439 Xexpr "Three"
2440 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2441 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2442 " Also, check for setting the context using quickfix list number zero.
2443 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2444 call test_garbagecollect_now()
2445 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2446 call assert_equal([1], l.context)
2447 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2448 call assert_equal([2], l.context)
2449 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2450 call assert_equal([3], l.context)
2451
2452 " Test for changing the context through reference and for garbage
2453 " collection of quickfix context
2454 let l = ["red"]
2455 call g:Xsetlist([], ' ', {'context' : l})
2456 call add(l, "blue")
2457 let x = g:Xgetlist({'context' : 1})
2458 call add(x.context, "green")
2459 call assert_equal(["red", "blue", "green"], l)
2460 call assert_equal(["red", "blue", "green"], x.context)
2461 unlet l
2462 call test_garbagecollect_now()
2463 let m = g:Xgetlist({'context' : 1})
2464 call assert_equal(["red", "blue", "green"], m.context)
2465
2466 " Test for setting/getting items
2467 Xexpr ""
2468 let qfprev = g:Xgetlist({'nr':0})
2469 let s = g:Xsetlist([], ' ', {'title':'Green',
2470 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2471 call assert_equal(0, s)
2472 let qfcur = g:Xgetlist({'nr':0})
2473 call assert_true(qfcur.nr == qfprev.nr + 1)
2474 let l = g:Xgetlist({'items':1})
2475 call assert_equal('F1', bufname(l.items[0].bufnr))
2476 call assert_equal(10, l.items[0].lnum)
2477 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2478 \ {'filename':'F2', 'lnum':30}]})
2479 let l = g:Xgetlist({'items':1})
2480 call assert_equal('F2', bufname(l.items[2].bufnr))
2481 call assert_equal(30, l.items[2].lnum)
2482 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2483 let l = g:Xgetlist({'items':1})
2484 call assert_equal('F3', bufname(l.items[0].bufnr))
2485 call assert_equal(40, l.items[0].lnum)
2486 call g:Xsetlist([], 'r', {'items' : []})
2487 let l = g:Xgetlist({'items':1})
2488 call assert_equal(0, len(l.items))
2489
2490 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2491 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2492 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2493 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2494
2495 " Test for getting id of window associated with a location list window
2496 if a:cchar == 'l'
2497 only
2498 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2499 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002500 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002501 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2502 wincmd w
2503 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2504 only
2505 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002506
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002507 " The following used to crash Vim with address sanitizer
2508 call g:Xsetlist([], 'f')
2509 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2510 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002511
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002512 " Try setting the items using a string
2513 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002514
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002515 " Save and restore the quickfix stack
2516 call g:Xsetlist([], 'f')
2517 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2518 Xexpr "File1:10:Line1"
2519 Xexpr "File2:20:Line2"
2520 Xexpr "File3:30:Line3"
2521 let last_qf = g:Xgetlist({'nr':'$'}).nr
2522 call assert_equal(3, last_qf)
2523 let qstack = []
2524 for i in range(1, last_qf)
2525 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2526 endfor
2527 call g:Xsetlist([], 'f')
2528 for i in range(len(qstack))
2529 call g:Xsetlist([], ' ', qstack[i])
2530 endfor
2531 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2532 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2533 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2534 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2535 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002536
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002537 " Swap two quickfix lists
2538 Xexpr "File1:10:Line10"
2539 Xexpr "File2:20:Line20"
2540 Xexpr "File3:30:Line30"
2541 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2542 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2543 let l1=g:Xgetlist({'nr':1,'all':1})
2544 let l2=g:Xgetlist({'nr':2,'all':1})
2545 let save_id = l1.id
2546 let l1.id=l2.id
2547 let l2.id=save_id
2548 call g:Xsetlist([], 'r', l1)
2549 call g:Xsetlist([], 'r', l2)
2550 let newl1=g:Xgetlist({'nr':1,'all':1})
2551 let newl2=g:Xgetlist({'nr':2,'all':1})
2552 call assert_equal('Fruits', newl1.title)
2553 call assert_equal(['Fruits'], newl1.context)
2554 call assert_equal('Line20', newl1.items[0].text)
2555 call assert_equal('Colors', newl2.title)
2556 call assert_equal(['Colors'], newl2.context)
2557 call assert_equal('Line10', newl2.items[0].text)
2558 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002559
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002560 " Cannot specify both a non-empty list argument and a dict argument
2561 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002562endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002563
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002564func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002565 call Xproperty_tests('c')
2566 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002567endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002568
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002569" Test for setting the current index in the location/quickfix list
2570func Xtest_setqfidx(cchar)
2571 call s:setup_commands(a:cchar)
2572
2573 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2574 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2575 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2576
2577 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2578 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2579 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2580 Xolder 2
2581 Xopen
2582 call assert_equal(3, line('.'))
2583 Xnewer
2584 call assert_equal(2, line('.'))
2585 Xnewer
2586 call assert_equal(2, line('.'))
2587 " Update the current index with the quickfix window open
2588 wincmd w
2589 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2590 Xopen
2591 call assert_equal(3, line('.'))
2592 Xclose
2593
2594 " Set the current index to the last entry
2595 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2596 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2597 " A large value should set the index to the last index
2598 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2599 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2600 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2601 " Invalid index values
2602 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2603 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2604 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2605 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2606 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2607 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2608 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2609
2610 call g:Xsetlist([], 'f')
2611 new | only
2612endfunc
2613
2614func Test_setqfidx()
2615 call Xtest_setqfidx('c')
2616 call Xtest_setqfidx('l')
2617endfunc
2618
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002619" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002620func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002621 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002622endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002623
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002624func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002625 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2626 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2627
2628 let g:acmds = []
2629 cexpr "F1:10:Line 10"
2630 caddexpr "F1:20:Line 20"
2631 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002632 cexpr ""
2633 caddexpr ""
2634 cgetexpr ""
2635 silent! cexpr non_existing_func()
2636 silent! caddexpr non_existing_func()
2637 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002638 let l = ['precexpr',
2639 \ 'postcexpr',
2640 \ 'precaddexpr',
2641 \ 'postcaddexpr',
2642 \ 'precgetexpr',
2643 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002644 \ 'precexpr',
2645 \ 'postcexpr',
2646 \ 'precaddexpr',
2647 \ 'postcaddexpr',
2648 \ 'precgetexpr',
2649 \ 'postcgetexpr',
2650 \ 'precexpr',
2651 \ 'precaddexpr',
2652 \ 'precgetexpr']
2653 call assert_equal(l, g:acmds)
2654
2655 let g:acmds = []
2656 enew! | call append(0, "F2:10:Line 10")
2657 cbuffer!
2658 enew! | call append(0, "F2:20:Line 20")
2659 cgetbuffer
2660 enew! | call append(0, "F2:30:Line 30")
2661 caddbuffer
2662 new
2663 let bnum = bufnr('%')
2664 bunload
2665 exe 'silent! cbuffer! ' . bnum
2666 exe 'silent! cgetbuffer ' . bnum
2667 exe 'silent! caddbuffer ' . bnum
2668 enew!
2669 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002670 \ 'postcbuffer',
2671 \ 'precgetbuffer',
2672 \ 'postcgetbuffer',
2673 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002674 \ 'postcaddbuffer',
2675 \ 'precbuffer',
2676 \ 'precgetbuffer',
2677 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002678 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002679
2680 call writefile(['Xtest:1:Line1'], 'Xtest')
2681 call writefile([], 'Xempty')
2682 let g:acmds = []
2683 cfile Xtest
2684 caddfile Xtest
2685 cgetfile Xtest
2686 cfile Xempty
2687 caddfile Xempty
2688 cgetfile Xempty
2689 silent! cfile do_not_exist
2690 silent! caddfile do_not_exist
2691 silent! cgetfile do_not_exist
2692 let l = ['precfile',
2693 \ 'postcfile',
2694 \ 'precaddfile',
2695 \ 'postcaddfile',
2696 \ 'precgetfile',
2697 \ 'postcgetfile',
2698 \ 'precfile',
2699 \ 'postcfile',
2700 \ 'precaddfile',
2701 \ 'postcaddfile',
2702 \ 'precgetfile',
2703 \ 'postcgetfile',
2704 \ 'precfile',
2705 \ 'postcfile',
2706 \ 'precaddfile',
2707 \ 'postcaddfile',
2708 \ 'precgetfile',
2709 \ 'postcgetfile']
2710 call assert_equal(l, g:acmds)
2711
2712 let g:acmds = []
2713 helpgrep quickfix
2714 silent! helpgrep non_existing_help_topic
2715 vimgrep test Xtest
2716 vimgrepadd test Xtest
2717 silent! vimgrep non_existing_test Xtest
2718 silent! vimgrepadd non_existing_test Xtest
2719 set makeprg=
2720 silent! make
2721 set makeprg&
2722 let l = ['prehelpgrep',
2723 \ 'posthelpgrep',
2724 \ 'prehelpgrep',
2725 \ 'posthelpgrep',
2726 \ 'previmgrep',
2727 \ 'postvimgrep',
2728 \ 'previmgrepadd',
2729 \ 'postvimgrepadd',
2730 \ 'previmgrep',
2731 \ 'postvimgrep',
2732 \ 'previmgrepadd',
2733 \ 'postvimgrepadd',
2734 \ 'premake',
2735 \ 'postmake']
2736 call assert_equal(l, g:acmds)
2737
2738 if has('unix')
2739 " Run this test only on Unix-like systems. The grepprg may not be set on
2740 " non-Unix systems.
2741 " The following lines are used for the grep test. Don't remove.
2742 " Grep_Autocmd_Text: Match 1
2743 " GrepAdd_Autocmd_Text: Match 2
2744 let g:acmds = []
2745 silent grep Grep_Autocmd_Text test_quickfix.vim
2746 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2747 silent grep abc123def Xtest
2748 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002749 set grepprg=internal
2750 silent grep Grep_Autocmd_Text test_quickfix.vim
2751 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2752 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2753 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2754 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002755 let l = ['pregrep',
2756 \ 'postgrep',
2757 \ 'pregrepadd',
2758 \ 'postgrepadd',
2759 \ 'pregrep',
2760 \ 'postgrep',
2761 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002762 \ 'postgrepadd',
2763 \ 'pregrep',
2764 \ 'postgrep',
2765 \ 'pregrepadd',
2766 \ 'postgrepadd',
2767 \ 'prelgrep',
2768 \ 'postlgrep',
2769 \ 'prelgrepadd',
2770 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002771 call assert_equal(l, g:acmds)
2772 endif
2773
2774 call delete('Xtest')
2775 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002776 au! QuickFixCmdPre
2777 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002778endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002779
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002780func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002781 set efm=%m
2782 lgetexpr '?'
2783
2784 try
2785 call DoesNotExit()
2786 catch
2787 lgetexpr '1'
2788 finally
2789 lgetexpr '1'
2790 endtry
2791
2792 call assert_equal('1', getloclist(0)[0].text)
2793
2794 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002795endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002796
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002797func Test_caddbuffer_wrong()
2798 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002799 let save_efm = &efm
2800 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2801 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2802 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002803 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002804 bwipe!
2805endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002806
2807func Test_caddexpr_wrong()
2808 " This used to cause a memory access in freed memory.
2809 cbuffer
2810 cbuffer
2811 copen
2812 let save_efm = &efm
2813 set efm=%
2814 call assert_fails('caddexpr ""', 'E376:')
2815 let &efm = save_efm
2816endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002817
2818func Test_dirstack_cleanup()
2819 " This used to cause a memory access in freed memory.
2820 let save_efm = &efm
2821 lexpr '0'
2822 lopen
2823 fun X(c)
2824 let save_efm=&efm
2825 set efm=%D%f
2826 if a:c == 'c'
2827 caddexpr '::'
2828 else
2829 laddexpr ':0:0'
2830 endif
2831 let &efm=save_efm
2832 endfun
2833 call X('c')
2834 call X('l')
2835 call setqflist([], 'r')
2836 caddbuffer
2837 let &efm = save_efm
2838endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002839
2840" Tests for jumping to entries from the location list window and quickfix
2841" window
2842func Test_cwindow_jump()
2843 set efm=%f%%%l%%%m
2844 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2845 lopen | only
2846 lfirst
2847 call assert_true(winnr('$') == 2)
2848 call assert_true(winnr() == 1)
2849 " Location list for the new window should be set
2850 call assert_true(getloclist(0)[2].text == 'Line 30')
2851
2852 " Open a scratch buffer
2853 " Open a new window and create a location list
2854 " Open the location list window and close the other window
2855 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002856 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002857 " should not be used.
2858 enew | only
2859 set buftype=nofile
2860 below new
2861 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2862 lopen
2863 2wincmd c
2864 lnext
2865 call assert_true(winnr('$') == 3)
2866 call assert_true(winnr() == 2)
2867
2868 " Open two windows with two different location lists
2869 " Open the location list window and close the previous window
2870 " Jump to an entry in the location list window
2871 " Should open the file in the first window and not set the location list.
2872 enew | only
2873 lgetexpr ["F1%5%Line 5"]
2874 below new
2875 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2876 lopen
2877 2wincmd c
2878 lnext
2879 call assert_true(winnr() == 1)
2880 call assert_true(getloclist(0)[0].text == 'Line 5')
2881
2882 enew | only
2883 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2884 copen
2885 cnext
2886 call assert_true(winnr('$') == 2)
2887 call assert_true(winnr() == 1)
2888
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002889 " open the quickfix buffer in two windows and jump to an entry. Should open
2890 " the file in the first quickfix window.
2891 enew | only
2892 copen
2893 let bnum = bufnr('')
2894 exe 'sbuffer ' . bnum
2895 wincmd b
2896 cfirst
2897 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002898 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002899 enew | only
2900 exe 'sb' bnum
2901 exe 'botright sb' bnum
2902 wincmd t
2903 clast
2904 call assert_equal(2, winnr())
2905 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2906 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2907
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002908 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002909 " window by wrapping around the window list.
2910 enew | only
2911 call setloclist(0, [], 'f')
2912 new | new
2913 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2914 lopen
2915 1close
2916 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2917 lnext
2918 call assert_equal(3, winnr())
2919 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2920
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002921 enew | only
2922 set efm&vim
2923endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002924
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002925func Test_cwindow_highlight()
2926 CheckScreendump
2927
2928 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002929 call setline(1, ['some', 'text', 'with', 'matches'])
2930 write XCwindow
2931 vimgrep e XCwindow
2932 redraw
2933 cwindow 4
2934 END
2935 call writefile(lines, 'XtestCwindow')
2936 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2937 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2938
2939 call term_sendkeys(buf, ":cnext\<CR>")
2940 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2941
2942 " clean up
2943 call StopVimInTerminal(buf)
2944 call delete('XtestCwindow')
2945 call delete('XCwindow')
2946endfunc
2947
Bram Moolenaaree85df32017-03-19 14:19:50 +01002948func XvimgrepTests(cchar)
2949 call s:setup_commands(a:cchar)
2950
2951 call writefile(['Editor:VIM vim',
2952 \ 'Editor:Emacs EmAcS',
2953 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002954 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002955
2956 " Error cases
2957 call assert_fails('Xvimgrep /abc *', 'E682:')
2958
2959 let @/=''
2960 call assert_fails('Xvimgrep // *', 'E35:')
2961
2962 call assert_fails('Xvimgrep abc', 'E683:')
2963 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2964 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2965
2966 Xexpr ""
2967 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002968 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002969 let l = g:Xgetlist()
2970 call assert_equal(2, len(l))
2971 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2972
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002973 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002974 let l = g:Xgetlist()
2975 call assert_equal(2, len(l))
2976 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002977 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002978 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002979 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002980
2981 1Xvimgrep ?Editor? Xtestfile*
2982 let l = g:Xgetlist()
2983 call assert_equal(1, len(l))
2984 call assert_equal('Editor:VIM vim', l[0].text)
2985
2986 edit +3 Xtestfile2
2987 Xvimgrep +\cemacs+j Xtestfile1
2988 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002989 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002990 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2991
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002992 " Test for unloading a buffer after vimgrep searched the buffer
2993 %bwipe
2994 Xvimgrep /Editor/j Xtestfile*
2995 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2996 call assert_equal([], getbufinfo('Xtestfile2'))
2997
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00002998 " Test for opening the dummy buffer used by vimgrep in a window. The new
2999 " window should be closed
3000 %bw!
3001 augroup QF_Test
3002 au!
3003 autocmd BufReadPre * exe "sb " .. expand("<abuf>")
3004 augroup END
3005 call assert_fails("Xvimgrep /sublime/ Xtestfile1", 'E480:')
3006 call assert_equal(1, winnr('$'))
3007 augroup QF_Test
3008 au!
3009 augroup END
3010
Bram Moolenaaree85df32017-03-19 14:19:50 +01003011 call delete('Xtestfile1')
3012 call delete('Xtestfile2')
3013endfunc
3014
3015" Tests for the :vimgrep command
3016func Test_vimgrep()
3017 call XvimgrepTests('c')
3018 call XvimgrepTests('l')
3019endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003020
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01003021func Test_vimgrep_wildcards_expanded_once()
3022 new X[id-01] file.txt
3023 call setline(1, 'some text to search for')
3024 vimgrep text %
3025 bwipe!
3026endfunc
3027
Bram Moolenaar1c299432018-10-28 14:36:09 +01003028" Test for incsearch highlighting of the :vimgrep pattern
3029" This test used to cause "E315: ml_get: invalid lnum" errors.
3030func Test_vimgrep_incsearch()
3031 enew
3032 set incsearch
3033 call test_override("char_avail", 1)
3034
3035 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
3036 let l = getqflist()
3037 call assert_equal(2, len(l))
3038
3039 call test_override("ALL", 0)
3040 set noincsearch
3041endfunc
3042
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003043" Test vimgrep with the last search pattern not set
3044func Test_vimgrep_with_no_last_search_pat()
3045 let lines =<< trim [SCRIPT]
3046 call assert_fails('vimgrep // *', 'E35:')
3047 call writefile(v:errors, 'Xresult')
3048 qall!
3049 [SCRIPT]
3050 call writefile(lines, 'Xscript')
3051 if RunVim([], [], '--clean -S Xscript')
3052 call assert_equal([], readfile('Xresult'))
3053 endif
3054 call delete('Xscript')
3055 call delete('Xresult')
3056endfunc
3057
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003058" Test vimgrep without swap file
3059func Test_vimgrep_without_swap_file()
3060 let lines =<< trim [SCRIPT]
3061 vimgrep grep test_c*
3062 call writefile(['done'], 'Xresult')
3063 qall!
3064 [SCRIPT]
3065 call writefile(lines, 'Xscript')
3066 if RunVim([], [], '--clean -n -S Xscript Xscript')
3067 call assert_equal(['done'], readfile('Xresult'))
3068 endif
3069 call delete('Xscript')
3070 call delete('Xresult')
3071endfunc
3072
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003073func Test_vimgrep_existing_swapfile()
3074 call writefile(['match apple with apple'], 'Xapple')
3075 call writefile(['swapfile'], '.Xapple.swp')
3076 let g:foundSwap = 0
3077 let g:ignoreSwapExists = 1
3078 augroup grep
3079 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3080 augroup END
3081 vimgrep apple Xapple
3082 call assert_equal(1, g:foundSwap)
3083 call assert_match('.Xapple.swo', swapname(''))
3084
3085 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003086 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003087 augroup grep
3088 au! SwapExists
3089 augroup END
3090 unlet g:ignoreSwapExists
3091endfunc
3092
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003093func XfreeTests(cchar)
3094 call s:setup_commands(a:cchar)
3095
3096 enew | only
3097
3098 " Deleting the quickfix stack should work even When the current list is
3099 " somewhere in the middle of the stack
3100 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3101 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3102 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3103 Xolder
3104 call g:Xsetlist([], 'f')
3105 call assert_equal(0, len(g:Xgetlist()))
3106
3107 " After deleting the stack, adding a new list should create a stack with a
3108 " single list.
3109 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3110 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3111
3112 " Deleting the stack from a quickfix window should update/clear the
3113 " quickfix/location list window.
3114 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3115 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3116 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3117 Xolder
3118 Xwindow
3119 call g:Xsetlist([], 'f')
3120 call assert_equal(2, winnr('$'))
3121 call assert_equal(1, line('$'))
3122 Xclose
3123
3124 " Deleting the stack from a non-quickfix window should update/clear the
3125 " quickfix/location list window.
3126 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3127 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3128 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3129 Xolder
3130 Xwindow
3131 wincmd p
3132 call g:Xsetlist([], 'f')
3133 call assert_equal(0, len(g:Xgetlist()))
3134 wincmd p
3135 call assert_equal(2, winnr('$'))
3136 call assert_equal(1, line('$'))
3137
3138 " After deleting the location list stack, if the location list window is
3139 " opened, then a new location list should be created. So opening the
3140 " location list window again should not create a new window.
3141 if a:cchar == 'l'
3142 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3143 wincmd p
3144 lopen
3145 call assert_equal(2, winnr('$'))
3146 endif
3147 Xclose
3148endfunc
3149
Bram Moolenaar74240d32017-12-10 15:26:15 +01003150" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003151func Test_qf_free()
3152 call XfreeTests('c')
3153 call XfreeTests('l')
3154endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003155
3156" Test for buffer overflow when parsing lines and adding new entries to
3157" the quickfix list.
3158func Test_bufoverflow()
3159 set efm=%f:%l:%m
3160 cgetexpr ['File1:100:' . repeat('x', 1025)]
3161
3162 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3163 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3164
3165 set efm=%DEntering\ directory\ %f,%f:%l:%m
3166 cgetexpr ['Entering directory ' . repeat('a', 1006),
3167 \ 'File1:10:Hello World']
3168 set efm&vim
3169endfunc
3170
Bram Moolenaar875feea2017-06-11 16:07:51 +02003171" Tests for getting the quickfix stack size
3172func XsizeTests(cchar)
3173 call s:setup_commands(a:cchar)
3174
3175 call g:Xsetlist([], 'f')
3176 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003177 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3178 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003179
3180 Xexpr "File1:10:Line1"
3181 Xexpr "File2:20:Line2"
3182 Xexpr "File3:30:Line3"
3183 Xolder | Xolder
3184 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3185 call g:Xsetlist([], 'f')
3186
3187 Xexpr "File1:10:Line1"
3188 Xexpr "File2:20:Line2"
3189 Xexpr "File3:30:Line3"
3190 Xolder | Xolder
3191 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3192 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3193endfunc
3194
3195func Test_Qf_Size()
3196 call XsizeTests('c')
3197 call XsizeTests('l')
3198endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003199
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003200func Test_cclose_from_copen()
3201 augroup QF_Test
3202 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003203 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003204 augroup END
3205 copen
3206 augroup QF_Test
3207 au!
3208 augroup END
3209 augroup! QF_Test
3210endfunc
3211
Bram Moolenaar18141832017-06-25 21:17:25 +02003212func Test_cclose_in_autocmd()
3213 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3214 " event will be triggered.
3215 call test_override('starting', 1)
3216 augroup QF_Test
3217 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003218 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003219 augroup END
3220 copen
3221 augroup QF_Test
3222 au!
3223 augroup END
3224 augroup! QF_Test
3225 call test_override('starting', 0)
3226endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003227
Bram Moolenaar379fb762018-08-30 15:58:28 +02003228" Check that ":file" without an argument is possible even when "curbuf_lock"
3229" is set.
3230func Test_file_from_copen()
3231 " Works without argument.
3232 augroup QF_Test
3233 au!
3234 au FileType qf file
3235 augroup END
3236 copen
3237
3238 augroup QF_Test
3239 au!
3240 augroup END
3241 cclose
3242
3243 " Fails with argument.
3244 augroup QF_Test
3245 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003246 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003247 augroup END
3248 copen
3249 augroup QF_Test
3250 au!
3251 augroup END
3252 cclose
3253
3254 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003255endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003256
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003257func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003258 augroup QF_Test
3259 au!
3260 au FileType qf resize 5
3261 augroup END
3262 try
3263 " This should succeed without any exception. No other buffers are
3264 " involved in the autocmd.
3265 copen
3266 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003267 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003268 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003269 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003270 augroup! QF_Test
3271 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003272endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003273
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003274func Test_vimgrep_with_textlock()
3275 new
3276
3277 " Simple way to execute something with "textwinlock" set.
3278 " Check that vimgrep without jumping can be executed.
3279 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3280 normal ax
3281 let qflist = getqflist()
3282 call assert_true(len(qflist) > 0)
3283 call assert_match('RunTheTest', qflist[0].text)
3284 call setqflist([], 'r')
3285 au! InsertCharPre
3286
3287 " Check that vimgrepadd without jumping can be executed.
3288 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3289 normal ax
3290 let qflist = getqflist()
3291 call assert_true(len(qflist) > 0)
3292 call assert_match('RunTheTest', qflist[0].text)
3293 call setqflist([], 'r')
3294 au! InsertCharPre
3295
3296 " Check that lvimgrep without jumping can be executed.
3297 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3298 normal ax
3299 let qflist = getloclist(0)
3300 call assert_true(len(qflist) > 0)
3301 call assert_match('RunTheTest', qflist[0].text)
3302 call setloclist(0, [], 'r')
3303 au! InsertCharPre
3304
3305 " Check that lvimgrepadd without jumping can be executed.
3306 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3307 normal ax
3308 let qflist = getloclist(0)
3309 call assert_true(len(qflist) > 0)
3310 call assert_match('RunTheTest', qflist[0].text)
3311 call setloclist(0, [], 'r')
3312 au! InsertCharPre
3313
3314 " trying to jump will give an error
3315 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3316 call assert_fails('normal ax', 'E565:')
3317 au! InsertCharPre
3318
3319 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3320 call assert_fails('normal ax', 'E565:')
3321 au! InsertCharPre
3322
3323 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3324 call assert_fails('normal ax', 'E565:')
3325 au! InsertCharPre
3326
3327 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3328 call assert_fails('normal ax', 'E565:')
3329 au! InsertCharPre
3330
3331 bwipe!
3332endfunc
3333
Bram Moolenaara8788f42017-07-19 17:06:20 +02003334" Tests for the quickfix buffer b:changedtick variable
3335func Xchangedtick_tests(cchar)
3336 call s:setup_commands(a:cchar)
3337
3338 new | only
3339
3340 Xexpr "" | Xexpr "" | Xexpr ""
3341
3342 Xopen
3343 Xolder
3344 Xolder
3345 Xaddexpr "F1:10:Line10"
3346 Xaddexpr "F2:20:Line20"
3347 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3348 call g:Xsetlist([], 'f')
3349 call assert_equal(8, getbufvar('%', 'changedtick'))
3350 Xclose
3351endfunc
3352
3353func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003354 call Xchangedtick_tests('c')
3355 call Xchangedtick_tests('l')
3356endfunc
3357
3358" Tests for parsing an expression using setqflist()
3359func Xsetexpr_tests(cchar)
3360 call s:setup_commands(a:cchar)
3361
3362 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003363 call g:Xsetlist([], ' ', {'lines' : t})
3364 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003365
3366 let l = g:Xgetlist()
3367 call assert_equal(3, len(l))
3368 call assert_equal(20, l[1].lnum)
3369 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003370 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003371 let l = g:Xgetlist()
3372 call assert_equal(1, len(l))
3373 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003374 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3375 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003376
3377 call g:Xsetlist([], 'f')
3378 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003379 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3380 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3381 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3382 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003383 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3384 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003385
3386 " Adding entries using a custom efm
3387 set efm&
3388 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3389 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3390 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3391 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3392 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3393 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3394 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3395 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003396endfunc
3397
3398func Test_setexpr()
3399 call Xsetexpr_tests('c')
3400 call Xsetexpr_tests('l')
3401endfunc
3402
3403" Tests for per quickfix/location list directory stack
3404func Xmultidirstack_tests(cchar)
3405 call s:setup_commands(a:cchar)
3406
3407 call g:Xsetlist([], 'f')
3408 Xexpr "" | Xexpr ""
3409
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003410 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3411 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3412 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3413 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003414
3415 let l1 = g:Xgetlist({'nr':1, 'items':1})
3416 let l2 = g:Xgetlist({'nr':2, 'items':1})
3417 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3418 call assert_equal(3, l1.items[1].lnum)
3419 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3420 call assert_equal(5, l2.items[1].lnum)
3421endfunc
3422
3423func Test_multidirstack()
3424 call mkdir('Xone/a', 'p')
3425 call mkdir('Xtwo/a', 'p')
3426 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3427 call writefile(lines, 'Xone/a/one.txt')
3428 call writefile(lines, 'Xtwo/a/two.txt')
3429 let save_efm = &efm
3430 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3431
3432 call Xmultidirstack_tests('c')
3433 call Xmultidirstack_tests('l')
3434
3435 let &efm = save_efm
3436 call delete('Xone', 'rf')
3437 call delete('Xtwo', 'rf')
3438endfunc
3439
3440" Tests for per quickfix/location list file stack
3441func Xmultifilestack_tests(cchar)
3442 call s:setup_commands(a:cchar)
3443
3444 call g:Xsetlist([], 'f')
3445 Xexpr "" | Xexpr ""
3446
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003447 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3448 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3449 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3450 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003451
3452 let l1 = g:Xgetlist({'nr':1, 'items':1})
3453 let l2 = g:Xgetlist({'nr':2, 'items':1})
3454 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3455 call assert_equal(3, l1.items[1].lnum)
3456 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3457 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003458
3459 " Test for start of a new error line in the same line where a previous
3460 " error line ends with a file stack.
3461 let efm_val = 'Error\ l%l\ in\ %f,'
3462 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3463 let l = g:Xgetlist({'lines' : [
3464 \ '(one.txt',
3465 \ 'Error l4 in one.txt',
3466 \ ') (two.txt',
3467 \ 'Error l6 in two.txt',
3468 \ ')',
3469 \ 'Error l8 in one.txt'
3470 \ ], 'efm' : efm_val})
3471 call assert_equal(3, len(l.items))
3472 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3473 call assert_equal(4, l.items[0].lnum)
3474 call assert_equal('one.txt', l.items[0].text)
3475 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3476 call assert_equal(6, l.items[1].lnum)
3477 call assert_equal('two.txt', l.items[1].text)
3478 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3479 call assert_equal(8, l.items[2].lnum)
3480 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003481endfunc
3482
3483func Test_multifilestack()
3484 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3485 call writefile(lines, 'one.txt')
3486 call writefile(lines, 'two.txt')
3487 let save_efm = &efm
3488 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3489
3490 call Xmultifilestack_tests('c')
3491 call Xmultifilestack_tests('l')
3492
3493 let &efm = save_efm
3494 call delete('one.txt')
3495 call delete('two.txt')
3496endfunc
3497
3498" Tests for per buffer 'efm' setting
3499func Test_perbuf_efm()
3500 call writefile(["File1-10-Line10"], 'one.txt')
3501 call writefile(["File2#20#Line20"], 'two.txt')
3502 set efm=%f#%l#%m
3503 new | only
3504 new
3505 setlocal efm=%f-%l-%m
3506 cfile one.txt
3507 wincmd w
3508 caddfile two.txt
3509
3510 let l = getqflist()
3511 call assert_equal(10, l[0].lnum)
3512 call assert_equal('Line20', l[1].text)
3513
3514 set efm&
3515 new | only
3516 call delete('one.txt')
3517 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003518endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003519
3520" Open multiple help windows using ":lhelpgrep
3521" This test used to crash Vim
3522func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003523 new | only
3524 lhelpgrep window
3525 lopen
3526 e#
3527 lhelpgrep buffer
3528 call assert_equal(3, winnr('$'))
3529 call assert_true(len(getloclist(1)) != 0)
3530 call assert_true(len(getloclist(2)) != 0)
3531 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003532endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003533
3534" Tests for adding new quickfix lists using setqflist()
3535func XaddQf_tests(cchar)
3536 call s:setup_commands(a:cchar)
3537
3538 " Create a new list using ' ' for action
3539 call g:Xsetlist([], 'f')
3540 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3541 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3542 call assert_equal(1, l.nr)
3543 call assert_equal('Test1', l.title)
3544
3545 " Create a new list using ' ' for action and '$' for 'nr'
3546 call g:Xsetlist([], 'f')
3547 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3548 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3549 call assert_equal(1, l.nr)
3550 call assert_equal('Test2', l.title)
3551
3552 " Create a new list using 'a' for action
3553 call g:Xsetlist([], 'f')
3554 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3555 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3556 call assert_equal(1, l.nr)
3557 call assert_equal('Test3', l.title)
3558
3559 " Create a new list using 'a' for action and '$' for 'nr'
3560 call g:Xsetlist([], 'f')
3561 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3562 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3563 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3564 call assert_equal(1, l.nr)
3565 call assert_equal('Test4', l.title)
3566
3567 " Adding a quickfix list should remove all the lists following the current
3568 " list.
3569 Xexpr "" | Xexpr "" | Xexpr ""
3570 silent! 10Xolder
3571 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3572 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3573 call assert_equal(2, l.nr)
3574 call assert_equal('Test5', l.title)
3575
3576 " Add a quickfix list using '$' as the list number.
3577 let lastqf = g:Xgetlist({'nr':'$'}).nr
3578 silent! 99Xolder
3579 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3580 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3581 call assert_equal(lastqf + 1, l.nr)
3582 call assert_equal('Test6', l.title)
3583
3584 " Add a quickfix list using 'nr' set to one more than the quickfix
3585 " list size.
3586 let lastqf = g:Xgetlist({'nr':'$'}).nr
3587 silent! 99Xolder
3588 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3589 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3590 call assert_equal(lastqf + 1, l.nr)
3591 call assert_equal('Test7', l.title)
3592
3593 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3594 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3595 silent! 99Xolder
3596 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3597 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3598 call assert_equal(10, l.nr)
3599 call assert_equal('Test8', l.title)
3600
3601 " Add a quickfix list using 'nr' set to a value greater than 10
3602 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3603
3604 " Try adding a quickfix list with 'nr' set to a value greater than the
3605 " quickfix list size but less than 10.
3606 call g:Xsetlist([], 'f')
3607 Xexpr "" | Xexpr "" | Xexpr ""
3608 silent! 99Xolder
3609 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3610
3611 " Add a quickfix list using 'nr' set to a some string or list
3612 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3613endfunc
3614
3615func Test_add_qf()
3616 call XaddQf_tests('c')
3617 call XaddQf_tests('l')
3618endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003619
3620" Test for getting the quickfix list items from some text without modifying
3621" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003622func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003623 call s:setup_commands(a:cchar)
3624 call g:Xsetlist([], 'f')
3625
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003626 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003627 call assert_equal(2, len(l))
3628 call assert_equal(30, l[1].lnum)
3629
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003630 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3631 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3632 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3633 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003634
Bram Moolenaar36538222017-09-02 19:51:44 +02003635 " Parse text using a custom efm
3636 set efm&
3637 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3638 call assert_equal('Line30', l[0].text)
3639 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3640 call assert_equal('File3:30:Line30', l[0].text)
3641 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3642 call assert_equal({}, l)
3643 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3644 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3645
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003646 " Make sure that the quickfix stack is not modified
3647 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3648endfunc
3649
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003650func Test_get_list_from_lines()
3651 call XgetListFromLines('c')
3652 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003653endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003654
3655" Tests for the quickfix list id
3656func Xqfid_tests(cchar)
3657 call s:setup_commands(a:cchar)
3658
3659 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003660 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003661 Xexpr ''
3662 let start_id = g:Xgetlist({'id' : 0}).id
3663 Xexpr '' | Xexpr ''
3664 Xolder
3665 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3666 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3667 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003668 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003669 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003670 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3671 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003672
3673 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3674 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003675 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003676 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3677 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3678 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3679
3680 let qfid = g:Xgetlist({'id':0, 'nr':0})
3681 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003682 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003683endfunc
3684
3685func Test_qf_id()
3686 call Xqfid_tests('c')
3687 call Xqfid_tests('l')
3688endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003689
3690func Xqfjump_tests(cchar)
3691 call s:setup_commands(a:cchar)
3692
3693 call writefile(["Line1\tFoo", "Line2"], 'F1')
3694 call writefile(["Line1\tBar", "Line2"], 'F2')
3695 call writefile(["Line1\tBaz", "Line2"], 'F3')
3696
3697 call g:Xsetlist([], 'f')
3698
3699 " Tests for
3700 " Jumping to a line using a pattern
3701 " Jumping to a column greater than the last column in a line
3702 " Jumping to a line greater than the last line in the file
3703 let l = []
3704 for i in range(1, 7)
3705 call add(l, {})
3706 endfor
3707 let l[0].filename='F1'
3708 let l[0].pattern='Line1'
3709 let l[1].filename='F2'
3710 let l[1].pattern='Line1'
3711 let l[2].filename='F3'
3712 let l[2].pattern='Line1'
3713 let l[3].filename='F3'
3714 let l[3].lnum=1
3715 let l[3].col=9
3716 let l[3].vcol=1
3717 let l[4].filename='F3'
3718 let l[4].lnum=99
3719 let l[5].filename='F3'
3720 let l[5].lnum=1
3721 let l[5].col=99
3722 let l[5].vcol=1
3723 let l[6].filename='F3'
3724 let l[6].pattern='abcxyz'
3725
3726 call g:Xsetlist([], ' ', {'items' : l})
3727 Xopen | only
3728 2Xnext
3729 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003730 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003731 Xnext
3732 call assert_equal(7, col('.'))
3733 Xnext
3734 call assert_equal(2, line('.'))
3735 Xnext
3736 call assert_equal(9, col('.'))
3737 2
3738 Xnext
3739 call assert_equal(2, line('.'))
3740
3741 if a:cchar == 'l'
3742 " When jumping to a location list entry in the location list window and
3743 " no usable windows are available, then a new window should be opened.
3744 enew! | new | only
3745 call g:Xsetlist([], 'f')
3746 setlocal buftype=nofile
3747 new
3748 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']})
3749 Xopen
3750 let winid = win_getid()
3751 wincmd p
3752 close
3753 call win_gotoid(winid)
3754 Xnext
3755 call assert_equal(3, winnr('$'))
3756 call assert_equal(1, winnr())
3757 call assert_equal(2, line('.'))
3758
3759 " When jumping to an entry in the location list window and the window
3760 " associated with the location list is not present and a window containing
3761 " the file is already present, then that window should be used.
3762 close
3763 belowright new
3764 call g:Xsetlist([], 'f')
3765 edit F3
3766 call win_gotoid(winid)
3767 Xlast
3768 call assert_equal(3, winnr())
3769 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3770 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3771 endif
3772
3773 " Cleanup
3774 enew!
3775 new | only
3776
3777 call delete('F1')
3778 call delete('F2')
3779 call delete('F3')
3780endfunc
3781
3782func Test_qfjump()
3783 call Xqfjump_tests('c')
3784 call Xqfjump_tests('l')
3785endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003786
3787" Tests for the getqflist() and getloclist() functions when the list is not
3788" present or is empty
3789func Xgetlist_empty_tests(cchar)
3790 call s:setup_commands(a:cchar)
3791
3792 " Empty quickfix stack
3793 call g:Xsetlist([], 'f')
3794 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3795 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3796 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3797 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3798 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3799 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3800 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3801 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003802 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003803 if a:cchar == 'c'
3804 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003805 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003806 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3807 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003808 else
3809 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3810 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003811 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003812 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003813 \ g:Xgetlist({'all' : 0}))
3814 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003815
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003816 " Quickfix window with empty stack
3817 silent! Xopen
3818 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003819 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003820 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3821 Xclose
3822
Bram Moolenaara6d48492017-12-12 22:45:31 +01003823 " Empty quickfix list
3824 Xexpr ""
3825 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3826 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3827 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3828 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3829 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3830 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3831 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3832 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003833 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003834
3835 let qfid = g:Xgetlist({'id' : 0}).id
3836 call g:Xsetlist([], 'f')
3837
3838 " Non-existing quickfix identifier
3839 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3840 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3841 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3842 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3843 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3844 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3845 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3846 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003847 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003848 if a:cchar == 'c'
3849 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3850 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003851 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003852 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3853 else
3854 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3855 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003856 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3857 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003858 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3859 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003860
3861 " Non-existing quickfix list number
3862 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3863 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3864 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3865 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3866 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3867 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3868 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3869 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003870 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003871 if a:cchar == 'c'
3872 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3873 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003874 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3875 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003876 else
3877 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3878 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003879 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3880 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003881 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003882endfunc
3883
3884func Test_getqflist()
3885 call Xgetlist_empty_tests('c')
3886 call Xgetlist_empty_tests('l')
3887endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003888
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003889func Test_getqflist_invalid_nr()
3890 " The following commands used to crash Vim
3891 cexpr ""
3892 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3893
3894 " Cleanup
3895 call setqflist([], 'r')
3896endfunc
3897
Bram Moolenaarb254af32017-12-18 19:48:58 +01003898" Tests for the quickfix/location list changedtick
3899func Xqftick_tests(cchar)
3900 call s:setup_commands(a:cchar)
3901
3902 call g:Xsetlist([], 'f')
3903
3904 Xexpr "F1:10:Line10"
3905 let qfid = g:Xgetlist({'id' : 0}).id
3906 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3907 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3908 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3909 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3910 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3911 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3912 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3913 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3914 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3915
3916 enew!
3917 call append(0, ["F5:50:L50", "F6:60:L60"])
3918 Xaddbuffer
3919 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3920 enew!
3921
3922 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3923 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3924 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3925 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3926 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3927 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3928 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3929 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3930 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3931 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3932 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3933
3934 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3935 Xfile Xone
3936 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3937 Xaddfile Xone
3938 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3939
3940 " Test case for updating a non-current quickfix list
3941 call g:Xsetlist([], 'f')
3942 Xexpr "F1:1:L1"
3943 Xexpr "F2:2:L2"
3944 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3945 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3946 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3947
3948 call delete("Xone")
3949endfunc
3950
3951func Test_qf_tick()
3952 call Xqftick_tests('c')
3953 call Xqftick_tests('l')
3954endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003955
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003956" Test helpgrep with lang specifier
3957func Xtest_helpgrep_with_lang_specifier(cchar)
3958 call s:setup_commands(a:cchar)
3959 Xhelpgrep Vim@en
3960 call assert_equal('help', &filetype)
3961 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3962 new | only
3963endfunc
3964
3965func Test_helpgrep_with_lang_specifier()
3966 call Xtest_helpgrep_with_lang_specifier('c')
3967 call Xtest_helpgrep_with_lang_specifier('l')
3968endfunc
3969
Bram Moolenaar12237442017-12-19 12:38:52 +01003970" The following test used to crash Vim.
3971" Open the location list window and close the regular window associated with
3972" the location list. When the garbage collection runs now, it incorrectly
3973" marks the location list context as not in use and frees the context.
3974func Test_ll_window_ctx()
3975 call setloclist(0, [], 'f')
3976 call setloclist(0, [], 'a', {'context' : []})
3977 lopen | only
3978 call test_garbagecollect_now()
3979 echo getloclist(0, {'context' : 1}).context
3980 enew | only
3981endfunc
3982
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003983" The following test used to crash vim
3984func Test_lfile_crash()
3985 sp Xtest
3986 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003987 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003988 au! QuickFixCmdPre
3989endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003990
3991" The following test used to crash vim
3992func Test_lbuffer_crash()
3993 sv Xtest
3994 augroup QF_Test
3995 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003996 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003997 augroup END
3998 lbuffer
3999 augroup QF_Test
4000 au!
4001 augroup END
4002endfunc
4003
4004" The following test used to crash vim
4005func Test_lexpr_crash()
4006 augroup QF_Test
4007 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004008 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004009 augroup END
4010 lexpr ""
4011 augroup QF_Test
4012 au!
4013 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004014
Bram Moolenaar3c097222017-12-21 20:54:49 +01004015 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02004016 augroup QF_Test
4017 au!
4018 au BufNew * call setloclist(0, [], 'f')
4019 augroup END
4020 lexpr 'x:1:x'
4021 augroup QF_Test
4022 au!
4023 augroup END
4024
4025 enew | only
4026 lexpr ''
4027 lopen
4028 augroup QF_Test
4029 au!
4030 au FileType * call setloclist(0, [], 'f')
4031 augroup END
4032 lexpr ''
4033 augroup QF_Test
4034 au!
4035 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01004036endfunc
4037
4038" The following test used to crash Vim
4039func Test_lvimgrep_crash()
4040 sv Xtest
4041 augroup QF_Test
4042 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004043 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004044 augroup END
4045 lvimgrep quickfix test_quickfix.vim
4046 augroup QF_Test
4047 au!
4048 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004049
4050 new | only
4051 augroup QF_Test
4052 au!
4053 au BufEnter * call setloclist(0, [], 'r')
4054 augroup END
4055 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4056 augroup QF_Test
4057 au!
4058 augroup END
4059
Bram Moolenaar3c097222017-12-21 20:54:49 +01004060 enew | only
4061endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004062
Bram Moolenaar2573af32020-03-14 17:21:34 +01004063func Test_lvimgrep_crash2()
4064 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004065 call assert_fails('lvimgrep x x', 'E471:')
4066 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004067
4068 au! BufNewFile
4069endfunc
4070
Bram Moolenaarde046542017-12-26 13:53:11 +01004071" Test for the position of the quickfix and location list window
4072func Test_qfwin_pos()
4073 " Open two windows
4074 new | only
4075 new
4076 cexpr ['F1:10:L10']
4077 copen
4078 " Quickfix window should be the bottom most window
4079 call assert_equal(3, winnr())
4080 close
4081 " Open at the very top
4082 wincmd t
4083 topleft copen
4084 call assert_equal(1, winnr())
4085 close
4086 " open left of the current window
4087 wincmd t
4088 below new
4089 leftabove copen
4090 call assert_equal(2, winnr())
4091 close
4092 " open right of the current window
4093 rightbelow copen
4094 call assert_equal(3, winnr())
4095 close
4096endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004097
4098" Tests for quickfix/location lists changed by autocommands when
4099" :vimgrep/:lvimgrep commands are running.
4100func Test_vimgrep_autocmd()
4101 call setqflist([], 'f')
4102 call writefile(['stars'], 'Xtest1.txt')
4103 call writefile(['stars'], 'Xtest2.txt')
4104
4105 " Test 1:
4106 " When searching for a pattern using :vimgrep, if the quickfix list is
4107 " changed by an autocmd, the results should be added to the correct quickfix
4108 " list.
4109 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4110 silent vimgrep stars Xtest*.txt
4111 call assert_equal(1, getqflist({'nr' : 0}).nr)
4112 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4113 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4114 au! BufRead Xtest2.txt
4115
4116 " Test 2:
4117 " When searching for a pattern using :vimgrep, if the quickfix list is
4118 " freed, then a error should be given.
4119 silent! %bwipe!
4120 call setqflist([], 'f')
4121 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4122 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4123 au! BufRead Xtest2.txt
4124
4125 " Test 3:
4126 " When searching for a pattern using :lvimgrep, if the location list is
4127 " freed, then the command should error out.
4128 silent! %bwipe!
4129 let g:save_winid = win_getid()
4130 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4131 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4132 au! BufRead Xtest2.txt
4133
4134 call delete('Xtest1.txt')
4135 call delete('Xtest2.txt')
4136 call setqflist([], 'f')
4137endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004138
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004139" Test for an autocmd changing the current directory when running vimgrep
4140func Xvimgrep_autocmd_cd(cchar)
4141 call s:setup_commands(a:cchar)
4142
4143 %bwipe
4144 let save_cwd = getcwd()
4145
4146 augroup QF_Test
4147 au!
4148 autocmd BufRead * silent cd %:p:h
4149 augroup END
4150
4151 10Xvimgrep /vim/ Xdir/**
4152 let l = g:Xgetlist()
4153 call assert_equal('f1.txt', bufname(l[0].bufnr))
4154 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4155
4156 augroup QF_Test
4157 au!
4158 augroup END
4159
4160 exe 'cd ' . save_cwd
4161endfunc
4162
4163func Test_vimgrep_autocmd_cd()
4164 call mkdir('Xdir/a', 'p')
4165 call mkdir('Xdir/b', 'p')
4166 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4167 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4168 call Xvimgrep_autocmd_cd('c')
4169 call Xvimgrep_autocmd_cd('l')
4170 %bwipe
4171 call delete('Xdir', 'rf')
4172endfunc
4173
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004174" The following test used to crash Vim
4175func Test_lhelpgrep_autocmd()
4176 lhelpgrep quickfix
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004177 augroup QF_Test
4178 au!
4179 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4180 augroup END
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004181 lhelpgrep buffer
4182 call assert_equal('help', &filetype)
4183 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4184 lhelpgrep tabpage
4185 call assert_equal('help', &filetype)
4186 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004187 augroup QF_Test
4188 au!
4189 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004190
4191 new | only
4192 augroup QF_Test
4193 au!
4194 au BufEnter * call setqflist([], 'f')
4195 augroup END
4196 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004197 " run the test with a help window already open
4198 help
4199 wincmd w
4200 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004201 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004202 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004203 augroup END
4204
4205 new | only
4206 augroup QF_Test
4207 au!
4208 au BufEnter * call setqflist([], 'r')
4209 augroup END
4210 call assert_fails('helpgrep quickfix', 'E925:')
4211 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004212 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004213 augroup END
4214
4215 new | only
4216 augroup QF_Test
4217 au!
4218 au BufEnter * call setloclist(0, [], 'r')
4219 augroup END
4220 call assert_fails('lhelpgrep quickfix', 'E926:')
4221 augroup QF_Test
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004222 au!
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004223 augroup END
4224
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004225 " Replace the contents of a help window location list when it is still in
4226 " use.
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004227 new | only
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00004228 lhelpgrep quickfix
4229 wincmd w
4230 augroup QF_Test
4231 au!
4232 autocmd WinEnter * call setloclist(0, [], 'r')
4233 augroup END
4234 call assert_fails('lhelpgrep win_getid', 'E926:')
4235 augroup QF_Test
4236 au!
4237 augroup END
4238
4239 %bw!
4240endfunc
4241
4242" The following test used to crash Vim
4243func Test_lhelpgrep_autocmd_free_loclist()
4244 %bw!
4245 lhelpgrep quickfix
4246 wincmd w
4247 augroup QF_Test
4248 au!
4249 autocmd WinEnter * call setloclist(0, [], 'f')
4250 augroup END
4251 lhelpgrep win_getid
4252 wincmd w
4253 wincmd w
4254 wincmd w
4255 augroup QF_Test
4256 au!
4257 augroup END
4258 %bw!
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004259endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004260
4261" Test for shortening/simplifying the file name when opening the
4262" quickfix window or when displaying the quickfix list
4263func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004264 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004265 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004266 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004267 let fname = getcwd() . '/test_quickfix.vim'
4268 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4269 call assert_equal(fname, bufname('test_quickfix.vim'))
4270 " Opening the quickfix window should simplify the file path
4271 cwindow
4272 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4273 cclose
4274 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004275 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004276 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4277 call assert_equal(fname, bufname('test_quickfix.vim'))
4278 " Displaying the quickfix list should simplify the file path
4279 silent! clist
4280 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004281 " Add a few entries for the same file with different paths and check whether
4282 " the buffer name is shortened
4283 %bwipe
4284 call setqflist([], 'f')
4285 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4286 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4287 \ {'filename' : fname, 'lnum' : 30}], ' ')
4288 copen
4289 call assert_equal(['test_quickfix.vim|10| ',
4290 \ 'test_quickfix.vim|20| ',
4291 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4292 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004293endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004294
4295" Quickfix title tests
4296" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4297" Otherwise due to indentation, the title is set with spaces at the beginning
4298" of the command.
4299func Test_qftitle()
4300 call writefile(["F1:1:Line1"], 'Xerr')
4301
4302 " :cexpr
4303 exe "cexpr readfile('Xerr')"
4304 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4305
4306 " :cgetexpr
4307 exe "cgetexpr readfile('Xerr')"
4308 call assert_equal(":cgetexpr readfile('Xerr')",
4309 \ getqflist({'title' : 1}).title)
4310
4311 " :caddexpr
4312 call setqflist([], 'f')
4313 exe "caddexpr readfile('Xerr')"
4314 call assert_equal(":caddexpr readfile('Xerr')",
4315 \ getqflist({'title' : 1}).title)
4316
4317 " :cbuffer
4318 new Xerr
4319 exe "cbuffer"
4320 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4321
4322 " :cgetbuffer
4323 edit Xerr
4324 exe "cgetbuffer"
4325 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4326
4327 " :caddbuffer
4328 call setqflist([], 'f')
4329 edit Xerr
4330 exe "caddbuffer"
4331 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4332
4333 " :cfile
4334 exe "cfile Xerr"
4335 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4336
4337 " :cgetfile
4338 exe "cgetfile Xerr"
4339 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4340
4341 " :caddfile
4342 call setqflist([], 'f')
4343 exe "caddfile Xerr"
4344 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4345
4346 " :grep
4347 set grepprg=internal
4348 exe "grep F1 Xerr"
4349 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4350
4351 " :grepadd
4352 call setqflist([], 'f')
4353 exe "grepadd F1 Xerr"
4354 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4355 set grepprg&vim
4356
4357 " :vimgrep
4358 exe "vimgrep F1 Xerr"
4359 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4360
4361 " :vimgrepadd
4362 call setqflist([], 'f')
4363 exe "vimgrepadd F1 Xerr"
4364 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4365
4366 call setqflist(['F1:10:L10'], ' ')
4367 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4368
4369 call setqflist([], 'f')
4370 call setqflist(['F1:10:L10'], 'a')
4371 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4372
4373 call setqflist([], 'f')
4374 call setqflist(['F1:10:L10'], 'r')
4375 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4376
4377 close
4378 call delete('Xerr')
4379
4380 call setqflist([], ' ', {'title' : 'Errors'})
4381 copen
4382 call assert_equal('Errors', w:quickfix_title)
4383 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4384 call assert_equal('Errors', w:quickfix_title)
4385 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004386
4387 " Switching to another quickfix list in one tab page should update the
4388 " quickfix window title and statusline in all the other tab pages also
4389 call setqflist([], 'f')
4390 %bw!
4391 cgetexpr ['file_one:1:1: error in the first quickfix list']
4392 call setqflist([], 'a', {'title': 'first quickfix list'})
4393 cgetexpr ['file_two:2:1: error in the second quickfix list']
4394 call setqflist([], 'a', {'title': 'second quickfix list'})
4395 copen
4396 wincmd t
4397 tabnew two
4398 copen
4399 wincmd t
4400 colder
4401 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4402 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4403 call assert_equal(1, tabpagewinnr(1))
4404 call assert_equal(1, tabpagewinnr(2))
4405 tabnew
4406 call setqflist([], 'a', {'title': 'new quickfix title'})
4407 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4408 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4409 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004410endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004411
4412func Test_lbuffer_with_bwipe()
4413 new
4414 new
4415 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004416 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004417 augroup END
4418 lbuffer
4419 augroup nasty
4420 au!
4421 augroup END
4422endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004423
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004424" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4425" running
4426func Xexpr_acmd_freelist(cchar)
4427 call s:setup_commands(a:cchar)
4428
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004429 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004430 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004431 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004432 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004433 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004434 augroup nasty
4435 au!
4436 augroup END
4437endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004438
4439func Test_cexpr_acmd_freelist()
4440 call Xexpr_acmd_freelist('c')
4441 call Xexpr_acmd_freelist('l')
4442endfunc
4443
4444" Test for commands that create a new quickfix/location list and jump to the
4445" first error automatically.
4446func Xjumpto_first_error_test(cchar)
4447 call s:setup_commands(a:cchar)
4448
4449 call s:create_test_file('Xtestfile1')
4450 call s:create_test_file('Xtestfile2')
4451 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4452
4453 " Test for cexpr/lexpr
4454 enew
4455 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004456 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004457 call assert_equal(2, line('.'))
4458
4459 " Test for cfile/lfile
4460 enew
4461 call writefile(l, 'Xerr')
4462 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004463 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004464 call assert_equal(2, line('.'))
4465
4466 " Test for cbuffer/lbuffer
4467 edit Xerr
4468 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004469 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004470 call assert_equal(2, line('.'))
4471
4472 call delete('Xerr')
4473 call delete('Xtestfile1')
4474 call delete('Xtestfile2')
4475endfunc
4476
4477func Test_jumpto_first_error()
4478 call Xjumpto_first_error_test('c')
4479 call Xjumpto_first_error_test('l')
4480endfunc
4481
4482" Test for a quickfix autocmd changing the quickfix/location list before
4483" jumping to the first error in the new list.
4484func Xautocmd_changelist(cchar)
4485 call s:setup_commands(a:cchar)
4486
4487 " Test for cfile/lfile
4488 call s:create_test_file('Xtestfile1')
4489 call s:create_test_file('Xtestfile2')
4490 Xexpr 'Xtestfile1:2:Line2'
4491 autocmd QuickFixCmdPost * Xolder
4492 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4493 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004494 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004495 call assert_equal(4, line('.'))
4496 autocmd! QuickFixCmdPost
4497
4498 " Test for cbuffer/lbuffer
4499 call g:Xsetlist([], 'f')
4500 Xexpr 'Xtestfile1:2:Line2'
4501 autocmd QuickFixCmdPost * Xolder
4502 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4503 edit Xerr
4504 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004505 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004506 call assert_equal(4, line('.'))
4507 autocmd! QuickFixCmdPost
4508
4509 " Test for cexpr/lexpr
4510 call g:Xsetlist([], 'f')
4511 Xexpr 'Xtestfile1:2:Line2'
4512 autocmd QuickFixCmdPost * Xolder
4513 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004514 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004515 call assert_equal(4, line('.'))
4516 autocmd! QuickFixCmdPost
4517
Bram Moolenaar851332e2018-07-03 19:16:00 +02004518 " The grepprg may not be set on non-Unix systems
4519 if has('unix')
4520 " Test for grep/lgrep
4521 call g:Xsetlist([], 'f')
4522 Xexpr 'Xtestfile1:2:Line2'
4523 autocmd QuickFixCmdPost * Xolder
4524 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004525 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004526 call assert_equal(5, line('.'))
4527 autocmd! QuickFixCmdPost
4528 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004529
4530 " Test for vimgrep/lvimgrep
4531 call g:Xsetlist([], 'f')
4532 Xexpr 'Xtestfile1:2:Line2'
4533 autocmd QuickFixCmdPost * Xolder
4534 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004535 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004536 call assert_equal(5, line('.'))
4537 autocmd! QuickFixCmdPost
4538
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004539 " Test for autocommands clearing the quickfix list before jumping to the
4540 " first error. This should not result in an error
4541 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4542 let v:errmsg = ''
4543 " Test for cfile/lfile
4544 Xfile Xerr
4545 call assert_true(v:errmsg !~# 'E42:')
4546 " Test for cbuffer/lbuffer
4547 edit Xerr
4548 Xbuffer
4549 call assert_true(v:errmsg !~# 'E42:')
4550 " Test for cexpr/lexpr
4551 Xexpr 'Xtestfile2:4:Line4'
4552 call assert_true(v:errmsg !~# 'E42:')
4553 " Test for grep/lgrep
4554 " The grepprg may not be set on non-Unix systems
4555 if has('unix')
4556 silent Xgrep Line5 Xtestfile2
4557 call assert_true(v:errmsg !~# 'E42:')
4558 endif
4559 " Test for vimgrep/lvimgrep
4560 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4561 autocmd! QuickFixCmdPost
4562
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004563 call delete('Xerr')
4564 call delete('Xtestfile1')
4565 call delete('Xtestfile2')
4566endfunc
4567
4568func Test_autocmd_changelist()
4569 call Xautocmd_changelist('c')
4570 call Xautocmd_changelist('l')
4571endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004572
4573" Tests for the ':filter /pat/ clist' command
4574func Test_filter_clist()
4575 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4576 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4577 \ split(execute('filter /Line 15/ clist'), "\n"))
4578 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4579 \ split(execute('filter /Xfile1/ clist'), "\n"))
4580 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4581
4582 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4583 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4584 call assert_equal([' 2 pqr:pat2: '],
4585 \ split(execute('filter /pqr/ clist'), "\n"))
4586 call assert_equal([' 1 abc:pat1: '],
4587 \ split(execute('filter /pat1/ clist'), "\n"))
4588endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004589
4590" Tests for the "CTRL-W <CR>" command.
4591func Xview_result_split_tests(cchar)
4592 call s:setup_commands(a:cchar)
4593
4594 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4595 call g:Xsetlist([])
4596 Xopen
4597 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004598 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004599 call assert_equal(l:win_count, winnr('$'))
4600 Xclose
4601endfunc
4602
4603func Test_view_result_split()
4604 call Xview_result_split_tests('c')
4605 call Xview_result_split_tests('l')
4606endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004607
4608" Test that :cc sets curswant
4609func Test_curswant()
4610 helpgrep quickfix
4611 normal! llll
4612 1cc
4613 call assert_equal(getcurpos()[4], virtcol('.'))
4614 cclose | helpclose
4615endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004616
4617" Test for opening a file from the quickfix window using CTRL-W <Enter>
4618" doesn't leave an empty buffer around.
4619func Test_splitview()
4620 call s:create_test_file('Xtestfile1')
4621 call s:create_test_file('Xtestfile2')
4622 new | only
4623 let last_bufnr = bufnr('Test_sv_1', 1)
4624 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4625 cgetexpr l
4626 copen
4627 let numbufs = len(getbufinfo())
4628 exe "normal \<C-W>\<CR>"
4629 copen
4630 exe "normal j\<C-W>\<CR>"
4631 " Make sure new empty buffers are not created
4632 call assert_equal(numbufs, len(getbufinfo()))
4633 " Creating a new buffer should use the next available buffer number
4634 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4635 bwipe Test_sv_1
4636 bwipe Test_sv_2
4637 new | only
4638
4639 " When split opening files from location list window, make sure that two
4640 " windows doesn't refer to the same location list
4641 lgetexpr l
4642 let locid = getloclist(0, {'id' : 0}).id
4643 lopen
4644 exe "normal \<C-W>\<CR>"
4645 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4646 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4647 new | only
4648
4649 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004650 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004651 lhelpgrep window
4652 let locid = getloclist(0, {'id' : 0}).id
4653 lwindow
4654 exe "normal j\<C-W>\<CR>"
4655 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4656 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4657 new | only
4658
Bram Moolenaar406cd902020-02-18 21:54:41 +01004659 " Using :split or :vsplit from a quickfix window should behave like a :new
4660 " or a :vnew command
4661 copen
4662 split
4663 call assert_equal(3, winnr('$'))
4664 let l = getwininfo()
4665 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4666 close
4667 copen
4668 vsplit
4669 let l = getwininfo()
4670 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4671 new | only
4672
Bram Moolenaarb2443732018-11-11 22:50:27 +01004673 call delete('Xtestfile1')
4674 call delete('Xtestfile2')
4675endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004676
4677" Test for parsing entries using visual screen column
4678func Test_viscol()
4679 enew
4680 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4681 edit Xfile1
4682
4683 " Use byte offset for column number
4684 set efm&
4685 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4686 call assert_equal([5, 8], [col('.'), virtcol('.')])
4687 cnext
4688 call assert_equal([9, 12], [col('.'), virtcol('.')])
4689 cnext
4690 call assert_equal([14, 20], [col('.'), virtcol('.')])
4691
4692 " Use screen column offset for column number
4693 set efm=%f:%l:%v:%m
4694 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4695 call assert_equal([5, 8], [col('.'), virtcol('.')])
4696 cnext
4697 call assert_equal([9, 12], [col('.'), virtcol('.')])
4698 cnext
4699 call assert_equal([14, 20], [col('.'), virtcol('.')])
4700 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4701 call assert_equal([5, 8], [col('.'), virtcol('.')])
4702 cnext
4703 call assert_equal([10, 16], [col('.'), virtcol('.')])
4704 cnext
4705 call assert_equal([14, 20], [col('.'), virtcol('.')])
4706
4707 enew
4708 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4709
4710 " Use byte offset for column number
4711 set efm&
4712 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4713 call assert_equal([8, 10], [col('.'), virtcol('.')])
4714 cnext
4715 call assert_equal([11, 17], [col('.'), virtcol('.')])
4716 cnext
4717 call assert_equal([16, 25], [col('.'), virtcol('.')])
4718
4719 " Use screen column offset for column number
4720 set efm=%f:%l:%v:%m
4721 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4722 call assert_equal([8, 10], [col('.'), virtcol('.')])
4723 cnext
4724 call assert_equal([11, 17], [col('.'), virtcol('.')])
4725 cnext
4726 call assert_equal([16, 25], [col('.'), virtcol('.')])
4727
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004728 " Use screen column number with a multi-line error message
4729 enew
4730 call writefile(["à test"], 'Xfile1')
4731 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4732 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4733 call assert_equal('Xfile1', @%)
4734 call assert_equal([0, 1, 4, 0], getpos('.'))
4735
4736 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4737 " does not break this
4738 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4739 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4740 call assert_equal('Xfile1', @%)
4741 call assert_equal([0, 1, 3, 0], getpos('.'))
4742
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004743 enew | only
4744 set efm&
4745 call delete('Xfile1')
4746endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004747
4748" Test for the quickfix window buffer
4749func Xqfbuf_test(cchar)
4750 call s:setup_commands(a:cchar)
4751
4752 " Quickfix buffer should be reused across closing and opening a quickfix
4753 " window
4754 Xexpr "F1:10:Line10"
4755 Xopen
4756 let qfbnum = bufnr('')
4757 Xclose
4758 " Even after the quickfix window is closed, the buffer should be loaded
4759 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004760 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004761 Xopen
4762 " Buffer should be reused when opening the window again
4763 call assert_equal(qfbnum, bufnr(''))
4764 Xclose
4765
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004766 " When quickfix buffer is wiped out, getqflist() should return 0
4767 %bw!
4768 Xexpr ""
4769 Xopen
4770 bw!
4771 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4772
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004773 if a:cchar == 'l'
4774 %bwipe
4775 " For a location list, when both the file window and the location list
4776 " window for the list are closed, then the buffer should be freed.
4777 new | only
4778 lexpr "F1:10:Line10"
4779 let wid = win_getid()
4780 lopen
4781 let qfbnum = bufnr('')
4782 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4783 close
4784 " When the location list window is closed, the buffer name should not
4785 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004786 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004787 call assert_true(bufloaded(qfbnum))
4788
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004789 " After deleting a location list buffer using ":bdelete", opening the
4790 " location list window should mark the buffer as a location list buffer.
4791 exe "bdelete " . qfbnum
4792 lopen
4793 call assert_equal("quickfix", &buftype)
4794 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4795 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4796 call assert_false(&swapfile)
4797 lclose
4798
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004799 " When the location list is cleared for the window, the buffer should be
4800 " removed
4801 call setloclist(0, [], 'f')
4802 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004803 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004804
4805 " When the location list is freed with the location list window open, the
4806 " location list buffer should not be lost. It should be reused when the
4807 " location list is again populated.
4808 lexpr "F1:10:Line10"
4809 lopen
4810 let wid = win_getid()
4811 let qfbnum = bufnr('')
4812 wincmd p
4813 call setloclist(0, [], 'f')
4814 lexpr "F1:10:Line10"
4815 lopen
4816 call assert_equal(wid, win_getid())
4817 call assert_equal(qfbnum, bufnr(''))
4818 lclose
4819
4820 " When the window with the location list is closed, the buffer should be
4821 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004822 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004823 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004824 endif
4825endfunc
4826
4827func Test_qfbuf()
4828 call Xqfbuf_test('c')
4829 call Xqfbuf_test('l')
4830endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004831
4832" If there is an autocmd to use only one window, then opening the location
4833" list window used to crash Vim.
4834func Test_winonly_autocmd()
4835 call s:create_test_file('Xtest1')
4836 " Autocmd to show only one Vim window at a time
4837 autocmd WinEnter * only
4838 new
4839 " Load the location list
4840 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4841 let loclistid = getloclist(0, {'id' : 0}).id
4842 " Open the location list window. Only this window will be shown and the file
4843 " window is closed.
4844 lopen
4845 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4846 " Jump to an entry in the location list and make sure that the cursor is
4847 " positioned correctly.
4848 ll 3
4849 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004850 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004851 call assert_equal(15, line('.'))
4852 " Cleanup
4853 autocmd! WinEnter
4854 new | only
4855 call delete('Xtest1')
4856endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004857
4858" Test to make sure that an empty quickfix buffer is not reused for loading
4859" a normal buffer.
4860func Test_empty_qfbuf()
4861 enew | only
4862 call writefile(["Test"], 'Xfile1')
4863 call setqflist([], 'f')
4864 copen | only
4865 let qfbuf = bufnr('')
4866 edit Xfile1
4867 call assert_notequal(qfbuf, bufnr(''))
4868 enew
4869 call delete('Xfile1')
4870endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004871
4872" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004873" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004874func Xtest_below(cchar)
4875 call s:setup_commands(a:cchar)
4876
4877 " No quickfix/location list
4878 call assert_fails('Xbelow', 'E42:')
4879 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004880 call assert_fails('Xbefore', 'E42:')
4881 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004882
4883 " Empty quickfix/location list
4884 call g:Xsetlist([])
4885 call assert_fails('Xbelow', 'E42:')
4886 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004887 call assert_fails('Xbefore', 'E42:')
4888 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004889
4890 call s:create_test_file('X1')
4891 call s:create_test_file('X2')
4892 call s:create_test_file('X3')
4893 call s:create_test_file('X4')
4894
4895 " Invalid entries
4896 edit X1
4897 call g:Xsetlist(["E1", "E2"])
4898 call assert_fails('Xbelow', 'E42:')
4899 call assert_fails('Xabove', 'E42:')
4900 call assert_fails('3Xbelow', 'E42:')
4901 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004902 call assert_fails('Xbefore', 'E42:')
4903 call assert_fails('Xafter', 'E42:')
4904 call assert_fails('3Xbefore', 'E42:')
4905 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004906
4907 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004908 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 +02004909 edit +7 X2
4910 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004911 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004912 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004913 normal 7G
4914 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004915 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004916 call assert_fails('Xbefore', 'E553:')
4917
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004918 normal 2j
4919 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004920 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004921 normal 7G
4922 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004923 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004924
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004925 " Last error in this file
4926 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004927 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004928 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004929 normal gg
4930 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004931 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004932 call assert_fails('Xafter', 'E553:')
4933
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004934 " First error in this file
4935 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004936 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004937 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004938 normal G
4939 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004940 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004941 call assert_fails('Xbefore', 'E553:')
4942
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004943 normal gg
4944 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004945 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004946 normal gg
4947 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004948 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004949
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004950 normal G
4951 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004952 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004953 normal G
4954 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004955 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004956
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004957 edit X4
4958 call assert_fails('Xabove', 'E42:')
4959 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004960 call assert_fails('Xbefore', 'E42:')
4961 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004962 if a:cchar == 'l'
4963 " If a buffer has location list entries from some other window but not
4964 " from the current window, then the commands should fail.
4965 edit X1 | split | call setloclist(0, [], 'f')
4966 call assert_fails('Xabove', 'E776:')
4967 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004968 call assert_fails('Xbefore', 'E776:')
4969 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004970 close
4971 endif
4972
4973 " Test for lines with multiple quickfix entries
4974 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4975 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4976 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4977 edit +1 X2
4978 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004979 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004980 normal 1G
4981 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004982 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004983
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004984 normal gg
4985 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004986 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004987 normal gg
4988 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004989 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004990
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004991 normal G
4992 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004993 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004994 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004995 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004996 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004997
4998 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004999 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005000 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005001 normal G
5002 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005003 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005004
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005005 normal 10G
5006 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005007 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005008 normal 10G$
5009 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005010 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005011
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005012 normal 10G
5013 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005014 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005015 normal 9G
5016 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02005017 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005018
5019 " Invalid range
5020 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02005021 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005022 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005023 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02005024 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02005025 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02005026 endif
5027
5028 call delete('X1')
5029 call delete('X2')
5030 call delete('X3')
5031 call delete('X4')
5032endfunc
5033
5034func Test_cbelow()
5035 call Xtest_below('c')
5036 call Xtest_below('l')
5037endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02005038
5039func Test_quickfix_count()
5040 let commands = [
5041 \ 'cNext',
5042 \ 'cNfile',
5043 \ 'cabove',
5044 \ 'cbelow',
5045 \ 'cfirst',
5046 \ 'clast',
5047 \ 'cnewer',
5048 \ 'cnext',
5049 \ 'cnfile',
5050 \ 'colder',
5051 \ 'cprevious',
5052 \ 'crewind',
5053 \
5054 \ 'lNext',
5055 \ 'lNfile',
5056 \ 'labove',
5057 \ 'lbelow',
5058 \ 'lfirst',
5059 \ 'llast',
5060 \ 'lnewer',
5061 \ 'lnext',
5062 \ 'lnfile',
5063 \ 'lolder',
5064 \ 'lprevious',
5065 \ 'lrewind',
5066 \ ]
5067 for cmd in commands
5068 call assert_fails('-1' .. cmd, 'E16:')
5069 call assert_fails('.' .. cmd, 'E16:')
5070 call assert_fails('%' .. cmd, 'E16:')
5071 call assert_fails('$' .. cmd, 'E16:')
5072 endfor
5073endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005074
5075" Test for aborting quickfix commands using QuickFixCmdPre
5076func Xtest_qfcmd_abort(cchar)
5077 call s:setup_commands(a:cchar)
5078
5079 call g:Xsetlist([], 'f')
5080
5081 " cexpr/lexpr
5082 let e = ''
5083 try
5084 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5085 catch /.*/
5086 let e = v:exception
5087 endtry
5088 call assert_equal('AbortCmd', e)
5089 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5090
5091 " cfile/lfile
5092 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
5093 let e = ''
5094 try
5095 Xfile Xfile1
5096 catch /.*/
5097 let e = v:exception
5098 endtry
5099 call assert_equal('AbortCmd', e)
5100 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5101 call delete('Xfile1')
5102
5103 " cgetbuffer/lgetbuffer
5104 enew!
5105 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5106 let e = ''
5107 try
5108 Xgetbuffer
5109 catch /.*/
5110 let e = v:exception
5111 endtry
5112 call assert_equal('AbortCmd', e)
5113 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5114 enew!
5115
5116 " vimgrep/lvimgrep
5117 let e = ''
5118 try
5119 Xvimgrep /func/ test_quickfix.vim
5120 catch /.*/
5121 let e = v:exception
5122 endtry
5123 call assert_equal('AbortCmd', e)
5124 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5125
5126 " helpgrep/lhelpgrep
5127 let e = ''
5128 try
5129 Xhelpgrep quickfix
5130 catch /.*/
5131 let e = v:exception
5132 endtry
5133 call assert_equal('AbortCmd', e)
5134 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5135
5136 " grep/lgrep
5137 if has('unix')
5138 let e = ''
5139 try
5140 silent Xgrep func test_quickfix.vim
5141 catch /.*/
5142 let e = v:exception
5143 endtry
5144 call assert_equal('AbortCmd', e)
5145 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5146 endif
5147endfunc
5148
5149func Test_qfcmd_abort()
5150 augroup QF_Test
5151 au!
5152 autocmd QuickFixCmdPre * throw "AbortCmd"
5153 augroup END
5154
5155 call Xtest_qfcmd_abort('c')
5156 call Xtest_qfcmd_abort('l')
5157
5158 augroup QF_Test
5159 au!
5160 augroup END
5161endfunc
5162
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005163" Test for using a file in one of the parent directories.
5164func Test_search_in_dirstack()
5165 call mkdir('Xtestdir/a/b/c', 'p')
5166 let save_cwd = getcwd()
5167 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5168 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5169 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5170 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5171
5172 let lines = "Entering dir Xtestdir\n" .
5173 \ "Entering dir a\n" .
5174 \ "Entering dir b\n" .
5175 \ "Xfile2:2:X2_L2\n" .
5176 \ "Leaving dir a\n" .
5177 \ "Xfile1:2:X1_L2\n" .
5178 \ "Xfile3:1:X3_L1\n" .
5179 \ "Entering dir c\n" .
5180 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005181 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005182 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005183 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005184 call assert_equal(11, getqflist({'size' : 0}).size)
5185 call assert_equal(4, getqflist({'idx' : 0}).idx)
5186 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005187 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005188 cnext
5189 call assert_equal(6, getqflist({'idx' : 0}).idx)
5190 call assert_equal('X1_L2', getline('.'))
5191 cnext
5192 call assert_equal(7, getqflist({'idx' : 0}).idx)
5193 call assert_equal(1, line('$'))
5194 call assert_equal('', getline(1))
5195 cnext
5196 call assert_equal(9, getqflist({'idx' : 0}).idx)
5197 call assert_equal(1, line('$'))
5198 call assert_equal('', getline(1))
5199
5200 set efm&
5201 exe 'cd ' . save_cwd
5202 call delete('Xtestdir', 'rf')
5203endfunc
5204
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005205" Test for :cquit
5206func Test_cquit()
5207 " Exit Vim with a non-zero value
5208 if RunVim([], ["cquit 7"], '')
5209 call assert_equal(7, v:shell_error)
5210 endif
5211
5212 if RunVim([], ["50cquit"], '')
5213 call assert_equal(50, v:shell_error)
5214 endif
5215
5216 " Exit Vim with default value
5217 if RunVim([], ["cquit"], '')
5218 call assert_equal(1, v:shell_error)
5219 endif
5220
5221 " Exit Vim with zero value
5222 if RunVim([], ["cquit 0"], '')
5223 call assert_equal(0, v:shell_error)
5224 endif
5225
5226 " Exit Vim with negative value
5227 call assert_fails('-3cquit', 'E16:')
5228endfunc
5229
Bram Moolenaar858ba062020-05-31 23:11:59 +02005230" Test for getting a specific item from a quickfix list
5231func Xtest_getqflist_by_idx(cchar)
5232 call s:setup_commands(a:cchar)
5233 " Empty list
5234 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5235 Xexpr ['F1:10:L10', 'F1:20:L20']
5236 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5237 call assert_equal(bufnr('F1'), l[0].bufnr)
5238 call assert_equal(20, l[0].lnum)
5239 call assert_equal('L20', l[0].text)
5240 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5241 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005242 call assert_equal({}, g:Xgetlist(#{idx: "abc"}))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005243 %bwipe!
5244endfunc
5245
5246func Test_getqflist_by_idx()
5247 call Xtest_getqflist_by_idx('c')
5248 call Xtest_getqflist_by_idx('l')
5249endfunc
5250
5251" Test for the 'quickfixtextfunc' setting
5252func Tqfexpr(info)
5253 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005254 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005255 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005256 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005257 endif
5258
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005259 let l = []
5260 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5261 let e = qfl[idx]
5262 let s = ''
5263 if e.bufnr != 0
5264 let bname = bufname(e.bufnr)
5265 let s ..= fnamemodify(bname, ':.')
5266 endif
5267 let s ..= '-'
5268 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5269 let s ..= e.text
5270 call add(l, s)
5271 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005272
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005273 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005274endfunc
5275
5276func Xtest_qftextfunc(cchar)
5277 call s:setup_commands(a:cchar)
5278
5279 set efm=%f:%l:%c:%m
5280 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005281 call assert_equal('Tqfexpr', &quickfixtextfunc)
5282 call assert_equal('',
5283 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005284 call g:Xsetlist([
5285 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5286 \ 'end_col': 7, 'text': 'green'},
5287 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5288 \ 'end_col': 8, 'text': 'blue'},
5289 \ ])
5290
Bram Moolenaar858ba062020-05-31 23:11:59 +02005291 Xwindow
5292 call assert_equal('F1-L10C2-green', getline(1))
5293 call assert_equal('F1-L20C4-blue', getline(2))
5294 Xclose
5295 set quickfixtextfunc&vim
5296 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005297 call assert_equal('F1|10 col 2-7| green', getline(1))
5298 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005299 Xclose
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00005300
5301 set efm=%f:%l:%c:%m
5302 set quickfixtextfunc=Tqfexpr
5303 " Update the list with only the cwindow
5304 Xwindow
5305 only
5306 call g:Xsetlist([
5307 \ { 'filename': 'F2', 'lnum': 20, 'col': 2,
5308 \ 'end_col': 7, 'text': 'red'}
5309 \ ])
5310 call assert_equal(['F2-L20C2-red'], getline(1, '$'))
5311 new
5312 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005313 set efm&
5314 set quickfixtextfunc&
5315
5316 " Test for per list 'quickfixtextfunc' setting
5317 func PerQfText(info)
5318 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005319 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005320 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005321 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005322 endif
5323 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005324 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005325 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005326 let l = []
5327 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5328 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5329 endfor
5330 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005331 endfunc
5332 set quickfixtextfunc=Tqfexpr
5333 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5334 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5335 Xwindow
5336 call assert_equal('Line 10, Col 2', getline(1))
5337 call assert_equal('Line 20, Col 4', getline(2))
5338 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005339 call assert_equal(function('PerQfText'),
5340 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005341 " Add entries to the list when the quickfix buffer is hidden
5342 Xaddexpr ['F1:30:6:red']
5343 Xwindow
5344 call assert_equal('Line 30, Col 6', getline(3))
5345 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005346 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005347 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005348 set quickfixtextfunc&
5349 delfunc PerQfText
5350
5351 " Non-existing function
5352 set quickfixtextfunc=Tabc
5353 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5354 call assert_fails("Xwindow", 'E117:')
5355 Xclose
5356 set quickfixtextfunc&
5357
5358 " set option to a non-function
5359 set quickfixtextfunc=[10,\ 20]
5360 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5361 call assert_fails("Xwindow", 'E117:')
5362 Xclose
5363 set quickfixtextfunc&
5364
5365 " set option to a function with different set of arguments
5366 func Xqftext(a, b, c)
5367 return a:a .. a:b .. a:c
5368 endfunc
5369 set quickfixtextfunc=Xqftext
5370 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5371 call assert_fails("Xwindow", 'E119:')
5372 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005373
5374 " set option to a function that returns a list with non-strings
5375 func Xqftext2(d)
5376 return ['one', [], 'two']
5377 endfunc
5378 set quickfixtextfunc=Xqftext2
5379 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5380 \ 'E730:')
5381 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005382 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5383 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005384 Xclose
5385
Bram Moolenaar858ba062020-05-31 23:11:59 +02005386 set quickfixtextfunc&
5387 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005388 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005389
5390 " set the global option to a lambda function
5391 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5392 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5393 Xwindow
5394 call assert_equal(['green', 'blue'], getline(1, '$'))
5395 Xclose
5396 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)
5397 set quickfixtextfunc&
5398
5399 " use a lambda function that returns an empty list
5400 set quickfixtextfunc={d\ ->\ []}
5401 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5402 Xwindow
5403 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5404 \ getline(1, '$'))
5405 Xclose
5406 set quickfixtextfunc&
5407
5408 " use a lambda function that returns a list with empty strings
5409 set quickfixtextfunc={d\ ->\ ['',\ '']}
5410 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5411 Xwindow
5412 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5413 \ getline(1, '$'))
5414 Xclose
5415 set quickfixtextfunc&
5416
5417 " set the per-quickfix list text function to a lambda function
5418 call g:Xsetlist([], ' ',
5419 \ {'quickfixtextfunc' :
5420 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5421 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5422 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5423 Xwindow
5424 call assert_equal('Line 10, Col 2', getline(1))
5425 call assert_equal('Line 20, Col 4', getline(2))
5426 Xclose
5427 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5428 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005429endfunc
5430
5431func Test_qftextfunc()
5432 call Xtest_qftextfunc('c')
5433 call Xtest_qftextfunc('l')
5434endfunc
5435
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005436func Test_qftextfunc_callback()
5437 let lines =<< trim END
5438 set efm=%f:%l:%c:%m
5439
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005440 #" Test for using a function name
5441 LET &qftf = 'g:Tqfexpr'
5442 cexpr "F0:0:0:L0"
5443 copen
5444 call assert_equal('F0-L0C0-L0', getline(1))
5445 cclose
5446
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005447 #" Test for using a function()
5448 set qftf=function('g:Tqfexpr')
5449 cexpr "F1:1:1:L1"
5450 copen
5451 call assert_equal('F1-L1C1-L1', getline(1))
5452 cclose
5453
5454 #" Using a funcref variable to set 'quickfixtextfunc'
5455 VAR Fn = function('g:Tqfexpr')
5456 LET &qftf = Fn
5457 cexpr "F2:2:2:L2"
5458 copen
5459 call assert_equal('F2-L2C2-L2', getline(1))
5460 cclose
5461
5462 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5463 LET Fn = function('g:Tqfexpr')
5464 LET &qftf = string(Fn)
5465 cexpr "F3:3:3:L3"
5466 copen
5467 call assert_equal('F3-L3C3-L3', getline(1))
5468 cclose
5469
5470 #" Test for using a funcref()
5471 set qftf=funcref('g:Tqfexpr')
5472 cexpr "F4:4:4:L4"
5473 copen
5474 call assert_equal('F4-L4C4-L4', getline(1))
5475 cclose
5476
5477 #" Using a funcref variable to set 'quickfixtextfunc'
5478 LET Fn = funcref('g:Tqfexpr')
5479 LET &qftf = Fn
5480 cexpr "F5:5:5:L5"
5481 copen
5482 call assert_equal('F5-L5C5-L5', getline(1))
5483 cclose
5484
5485 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5486 LET Fn = funcref('g:Tqfexpr')
5487 LET &qftf = string(Fn)
5488 cexpr "F5:5:5:L5"
5489 copen
5490 call assert_equal('F5-L5C5-L5', getline(1))
5491 cclose
5492
5493 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005494 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005495 LET optval = substitute(optval, ' ', '\\ ', 'g')
5496 exe "set qftf=" .. optval
5497 cexpr "F6:6:6:L6"
5498 copen
5499 call assert_equal('F6-L6C6-L6', getline(1))
5500 cclose
5501
5502 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005503 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005504 cexpr "F7:7:7:L7"
5505 copen
5506 call assert_equal('F7-L7C7-L7', getline(1))
5507 cclose
5508
5509 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005510 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005511 cexpr "F8:8:8:L8"
5512 copen
5513 call assert_equal('F8-L8C8-L8', getline(1))
5514 cclose
5515
5516 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005517 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005518 LET &qftf = Lambda
5519 cexpr "F9:9:9:L9"
5520 copen
5521 call assert_equal('F9-L9C9-L9', getline(1))
5522 cclose
5523
5524 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005525 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005526 LET &qftf = string(Lambda)
5527 cexpr "F9:9:9:L9"
5528 copen
5529 call assert_equal('F9-L9C9-L9', getline(1))
5530 cclose
5531 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005532 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005533
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005534 " Test for using a script-local function name
5535 func s:TqfFunc2(info)
5536 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5537 return ''
5538 endfunc
5539 let g:TqfFunc2Args = []
5540 set quickfixtextfunc=s:TqfFunc2
5541 cexpr "F10:10:10:L10"
5542 cclose
5543 call assert_equal([1, 1], g:TqfFunc2Args)
5544
5545 let &quickfixtextfunc = 's:TqfFunc2'
5546 cexpr "F11:11:11:L11"
5547 cclose
5548 call assert_equal([1, 1], g:TqfFunc2Args)
5549 delfunc s:TqfFunc2
5550
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005551 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5552 func SetQftfFunc()
5553 let params = {'qftf': function('g:DictQftfFunc')}
5554 let &quickfixtextfunc = params.qftf
5555 endfunc
5556 func g:DictQftfFunc(_) dict
5557 endfunc
5558 call SetQftfFunc()
5559 new
5560 call SetQftfFunc()
5561 bw
5562 call test_garbagecollect_now()
5563 new
5564 set qftf=
5565 wincmd w
5566 set qftf=
5567 :%bw!
5568
5569 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5570 " to cause a crash.
5571 let &qftf = ''
5572 func SetLocalQftfFunc()
5573 let params = {'qftf': function('g:DictQftfFunc')}
5574 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5575 endfunc
5576 call SetLocalQftfFunc()
5577 call test_garbagecollect_now()
5578 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5579 delfunc g:DictQftfFunc
5580 delfunc SetQftfFunc
5581 delfunc SetLocalQftfFunc
5582 set efm&
5583endfunc
5584
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005585" Test for updating a location list for some other window and check that
5586" 'qftextfunc' uses the correct location list.
5587func Test_qftextfunc_other_loclist()
5588 %bw!
5589 call setloclist(0, [], 'f')
5590
5591 " create a window and a location list for it and open the location list
5592 " window
5593 lexpr ['F1:10:12:one', 'F1:20:14:two']
5594 let w1_id = win_getid()
5595 call setloclist(0, [], ' ',
5596 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5597 \ 'quickfixtextfunc':
5598 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5599 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5600 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5601 lwindow
5602 let w2_id = win_getid()
5603
5604 " create another window and a location list for it and open the location
5605 " list window
5606 topleft new
5607 let w3_id = win_getid()
5608 call setloclist(0, [], ' ',
5609 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5610 \ 'quickfixtextfunc':
5611 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5612 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5613 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5614 lwindow
5615 let w4_id = win_getid()
5616
5617 topleft new
5618 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5619 let w5_id = win_getid()
5620
5621 " change the location list for some other window
5622 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5623 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5624 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5625 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5626 \ getbufline(winbufnr(w2_id), 1, '$'))
5627 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5628 \ getbufline(winbufnr(w4_id), 1, '$'))
5629 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5630 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5631 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5632 \ getbufline(winbufnr(w2_id), 1, '$'))
5633 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5634 \ getbufline(winbufnr(w4_id), 1, '$'))
5635
5636 call win_gotoid(w5_id)
5637 lwindow
5638 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5639 \ getline(1, '$'))
5640 %bw!
5641endfunc
5642
Bram Moolenaarec98e932020-06-08 19:35:59 +02005643" Running :lhelpgrep command more than once in a help window, doesn't jump to
5644" the help topic
5645func Test_lhelpgrep_from_help_window()
5646 call mkdir('Xtestdir/doc', 'p')
5647 call writefile(['window'], 'Xtestdir/doc/a.txt')
5648 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5649 let save_rtp = &rtp
5650 let &rtp = 'Xtestdir'
5651 lhelpgrep window
5652 lhelpgrep buffer
5653 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5654 lhelpgrep window
5655 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5656 let &rtp = save_rtp
5657 call delete('Xtestdir', 'rf')
5658 new | only!
5659endfunc
5660
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005661" Test for the crash fixed by 7.3.715
5662func Test_setloclist_crash()
5663 %bw!
5664 let g:BufNum = bufnr()
5665 augroup QF_Test
5666 au!
5667 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5668 augroup END
5669
5670 try
5671 lvimgrep /.*/ *.mak
5672 catch /E926:/
5673 endtry
5674 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5675 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5676
5677 augroup QF_Test
5678 au!
5679 augroup END
5680 unlet g:BufNum
5681 %bw!
5682endfunc
5683
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005684" Test for adding an invalid entry with the quickfix window open and making
5685" sure that the window contents are not changed
5686func Test_add_invalid_entry_with_qf_window()
5687 call setqflist([], 'f')
5688 cexpr "Xfile1:10:aa"
5689 copen
5690 call setqflist(['bb'], 'a')
5691 call assert_equal(1, line('$'))
5692 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005693 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())
5694
5695 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5696 call assert_equal(1 , line('$'))
5697 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5698 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())
5699
5700 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')
5701 call assert_equal(1 , line('$'))
5702 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5703 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())
5704
5705 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')
5706 call assert_equal(1 , line('$'))
5707 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5708 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())
5709
5710 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')
5711 call assert_equal(1 , line('$'))
5712 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5713 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())
5714
5715 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')
5716 call assert_equal(1 , line('$'))
5717 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5718 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())
5719
5720 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')
5721 call assert_equal(1 , line('$'))
5722 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5723 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())
5724
5725 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')
5726 call assert_equal(1 , line('$'))
5727 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5728 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 +01005729 cclose
5730endfunc
5731
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005732" Test for very weird problem: autocommand causes a failure, resulting opening
5733" the quickfix window to fail. This still splits the window, but otherwise
5734" should not mess up buffers.
5735func Test_quickfix_window_fails_to_open()
5736 CheckScreendump
5737
5738 let lines =<< trim END
5739 anything
5740 try
5741 anything
5742 endtry
5743 END
5744 call writefile(lines, 'XquickfixFails')
5745
5746 let lines =<< trim END
5747 split XquickfixFails
5748 silent vimgrep anything %
5749 normal o
5750 au BufLeave * ++once source XquickfixFails
5751 " This will trigger the autocommand, which causes an error, what follows
5752 " is aborted but the window was already split.
5753 silent! cwindow
5754 END
5755 call writefile(lines, 'XtestWinFails')
5756 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5757 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5758
5759 " clean up
5760 call term_sendkeys(buf, ":bwipe!\<CR>")
5761 call term_wait(buf)
5762 call StopVimInTerminal(buf)
5763 call delete('XtestWinFails')
5764 call delete('XquickfixFails')
5765endfunc
5766
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005767" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005768" is changed.
5769func Xqfbuf_update(cchar)
5770 call s:setup_commands(a:cchar)
5771
5772 Xexpr "F1:1:line1"
5773 Xopen
5774 call assert_equal(['F1|1| line1'], getline(1, '$'))
5775 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5776
5777 " Test setqflist() using the 'lines' key in 'what'
5778 " add a new entry
5779 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5780 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5781 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5782 " replace all the entries with a single entry
5783 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5784 call assert_equal(['F3|3| line3'], getline(1, '$'))
5785 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5786 " remove all the entries
5787 call g:Xsetlist([], 'r', {'lines' : []})
5788 call assert_equal([''], getline(1, '$'))
5789 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5790 " add a new list
5791 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5792 call assert_equal(['F4|4| line4'], getline(1, '$'))
5793 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5794
5795 " Test setqflist() using the 'items' key in 'what'
5796 " add a new entry
5797 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5798 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5799 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5800 " replace all the entries with a single entry
5801 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5802 call assert_equal(['F6|6| line6'], getline(1, '$'))
5803 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5804 " remove all the entries
5805 call g:Xsetlist([], 'r', {'items' : []})
5806 call assert_equal([''], getline(1, '$'))
5807 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5808 " add a new list
5809 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5810 call assert_equal(['F7|7| line7'], getline(1, '$'))
5811 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5812
5813 call g:Xsetlist([], ' ', {})
5814 call assert_equal([''], getline(1, '$'))
5815 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5816
5817 Xclose
5818endfunc
5819
5820func Test_qfbuf_update()
5821 call Xqfbuf_update('c')
5822 call Xqfbuf_update('l')
5823endfunc
5824
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005825func Test_vimgrep_noswapfile()
5826 set noswapfile
5827 call writefile(['one', 'two', 'three'], 'Xgreppie')
5828 vimgrep two Xgreppie
5829 call assert_equal('two', getline('.'))
5830
5831 call delete('Xgreppie')
5832 set swapfile
5833endfunc
5834
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005835" Test for the :vimgrep 'f' flag (fuzzy match)
5836func Xvimgrep_fuzzy_match(cchar)
5837 call s:setup_commands(a:cchar)
5838
5839 Xvimgrep /three one/f Xfile*
5840 let l = g:Xgetlist()
5841 call assert_equal(2, len(l))
5842 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5843 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5844 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5845 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5846
5847 Xvimgrep /the/f Xfile*
5848 let l = g:Xgetlist()
5849 call assert_equal(3, len(l))
5850 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5851 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5852 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5853 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5854 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5855 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5856
5857 Xvimgrep /aaa/fg Xfile*
5858 let l = g:Xgetlist()
5859 call assert_equal(4, len(l))
5860 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5861 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5862 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5863 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5864 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5865 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5866 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5867 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5868
5869 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5870endfunc
5871
5872func Test_vimgrep_fuzzy_match()
5873 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5874 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5875 call Xvimgrep_fuzzy_match('c')
5876 call Xvimgrep_fuzzy_match('l')
5877 call delete('Xfile1')
5878 call delete('Xfile2')
5879endfunc
5880
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005881func Test_locationlist_open_in_newtab()
5882 call s:create_test_file('Xqftestfile1')
5883 call s:create_test_file('Xqftestfile2')
5884 call s:create_test_file('Xqftestfile3')
5885
5886 %bwipe!
5887
5888 lgetexpr ['Xqftestfile1:5:Line5',
5889 \ 'Xqftestfile2:10:Line10',
5890 \ 'Xqftestfile3:16:Line16']
5891
5892 silent! llast
5893 call assert_equal(1, tabpagenr('$'))
5894 call assert_equal('Xqftestfile3', bufname())
5895
5896 set switchbuf=newtab
5897
5898 silent! lfirst
5899 call assert_equal(2, tabpagenr('$'))
5900 call assert_equal('Xqftestfile1', bufname())
5901
5902 silent! lnext
5903 call assert_equal(3, tabpagenr('$'))
5904 call assert_equal('Xqftestfile2', bufname())
5905
5906 call delete('Xqftestfile1')
5907 call delete('Xqftestfile2')
5908 call delete('Xqftestfile3')
5909 set switchbuf&vim
5910
5911 %bwipe!
5912endfunc
5913
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005914" Test for win_gettype() in quickfix and location list windows
5915func Test_win_gettype()
5916 copen
5917 call assert_equal("quickfix", win_gettype())
5918 let wid = win_getid()
5919 wincmd p
5920 call assert_equal("quickfix", win_gettype(wid))
5921 cclose
5922 lexpr ''
5923 lopen
5924 call assert_equal("loclist", win_gettype())
5925 let wid = win_getid()
5926 wincmd p
5927 call assert_equal("loclist", win_gettype(wid))
5928 lclose
5929endfunc
5930
Christian Brabandt0b226f62021-12-01 10:54:24 +00005931fun Test_vimgrep_nomatch()
5932 call XexprTests('c')
5933 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5934 copen
5935 if has("win32")
5936 call assert_fails('vimgrep foo *.zzz', 'E479:')
5937 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'}]
5938 else
5939 call assert_fails('vimgrep foo *.zzz', 'E480:')
5940 let expected = []
5941 endif
5942 call assert_equal(expected, getqflist())
5943 cclose
5944endfunc
5945
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005946" Test for opening the quickfix window in two tab pages and then closing one
5947" of the quickfix windows. This should not make the quickfix buffer unlisted.
5948" (github issue #9300).
5949func Test_two_qf_windows()
5950 cexpr "F1:1:line1"
5951 copen
5952 tabnew
5953 copen
5954 call assert_true(&buflisted)
5955 cclose
5956 tabfirst
5957 call assert_true(&buflisted)
5958 let bnum = bufnr()
5959 cclose
5960 " if all the quickfix windows are closed, then buffer should be unlisted.
5961 call assert_false(buflisted(bnum))
5962 %bw!
5963
5964 " Repeat the test for a location list
5965 lexpr "F2:2:line2"
5966 lopen
5967 let bnum = bufnr()
5968 tabnew
5969 exe "buffer" bnum
5970 tabfirst
5971 lclose
5972 tablast
5973 call assert_true(buflisted(bnum))
5974 tabclose
5975 lopen
5976 call assert_true(buflisted(bnum))
5977 lclose
5978 call assert_false(buflisted(bnum))
5979 %bw!
5980endfunc
5981
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005982" Weird sequence of commands that caused entering a wiped-out buffer
5983func Test_lopen_bwipe()
5984 func R()
5985 silent! tab lopen
5986 e x
5987 silent! lfile
5988 endfunc
5989
5990 cal R()
5991 cal R()
5992 cal R()
5993 bw!
5994 delfunc R
5995endfunc
5996
Bram Moolenaare3537ae2022-02-08 15:05:20 +00005997" Another sequence of commands that caused all buffers to be wiped out
5998func Test_lopen_bwipe_all()
5999 let lines =<< trim END
6000 func R()
6001 silent! tab lopen
6002 e foo
6003 silent! lfile
6004 endfunc
6005 cal R()
6006 exe "norm \<C-W>\<C-V>0"
6007 cal R()
6008 bwipe
6009
6010 call writefile(['done'], 'Xresult')
6011 qall!
6012 END
6013 call writefile(lines, 'Xscript')
6014 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
6015 call assert_equal(['done'], readfile('Xresult'))
6016 endif
6017
6018 call delete('Xscript')
6019 call delete('Xresult')
6020endfunc
6021
Yegappan Lakshmanan9c9be052022-02-24 12:33:17 +00006022" Test for calling setqflist() function recursively
6023func Test_recursive_setqflist()
6024 augroup QF_Test
6025 au!
6026 autocmd BufWinEnter quickfix call setqflist([], 'r')
6027 augroup END
6028
6029 copen
6030 call assert_fails("call setqflist([], 'a')", 'E952:')
6031
6032 augroup QF_Test
6033 au!
6034 augroup END
6035 %bw!
6036endfunc
6037
6038" Test for failure to create a new window when selecting a file from the
6039" quickfix window
6040func Test_cwindow_newwin_fails()
6041 cgetexpr ["Xfile1:10:L10", "Xfile1:20:L20"]
6042 cwindow
6043 only
6044 let qf_wid = win_getid()
6045 " create the maximum number of scratch windows
6046 let hor_win_count = (&lines - 1)/2
6047 let hor_split_count = hor_win_count - 1
6048 for s in range(1, hor_split_count) | new | set buftype=nofile | endfor
6049 call win_gotoid(qf_wid)
6050 call assert_fails('exe "normal \<CR>"', 'E36:')
6051 %bw!
6052endfunc
6053
6054" Test for updating the location list when only the location list window is
6055" present and the corresponding file window is closed.
6056func Test_loclist_update_with_llwin_only()
6057 %bw!
6058 new
6059 wincmd w
6060 lexpr ["Xfile1:1:Line1"]
6061 lopen
6062 wincmd p
6063 close
6064 call setloclist(2, [], 'r', {'lines': ["Xtest2:2:Line2"]})
6065 call assert_equal(['Xtest2|2| Line2'], getbufline(winbufnr(2), 1, '$'))
6066 %bw!
6067endfunc
6068
6069" Test for getting the quickfix list after a buffer with an error is wiped out
6070func Test_getqflist_wiped_out_buffer()
6071 %bw!
6072 cexpr ["Xtest1:34:Wiped out"]
6073 let bnum = bufnr('Xtest1')
6074 call assert_equal(bnum, getqflist()[0].bufnr)
6075 bw Xtest1
6076 call assert_equal(0, getqflist()[0].bufnr)
6077 %bw!
6078endfunc
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00006079
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02006080" vim: shiftwidth=2 sts=2 expandtab