blob: 7d2373b828cf905688dc9dad3b7db17fb652909c [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00004import './vim9.vim' as v9
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020046 let g:Xgetlist = function('getqflist')
47 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020048 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020049 else
50 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
51 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020052 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020053 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020054 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010055 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020057 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xclose <mods>lclose <args>
59 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
60 command! -nargs=* Xgetfile <mods>lgetfile <args>
61 command! -nargs=* Xaddfile <mods>laddfile <args>
62 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
63 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
64 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
65 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020066 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
67 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020068 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
69 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020070 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020071 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020072 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020073 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010074 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020075 command! -nargs=* Xgrep <mods> lgrep <args>
76 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
77 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010078 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020079 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
80 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020081 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
82 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020083 let g:Xgetlist = function('getloclist', [0])
84 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020085 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020086 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010087endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088
Bram Moolenaara5d78d12021-12-15 12:28:22 +000089" This must be run before any error lists are created.
90func Test_AA_cc_no_errors()
91 call assert_fails('cc', 'E42:')
92 call assert_fails('ll', 'E42:')
93endfunc
94
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010096func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020097 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020099 if a:cchar == 'l'
100 call assert_fails('llist', 'E776:')
101 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200103 Xgetexpr []
104 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100105 call assert_true(v:errmsg ==# 'E42: No Errors')
106
107 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200108 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100109 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100110 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100111
112 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100113 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100114 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
115 \ ' 4 Xtestfile2:2 col 2: Line2',
116 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
117
118 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100119 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100120 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
121 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100122 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123
124 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
127 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
128
Bram Moolenaaree85df32017-03-19 14:19:50 +0100129 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100130 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
131
Bram Moolenaaree85df32017-03-19 14:19:50 +0100132 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100133 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
134
Bram Moolenaaree85df32017-03-19 14:19:50 +0100135 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100136 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
137 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100138
139 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100140 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100141 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
142 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100143
thinca6864efa2021-06-19 20:45:20 +0200144 " Ranged entries
145 call g:Xsetlist([{'lnum':10,'text':'Line1'},
146 \ {'lnum':20,'col':10,'text':'Line2'},
147 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
148 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
149 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
150 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
151 let l = split(execute('Xlist', ""), "\n")
152 call assert_equal([' 1:10: Line1',
153 \ ' 2:20 col 10: Line2',
154 \ ' 3:30 col 15-20: Line3',
155 \ ' 4:40-45: Line4',
156 \ ' 5:50-55 col 15: Line5',
157 \ ' 6:60-65 col 25-35: Line6'], l)
158
Bram Moolenaaree85df32017-03-19 14:19:50 +0100159 " Different types of errors
160 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
161 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
162 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
163 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
164 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
165 let l = split(execute('Xlist', ""), "\n")
166 call assert_equal([' 1:10 col 5 warning 11: Warning',
167 \ ' 2:20 col 10 error 22: Error',
168 \ ' 3:30 col 15 info 33: Info',
169 \ ' 4:40 col 20 x 44: Other',
170 \ ' 5:50 col 25 55: one'], l)
171
Bram Moolenaard76ce852018-05-01 15:02:04 +0200172 " Test for module names, one needs to explicitly set `'valid':v:true` so
173 call g:Xsetlist([
174 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
175 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
176 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
177 let l = split(execute('Xlist', ""), "\n")
178 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
179 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
180 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
181
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100182 " For help entries in the quickfix list, only the filename without directory
183 " should be displayed
184 Xhelpgrep setqflist()
185 let l = split(execute('Xlist 1', ''), "\n")
186 call assert_match('^ 1 [^\\/]\{-}:', l[0])
187
Bram Moolenaaree85df32017-03-19 14:19:50 +0100188 " Error cases
189 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100190endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100191
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100192func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100193 call XlistTests('c')
194 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100195endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100196
197" Tests for the :colder, :cnewer, :lolder and :lnewer commands
198" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100199" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100200func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200201 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100202
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200203 if a:cchar == 'l'
204 " No location list for the current window
205 call assert_fails('lolder', 'E776:')
206 call assert_fails('lnewer', 'E776:')
207 endif
208
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200209 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200210 call g:Xsetlist(list)
211
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100212 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100214 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
215
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200216 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100217 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
218
219 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200220 Xgetexpr ['Xtestfile1:1:3:Line1']
221 Xgetexpr ['Xtestfile2:2:2:Line2']
222 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223
224 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200225 Xolder
226 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100227 call assert_equal('Line2', l[0].text)
228
229 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 Xnewer
231 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100232 call assert_equal('Line3', l[0].text)
233
234 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200235 Xolder 2
236 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 call assert_equal('Line1', l[0].text)
238
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200239 Xnewer 2
240 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100241 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100242endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100243
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100244func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100245 call XageTests('c')
246 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100247endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100248
249" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
250" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100251func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200252 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200254 " Opening the location list window without any errors should fail
255 if a:cchar == 'l'
256 call assert_fails('lopen', 'E776:')
257 endif
258
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100259 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200260 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100261
262 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200263 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100264 call assert_true(winnr('$') == 1)
265
266 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200267 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
268 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
270 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200271 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100272 call assert_true(winnr('$') == 2 && winnr() == 2 &&
273 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200274 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100275
276 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200277 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100278 call assert_true(winnr('$') == 1)
279
280 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200281 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100282
283 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200284 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100285 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200286 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100287
288 " Opening the window again, should move the cursor to that window
289 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200290 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100291 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200292 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100293 \ getline('.') ==# '|| non-error 1')
294
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100295 " :cnext in quickfix window should move to the next entry
296 Xnext
297 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100298
299 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200300 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100301 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200302
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100303 " Specifying the width should adjust the width for a vertically split
304 " quickfix window.
305 vert Xopen
306 call assert_equal(10, winwidth(0))
307 vert Xopen 12
308 call assert_equal(12, winwidth(0))
309 Xclose
310
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200311 " Horizontally or vertically splitting the quickfix window should create a
312 " normal window/buffer
313 Xopen
314 wincmd s
315 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
316 call assert_equal(0, getwininfo(win_getid())[0].loclist)
317 call assert_notequal('quickfix', &buftype)
318 close
319 Xopen
320 wincmd v
321 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
322 call assert_equal(0, getwininfo(win_getid())[0].loclist)
323 call assert_notequal('quickfix', &buftype)
324 close
325 Xopen
326 Xclose
327
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200328 if a:cchar == 'c'
329 " Opening the quickfix window in multiple tab pages should reuse the
330 " quickfix buffer
331 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
332 \ 'Xtestfile3:3:1:Line3']
333 Xopen
334 let qfbufnum = bufnr('%')
335 tabnew
336 Xopen
337 call assert_equal(qfbufnum, bufnr('%'))
338 new | only | tabonly
339 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100340endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100341
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100342func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100343 call XwindowTests('c')
344 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100345endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346
Bram Moolenaar36d50222019-05-02 20:17:40 +0200347func Test_copenHeight()
348 copen
349 wincmd H
350 let height = winheight(0)
351 copen 10
352 call assert_equal(height, winheight(0))
353 quit
354endfunc
355
Bram Moolenaar1142a312019-10-16 14:51:39 +0200356func Test_copenHeight_tabline()
357 set tabline=foo showtabline=2
358 copen
359 wincmd H
360 let height = winheight(0)
361 copen 10
362 call assert_equal(height, winheight(0))
363 quit
364 set tabline& showtabline&
365endfunc
366
367
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
369" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100370func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100372
373 call writefile(['Xtestfile1:700:10:Line 700',
374 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
375
376 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200377 Xfile Xqftestfile1
378 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100379 call assert_true(len(l) == 2 &&
380 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
381 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
382
Bram Moolenaar049cba92016-06-26 14:38:04 +0200383 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200384 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200385
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100386 " Run cfile/lfile from a modified buffer
387 enew!
388 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200389 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100390 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
391
392 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200393 Xaddfile Xqftestfile1
394 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395 call assert_true(len(l) == 3 &&
396 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
397
398 call writefile(['Xtestfile1:222:77:Line 222',
399 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
400
401 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200402 Xgetfile Xqftestfile1
403 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100404 call assert_true(len(l) == 2 &&
405 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
406 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
407
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100408 " Test for a file with a long line and without a newline at the end
409 let text = repeat('x', 1024)
410 let t = 'a.txt:18:' . text
411 call writefile([t], 'Xqftestfile1', 'b')
412 silent! Xfile Xqftestfile1
413 call assert_equal(text, g:Xgetlist()[0].text)
414
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100415 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100416endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100417
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100418func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100419 call XfileTests('c')
420 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100421endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100422
423" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
424" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100425func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200426 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100427
428 enew!
429 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
430 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200431 Xbuffer!
432 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100433 call assert_true(len(l) == 2 &&
434 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
435 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
436
437 enew!
438 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
439 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200440 Xgetbuffer
441 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100442 call assert_true(len(l) == 2 &&
443 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
444 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
445
446 enew!
447 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
448 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200449 Xaddbuffer
450 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100451 call assert_true(len(l) == 4 &&
452 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
453 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
454 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200455 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100456
Bram Moolenaaree85df32017-03-19 14:19:50 +0100457 " Check for invalid buffer
458 call assert_fails('Xbuffer 199', 'E474:')
459
460 " Check for unloaded buffer
461 edit Xtestfile1
462 let bnr = bufnr('%')
463 enew!
464 call assert_fails('Xbuffer ' . bnr, 'E681:')
465
466 " Check for invalid range
467 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
468 " commands. So directly call the commands.
469 if (a:cchar == 'c')
470 call assert_fails('900,999cbuffer', 'E16:')
471 else
472 call assert_fails('900,999lbuffer', 'E16:')
473 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100474endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100475
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100476func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100477 call XbufferTests('c')
478 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100479endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100480
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100481func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200482 call s:setup_commands(a:cchar)
483
484 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100485endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200486
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100487func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200488 call XexprTests('c')
489 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100490endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200491
492" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100493func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200494 call s:setup_commands(a:cchar)
495
Bram Moolenaar74240d32017-12-10 15:26:15 +0100496 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200497 " Jumping to first or next location list entry without any error should
498 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100499 if a:cchar == 'c'
500 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100501 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100502 else
503 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100504 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200505 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100506 call assert_fails('Xnext', err)
507 call assert_fails('Xprev', err)
508 call assert_fails('Xnfile', err)
509 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100510 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200511
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100512 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100513 call assert_fails(cmd, 'E42:')
514
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200515 call s:create_test_file('Xqftestfile1')
516 call s:create_test_file('Xqftestfile2')
517
518 Xgetexpr ['Xqftestfile1:5:Line5',
519 \ 'Xqftestfile1:6:Line6',
520 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200521 \ 'Xqftestfile2:11:Line11',
522 \ 'RegularLine1',
523 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200524
525 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100526 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200527 call assert_fails('Xprev', 'E553:')
528 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200529 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200530 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200531 call assert_equal(10, line('.'))
532 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200533 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200534 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100535 5Xcc
536 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
537 2Xcc
538 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100539 if a:cchar == 'c'
540 cc
541 else
542 ll
543 endif
544 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100545 10Xcc
546 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200547 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200549 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200550 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200551 call assert_fails('Xnext', 'E553:')
552 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100553 " To process the range using quickfix list entries, directly use the
554 " quickfix commands (don't use the user defined commands)
555 if a:cchar == 'c'
556 $cc
557 else
558 $ll
559 endif
560 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200561 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200562 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200563 call assert_equal(5, line('.'))
564
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200565 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200566 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200567 call assert_equal(11, line('.'))
568 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200569 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200570 call assert_equal(5, line('.'))
571
Bram Moolenaar74240d32017-12-10 15:26:15 +0100572 " Jumping to an error from the error window using cc command
573 Xgetexpr ['Xqftestfile1:5:Line5',
574 \ 'Xqftestfile1:6:Line6',
575 \ 'Xqftestfile2:10:Line10',
576 \ 'Xqftestfile2:11:Line11']
577 Xopen
578 10Xcc
579 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200580 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100581 Xopen
582 call cursor(2, 1)
583 if a:cchar == 'c'
584 .cc
585 else
586 .ll
587 endif
588 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200589 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100590
591 " Jumping to an error from the error window (when only the error window is
592 " present)
593 Xopen | only
594 Xlast 1
595 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200596 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100597
Bram Moolenaaree85df32017-03-19 14:19:50 +0100598 Xexpr ""
599 call assert_fails('Xnext', 'E42:')
600
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200601 call delete('Xqftestfile1')
602 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200603
604 " Should be able to use next/prev with invalid entries
605 Xexpr ""
606 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
607 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100608 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200609 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
610 Xlast
611 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
612 Xfirst
613 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
614 2Xnext
615 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100616endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200617
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100618func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200619 call Xtest_browse('c')
620 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100621endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200622
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100623func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200624 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100625 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100626
Bram Moolenaarce90e362019-09-08 18:58:44 +0200627 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100628 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100629
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200630 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100631 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100632
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200633 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100634 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100635
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200636 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100637 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100638
639endfunc
640
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100641func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200642 call s:setup_commands(a:cchar)
643 Xhelpgrep quickfix
644 Xopen
645 if a:cchar == 'c'
646 let title_text = ':helpgrep quickfix'
647 else
648 let title_text = ':lhelpgrep quickfix'
649 endif
650 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200651
652 " Jumping to a help topic should open the help window
653 only
654 Xnext
655 call assert_true(&buftype == 'help')
656 call assert_true(winnr('$') == 2)
657 " Jumping to the next match should reuse the help window
658 Xnext
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
661 call assert_true(winnr('$') == 2)
662 " Jumping to the next match from the quickfix window should reuse the help
663 " window
664 Xopen
665 Xnext
666 call assert_true(&buftype == 'help')
667 call assert_true(winnr() == 1)
668 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200669 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200670
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100671 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200672 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100673
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100674 " When the current window is vertically split, jumping to a help match
675 " should open the help window at the top.
676 only | enew
677 let w1 = win_getid()
678 vert new
679 let w2 = win_getid()
680 Xnext
681 let w3 = win_getid()
682 call assert_true(&buftype == 'help')
683 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100684 " See jump_to_help_window() for details
685 let w2_width = winwidth(w2)
686 if w2_width != &columns && w2_width < 80
687 call assert_equal(['col', [['leaf', w3],
688 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
689 else
690 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
691 \ ['leaf', w1]]] , winlayout())
692 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100693
694 new | only
695 set buftype=help
696 set modified
697 call assert_fails('Xnext', 'E37:')
698 set nomodified
699 new | only
700
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200701 if a:cchar == 'l'
702 " When a help window is present, running :lhelpgrep should reuse the
703 " help window and not the current window
704 new | only
705 call g:Xsetlist([], 'f')
706 help index.txt
707 wincmd w
708 lhelpgrep quickfix
709 call assert_equal(1, winnr())
710 call assert_notequal([], getloclist(1))
711 call assert_equal([], getloclist(2))
712 endif
713
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200714 new | only
715
Bram Moolenaaree85df32017-03-19 14:19:50 +0100716 " Search for non existing help string
717 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200718 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200719 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100720endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200721
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100722func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200723 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200724 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200725 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100726endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100727
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100728def Test_helpgrep_vim9_restore_cpo()
729 assert_equal('aABceFs', &cpo)
730
731 var rtp_save = &rtp
732 var dir = 'Xruntime/after'
733 &rtp ..= ',' .. dir
734 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100735 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100736 filetype plugin on
737 silent helpgrep grail
738 cwindow
739 silent helpgrep grail
740
741 assert_equal('aABceFs', &cpo)
742 delete(dir, 'rf')
743 &rtp = rtp_save
744 cclose
745 helpclose
746enddef
747
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200748def Test_vim9_cexpr()
749 var text = 'somefile:95:error'
750 cexpr text
751 var l = getqflist()
752 assert_equal(1, l->len())
753 assert_equal(95, l[0].lnum)
754 assert_equal('error', l[0].text)
755
756 text = 'somefile:77:warning'
757 caddexpr text
758 l = getqflist()
759 assert_equal(2, l->len())
760 assert_equal(77, l[1].lnum)
761 assert_equal('warning', l[1].text)
762enddef
763
Bram Moolenaar6920c722016-01-22 22:44:10 +0100764func Test_errortitle()
765 augroup QfBufWinEnter
766 au!
767 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
768 augroup END
769 copen
770 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
771 call setqflist(a)
772 call assert_equal(':setqflist()', g:a)
773 augroup QfBufWinEnter
774 au!
775 augroup END
776 augroup! QfBufWinEnter
777endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100778
Bram Moolenaar5584df62016-03-18 21:00:51 +0100779func Test_vimgreptitle()
780 augroup QfBufWinEnter
781 au!
782 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
783 augroup END
784 try
785 vimgrep /pattern/j file
786 catch /E480/
787 endtry
788 copen
789 call assert_equal(': vimgrep /pattern/j file', g:a)
790 augroup QfBufWinEnter
791 au!
792 augroup END
793 augroup! QfBufWinEnter
794endfunc
795
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100796func Test_bufwinenter_once()
797 augroup QfBufWinEnter
798 au!
799 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
800 augroup END
801 let g:got_afile = ''
802 copen
803 call assert_equal('got quickfix', g:got_afile)
804
805 cclose
806 unlet g:got_afile
807 augroup QfBufWinEnter
808 au!
809 augroup END
810 augroup! QfBufWinEnter
811endfunc
812
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100813func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200814 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100815
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200816 Xgetexpr ['file:1:1:message']
817 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100818 if a:cchar == 'c'
819 call setqflist(l, 'r')
820 else
821 call setloclist(0, l, 'r')
822 endif
823
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200824 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100825 if a:cchar == 'c'
826 let title = ':setqflist()'
827 else
828 let title = ':setloclist()'
829 endif
830 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200831 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100832endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100833
834" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100835func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200836 call XqfTitleTests('c')
837 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100838endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100839
840" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100841func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100842 let save_efm = &efm
843 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
844 cgetexpr ['WWWW', 'EEEE', 'CCCC']
845 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
846 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
847 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
848 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
849 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
850 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
851 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
852 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
853 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100854endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100855
856" This will test for problems in quickfix:
857" A. incorrectly copying location lists which caused the location list to show
858" a different name than the file that was actually being displayed.
859" B. not reusing the window for which the location list window is opened but
860" instead creating new windows.
861" C. make sure that the location list window is not reused instead of the
862" window it belongs to.
863"
864" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100865func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100866 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
867 let word = substitute(base, '\v(.*)\..*', '\1', '')
868
869 setl modifiable
870 setl noreadonly
871 setl noswapfile
872 setl bufhidden=delete
873 %del _
874 " For problem 2:
875 " 'buftype' has to be set to reproduce the constant opening of new windows
876 setl buftype=nofile
877
878 call setline(1, word)
879
880 setl nomodified
881 setl nomodifiable
882 setl readonly
883 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100884endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100885
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100886func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200887 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100888
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200889 augroup testgroup
890 au!
891 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
892 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100893
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200894 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100895
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200896 let qflist = []
897 for word in words
898 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
899 " NOTE: problem 1:
900 " intentionally not setting 'lnum' so that the quickfix entries are not
901 " valid
902 eval qflist->setloclist(0, ' ')
903 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100904
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200905 " Test A
906 lrewind
907 enew
908 lopen
909 4lnext
910 vert split
911 wincmd L
912 lopen
913 wincmd p
914 lnext
915 let fileName = expand("%")
916 wincmd p
917 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
918 let fileName = substitute(fileName, '\\', '/', 'g')
919 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
920 call assert_equal("test://bar.txt", fileName)
921 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100922
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200923 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100924
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200925 " Test B:
926 lrewind
927 lopen
928 2
929 exe "normal \<CR>"
930 wincmd p
931 3
932 exe "normal \<CR>"
933 wincmd p
934 4
935 exe "normal \<CR>"
936 call assert_equal(2, winnr('$'))
937 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100938
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200939 " Test C:
940 lrewind
941 lopen
942 " Let's move the location list window to the top to check whether it (the
943 " first window found) will be reused when we try to open new windows:
944 wincmd K
945 2
946 exe "normal \<CR>"
947 wincmd p
948 3
949 exe "normal \<CR>"
950 wincmd p
951 4
952 exe "normal \<CR>"
953 1wincmd w
954 call assert_equal('quickfix', &buftype)
955 2wincmd w
956 let bufferName = expand("%")
957 let bufferName = substitute(bufferName, '\\', '/', 'g')
958 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100959
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200960 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100961
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200962 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100963endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100964
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100965func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200966 augroup testgroup
967 au!
968 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
969 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100970
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200971 func! R(n)
972 quit
973 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100974
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200975 new
976 let q = []
977 call add(q, {'filename': 'test_curwin.txt' })
978 call setloclist(0, q)
979 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100980
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200981 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +0000982 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +0100983endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100984
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100985func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200986 call writefile(['loclistfoo'], 'loclistfoo')
987 call writefile(['loclistbar'], 'loclistbar')
988 set switchbuf=usetab
989
990 edit loclistfoo
991 tabedit loclistbar
992 silent lgrep loclistfoo loclist*
993 call assert_equal(1, tabpagenr())
994
995 enew | only | tabonly
996 set switchbuf&vim
997 call delete('loclistfoo')
998 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100999endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001000
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001001" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001002func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001003 " The 'errorformat' setting is different on non-Unix systems.
1004 " This test works only on Unix-like systems.
1005 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001006
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001007 let l =<< trim [DATA]
1008 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1009 "Xtestfile", line 6 col 19; this is an error
1010 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1011 Xtestfile:9: parse error before `asd'
1012 make: *** [vim] Error 1
1013 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001014
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001015 2 returned
1016 "Xtestfile", line 11 col 1; this is an error
1017 "Xtestfile", line 12 col 2; this is another error
1018 "Xtestfile", line 14:10; this is an error in column 10
1019 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1020 "Xtestfile", linenr 16: yet another problem
1021 Error in "Xtestfile" at line 17:
1022 x should be a dot
1023 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1024 ^
1025 Error in "Xtestfile" at line 18:
1026 x should be a dot
1027 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1028 .............^
1029 Error in "Xtestfile" at line 19:
1030 x should be a dot
1031 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1032 --------------^
1033 Error in "Xtestfile" at line 20:
1034 x should be a dot
1035 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1036 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001037
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001038 Does anyone know what is the problem and how to correction it?
1039 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1040 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1041 [DATA]
1042
1043 call writefile(l, 'Xerrorfile1')
1044 call writefile(l[:-2], 'Xerrorfile2')
1045
1046 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001047 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1048 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1049 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1051 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1052 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1055 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1056 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1060 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1061 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1062 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1063 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1064 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1065 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1066 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1067 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1068[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001069 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001070
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001071 let save_efm = &efm
1072 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1073 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001074
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001075 exe 'cf Xerrorfile2'
1076 clast
1077 copen
1078 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1079 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001080
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001081 exe 'cf Xerrorfile1'
1082 call assert_equal([4, 12], [line('.'), col('.')])
1083 cn
1084 call assert_equal([6, 19], [line('.'), col('.')])
1085 cn
1086 call assert_equal([9, 2], [line('.'), col('.')])
1087 cn
1088 call assert_equal([10, 2], [line('.'), col('.')])
1089 cn
1090 call assert_equal([11, 1], [line('.'), col('.')])
1091 cn
1092 call assert_equal([12, 2], [line('.'), col('.')])
1093 cn
1094 call assert_equal([14, 10], [line('.'), col('.')])
1095 cn
1096 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1097 cn
1098 call assert_equal([16, 2], [line('.'), col('.')])
1099 cn
1100 call assert_equal([17, 6], [line('.'), col('.')])
1101 cn
1102 call assert_equal([18, 7], [line('.'), col('.')])
1103 cn
1104 call assert_equal([19, 8], [line('.'), col('.')])
1105 cn
1106 call assert_equal([20, 9], [line('.'), col('.')])
1107 clast
1108 cprev
1109 cprev
1110 wincmd w
1111 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1112 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001113
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001114 let &efm = save_efm
1115 call delete('Xerrorfile1')
1116 call delete('Xerrorfile2')
1117 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001118endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001119
Bram Moolenaarab47c612016-06-14 22:02:26 +02001120" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001121func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001122 call s:setup_commands(a:cchar)
1123
Bram Moolenaarab47c612016-06-14 22:02:26 +02001124 let save_efm=&efm
1125 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1126
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001127 let lines = ["Entering dir 'dir1/a'",
1128 \ 'habits2.txt:1:Nine Healthy Habits',
1129 \ "Entering dir 'b'",
1130 \ 'habits3.txt:2:0 Hours of television',
1131 \ 'habits2.txt:7:5 Small meals',
1132 \ "Entering dir 'dir1/c'",
1133 \ 'habits4.txt:3:1 Hour of exercise',
1134 \ "Leaving dir 'dir1/c'",
1135 \ "Leaving dir 'dir1/a'",
1136 \ 'habits1.txt:4:2 Liters of water',
1137 \ "Entering dir 'dir2'",
1138 \ 'habits5.txt:5:3 Cups of hot green tea',
1139 \ "Leaving dir 'dir2'"
1140 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001141
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001142 Xexpr ""
1143 for l in lines
1144 Xaddexpr l
1145 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001146
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001147 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001148
1149 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1150 call assert_equal(1, qf[1].lnum)
1151 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1152 call assert_equal(2, qf[3].lnum)
1153 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1154 call assert_equal(7, qf[4].lnum)
1155 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1156 call assert_equal(3, qf[6].lnum)
1157 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1158 call assert_equal(4, qf[9].lnum)
1159 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1160 call assert_equal(5, qf[11].lnum)
1161
1162 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001163endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001164
1165" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001166func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001167 " Create the directory stack and files
1168 call mkdir('dir1')
1169 call mkdir('dir1/a')
1170 call mkdir('dir1/a/b')
1171 call mkdir('dir1/c')
1172 call mkdir('dir2')
1173
1174 let lines = ["Nine Healthy Habits",
1175 \ "0 Hours of television",
1176 \ "1 Hour of exercise",
1177 \ "2 Liters of water",
1178 \ "3 Cups of hot green tea",
1179 \ "4 Short mental breaks",
1180 \ "5 Small meals",
1181 \ "6 AM wake up time",
1182 \ "7 Minutes of laughter",
1183 \ "8 Hours of sleep (at least)",
1184 \ "9 PM end of the day and off to bed"
1185 \ ]
1186 call writefile(lines, 'habits1.txt')
1187 call writefile(lines, 'dir1/a/habits2.txt')
1188 call writefile(lines, 'dir1/a/b/habits3.txt')
1189 call writefile(lines, 'dir1/c/habits4.txt')
1190 call writefile(lines, 'dir2/habits5.txt')
1191
1192 call s:dir_stack_tests('c')
1193 call s:dir_stack_tests('l')
1194
1195 call delete('dir1', 'rf')
1196 call delete('dir2', 'rf')
1197 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001198endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001199
Bram Moolenaar9b457942016-10-09 16:10:05 +02001200" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001201func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001202 call s:setup_commands(a:cchar)
1203
1204 let save_efm = &efm
1205
1206 let &efm =
1207 \ '%Eerror %m %l,' .
1208 \ '%-Wignored %m %l,' .
1209 \ '%+Cmore ignored %m %l,' .
1210 \ '%Zignored end'
1211 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1212 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1213 call assert_equal([['resync', 1, 4, 'E']], l)
1214
1215 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001216endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001217
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001218func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001219 call Xefm_ignore_continuations('c')
1220 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001221endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001222
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001223" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001224func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001225 call s:setup_commands(a:cchar)
1226
Bram Moolenaar049cba92016-06-26 14:38:04 +02001227 let save_efm = &efm
1228
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001229 set efm=%f:%l:%m,%f:%f:%l:%m
1230 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1231
1232 set efm=%f:%l:%m,%f:%l:%r:%m
1233 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1234
1235 set efm=%f:%l:%m,%O:%f:%l:%m
1236 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1237
1238 set efm=%f:%l:%m,%f:%l:%*[^a-z
1239 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1240
1241 set efm=%f:%l:%m,%f:%l:%*c
1242 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1243
1244 set efm=%f:%l:%m,%L%M%N
1245 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1246
1247 set efm=%f:%l:%m,%f:%l:%m:%R
1248 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1249
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001250 " Invalid regular expression
1251 set efm=%\\%%k
1252 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1253
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001254 set efm=
1255 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1256
1257 set efm=%DEntering\ dir\ abc,%f:%l:%m
1258 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1259
1260 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001261endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001262
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001263func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001264 call Xinvalid_efm_Tests('c')
1265 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001266endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001267
1268" TODO:
1269" Add tests for the following formats in 'errorformat'
1270" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001271func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001272 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001273
1274 " Test for %s format in efm
1275 set efm=%f:%s
1276 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001277 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001278 call assert_equal('^\VLine search text\$', l[0].pattern)
1279 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001280
Bram Moolenaaree85df32017-03-19 14:19:50 +01001281 let l = split(execute('clist', ''), "\n")
1282 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1283
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001284 " Test for a long line
1285 cexpr 'Xtestfile:' . repeat('a', 1026)
1286 let l = getqflist()
1287 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1288
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001289 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001290 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001291 [Xtestfile1]
1292 (1,17) error: ';' missing
1293 (21,2) warning: variable 'z' not defined
1294 (67,3) error: end of file found before string ended
1295 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001296
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001297 [Xtestfile2]
1298 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001299
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001300 [Xtestfile3]
1301 NEW compiler v1.1
1302 (2,2) warning: variable 'x' not defined
1303 (67,3) warning: 's' already defined
1304 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001305 [DATA]
1306
Bram Moolenaaree85df32017-03-19 14:19:50 +01001307 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001308 " To exercise the push/pop file functionality in quickfix, the test files
1309 " need to be created.
1310 call writefile(['Line1'], 'Xtestfile1')
1311 call writefile(['Line2'], 'Xtestfile2')
1312 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001313 cexpr ""
1314 for l in lines
1315 caddexpr l
1316 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001317 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001318 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001319 call assert_equal(21, l[2].lnum)
1320 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001321 call assert_equal('w', l[2].type)
1322 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001323 call delete('Xtestfile1')
1324 call delete('Xtestfile2')
1325 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001326
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001327 " Test for %P, %Q with non-existing files
1328 cexpr lines
1329 let l = getqflist()
1330 call assert_equal(14, len(l))
1331 call assert_equal('[Xtestfile1]', l[0].text)
1332 call assert_equal('[Xtestfile2]', l[6].text)
1333 call assert_equal('[Xtestfile3]', l[9].text)
1334
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001335 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001336 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001337 Error 275
1338 line 42
1339 column 3
1340 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001341 [DATA]
1342
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001343 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1344 cgetexpr lines
1345 let l = getqflist()
1346 call assert_equal(275, l[0].nr)
1347 call assert_equal(42, l[0].lnum)
1348 call assert_equal(3, l[0].col)
1349 call assert_equal('E', l[0].type)
1350 call assert_equal("\n' ' expected after '--'", l[0].text)
1351
1352 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001353 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001354 Error in line 147 of foo.c:
1355 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001356 [DATA]
1357
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001358 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1359 cgetexpr lines
1360 let l = getqflist()
1361 call assert_equal(147, l[0].lnum)
1362 call assert_equal('E', l[0].type)
1363 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001364
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001365 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001366 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001367 ==============================================================
1368 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1369 --------------------------------------------------------------
1370 Traceback (most recent call last):
1371 File "unittests/dbfacadeTest.py", line 89, in testFoo
1372 self.assertEquals(34, dtid)
1373 File "/usr/lib/python2.2/unittest.py", line 286, in
1374 failUnlessEqual
1375 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001376 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001377
1378 --------------------------------------------------------------
1379 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001380 [DATA]
1381
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001382 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001383 cgetexpr lines
1384 let l = getqflist()
1385 call assert_equal(8, len(l))
1386 call assert_equal(89, l[4].lnum)
1387 call assert_equal(1, l[4].valid)
1388 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001389 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001390
Bram Moolenaard76ce852018-05-01 15:02:04 +02001391 " Test for %o
1392 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001393 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1394 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001395 let l = getqflist()
1396 call assert_equal(1, len(l), string(l))
1397 call assert_equal('Language.PureScript.Types', l[0].module)
1398 copen
1399 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1400 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001401 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001402 cclose
1403 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001404 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001405
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001406 " Test for a long module name
1407 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1408 let l = getqflist()
1409 call assert_equal(repeat('m', 1024), l[0].module)
1410 call assert_equal(15, l[0].lnum)
1411 call assert_equal('message', l[0].text)
1412
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001413 " The following sequence of commands used to crash Vim
1414 set efm=%W%m
1415 cgetexpr ['msg1']
1416 let l = getqflist()
1417 call assert_equal(1, len(l), string(l))
1418 call assert_equal('msg1', l[0].text)
1419 set efm=%C%m
1420 lexpr 'msg2'
1421 let l = getloclist(0)
1422 call assert_equal(1, len(l), string(l))
1423 call assert_equal('msg2', l[0].text)
1424 lopen
1425 call setqflist([], 'r')
1426 caddbuf
1427 let l = getqflist()
1428 call assert_equal(1, len(l), string(l))
1429 call assert_equal('|| msg2', l[0].text)
1430
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001431 " When matching error lines, case should be ignored. Test for this.
1432 set noignorecase
1433 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1434 call assert_equal(10, l.items[0].lnum)
1435 call assert_equal('Line 20', l.items[0].text)
1436 set ignorecase&
1437
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001438 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001439 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001440endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001441
Bram Moolenaare9283662020-06-07 14:10:47 +02001442" Test for '%t' (error type) field in 'efm'
1443func Test_efm_error_type()
1444 let save_efm = &efm
1445
1446 " error type
1447 set efm=%f:%l:%t:%m
1448 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1449 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1450 let output = split(execute('clist'), "\n")
1451 call assert_equal([
1452 \ ' 1 Xfile1:10 error: msg1',
1453 \ ' 2 Xfile1:20 warning: msg2',
1454 \ ' 3 Xfile1:30 info: msg3',
1455 \ ' 4 Xfile1:40 note: msg4',
1456 \ ' 5 Xfile1:50 R: msg5'], output)
1457
1458 " error type and a error number
1459 set efm=%f:%l:%t:%n:%m
1460 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1461 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1462 let output = split(execute('clist'), "\n")
1463 call assert_equal([
1464 \ ' 1 Xfile1:10 error 2: msg1',
1465 \ ' 2 Xfile1:20 warning 4: msg2',
1466 \ ' 3 Xfile1:30 info 6: msg3',
1467 \ ' 4 Xfile1:40 note 8: msg4',
1468 \ ' 5 Xfile1:50 R 3: msg5'], output)
1469 let &efm = save_efm
1470endfunc
1471
haya14busae023d492022-02-08 18:09:29 +00001472" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1473func Test_efm_end_lnum_col()
1474 let save_efm = &efm
1475
1476 " single line
1477 set efm=%f:%l-%e:%c-%k:%t:%m
1478 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1479 let output = split(execute('clist'), "\n")
1480 call assert_equal([
1481 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1482 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1483
1484 " multiple lines
1485 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
1486 cexpr ["1)msg1", "Xfile1:14-24:1-2",
1487 \ "2)msg2", "Xfile1:24-34:3-4"]
1488 let output = split(execute('clist'), "\n")
1489 call assert_equal([
1490 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1491 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1492 let &efm = save_efm
1493endfunc
1494
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001495func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001496 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001497 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001498 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001499 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001500 colder
1501 cgetexpr []
1502 endfunc
1503 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001504 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001505 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001506 lolder
1507 lgetexpr []
1508 endfunc
1509 endif
1510
1511 augroup testgroup
1512 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001513 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001514 augroup END
1515
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001516 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001517 let words = [ "a", "b" ]
1518 let qflist = []
1519 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001520 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001521 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001522 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001523 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001524
1525 augroup! testgroup
1526endfunc
1527
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001528func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001529 call XquickfixChangedByAutocmd('c')
1530 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001531endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001532
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001533func Test_setloclist_in_autocommand()
1534 call writefile(['test1', 'test2'], 'Xfile')
1535 edit Xfile
1536 let s:bufnr = bufnr()
1537 call setloclist(1,
1538 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1539 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1540
1541 augroup Test_LocList
1542 au!
1543 autocmd BufEnter * call setloclist(1,
1544 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1545 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1546 augroup END
1547
1548 lopen
1549 call assert_fails('exe "normal j\<CR>"', 'E926:')
1550
1551 augroup Test_LocList
1552 au!
1553 augroup END
1554 call delete('Xfile')
1555endfunc
1556
Bram Moolenaar8b201792016-03-25 15:01:10 +01001557func Test_caddbuffer_to_empty()
1558 helpgr quickfix
1559 call setqflist([], 'r')
1560 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001561 try
1562 cn
1563 catch
1564 " number of matches is unknown
1565 call assert_true(v:exception =~ 'E553:')
1566 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001567 quit!
1568endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001569
1570func Test_cgetexpr_works()
1571 " this must not crash Vim
1572 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001573 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001574endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001575
1576" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001577func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001578 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001579
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001580 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001581 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001582 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001583 call assert_equal(2, len(l))
1584 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001585 call assert_equal(3, l[1].end_lnum)
1586 call assert_equal(4, l[1].col)
1587 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001588
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001589 Xnext
1590 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1591 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001592 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001593 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001594 call assert_equal(3, line('.'))
1595
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001596 " Appending entries to the list should not change the cursor position
1597 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001598 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001599 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001600 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001601 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1602 call assert_equal(1, line('.'))
1603 close
1604
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001605 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001606 \ {'bufnr': a:bnum, 'lnum': 4},
1607 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001608 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001609 call assert_equal(3, len(l))
1610 call assert_equal(5, l[2].lnum)
1611
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001612 call g:Xsetlist([])
1613 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001614 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001615
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001616 " Tests for setting the 'valid' flag
1617 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1618 Xwindow
1619 call assert_equal(1, winnr('$'))
1620 let l = g:Xgetlist()
1621 call g:Xsetlist(l)
1622 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001623 " Adding a non-valid entry should not mark the list as having valid entries
1624 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1625 Xwindow
1626 call assert_equal(1, winnr('$'))
1627
1628 " :cnext/:cprev should still work even with invalid entries in the list
1629 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1630 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1631 call g:Xsetlist(l)
1632 Xnext
1633 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1634 Xprev
1635 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1636 " :cnext/:cprev should still work after appending invalid entries to an
1637 " empty list
1638 call g:Xsetlist([])
1639 call g:Xsetlist(l, 'a')
1640 Xnext
1641 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1642 Xprev
1643 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1644
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001645 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1646 Xwindow
1647 call assert_equal(2, winnr('$'))
1648 Xclose
1649 let save_efm = &efm
1650 set efm=%m
1651 Xgetexpr 'TestMessage'
1652 let l = g:Xgetlist()
1653 call g:Xsetlist(l)
1654 call assert_equal(1, g:Xgetlist()[0].valid)
1655 let &efm = save_efm
1656
Bram Moolenaaree85df32017-03-19 14:19:50 +01001657 " Error cases:
1658 " Refer to a non-existing buffer and pass a non-dictionary type
1659 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1660 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1661 call g:Xsetlist([[1, 2,3]])
1662 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001663 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001664endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001665
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001666func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001667 new Xtestfile | only
1668 let bnum = bufnr('%')
1669 call setline(1, range(1,5))
1670
1671 call SetXlistTests('c', bnum)
1672 call SetXlistTests('l', bnum)
1673
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001674 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001675 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001676endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001677
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001678func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001679 call s:setup_commands(a:cchar)
1680
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001681 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001682 let @/ = 'Test_'
1683 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001684 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001685 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001686 Xvimgrep empty test_quickfix.vim
1687 call assert_true(len(g:Xgetlist()) > 0)
1688 Xvimgrep matches test_quickfix.vim
1689 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001690 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001691 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001692 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001693 call g:Xsetlist([], 'r')
1694 call assert_true(len(g:Xgetlist()) == 0)
1695 Xolder
1696 call assert_equal(testlen, len(g:Xgetlist()))
1697 Xnewer
1698 Xnewer
1699 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001700endfunc
1701
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001702func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001703 call Xlist_empty_middle('c')
1704 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001705endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001706
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001707func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001708 call s:setup_commands(a:cchar)
1709
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001710 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001711 Xvimgrep one test_quickfix.vim
1712 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001713 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001714 Xvimgrep two test_quickfix.vim
1715 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001716 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001717 Xvimgrep three test_quickfix.vim
1718 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001719 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001720 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001721 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001722 call g:Xsetlist([], 'r')
1723 call assert_true(len(g:Xgetlist()) == 0)
1724 Xnewer
1725 call assert_equal(twolen, len(g:Xgetlist()))
1726 Xnewer
1727 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001728endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001729
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001730func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001731 call Xlist_empty_older('c')
1732 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001733endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001734
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001735func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001736 call s:setup_commands(a:cchar)
1737
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001738 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1739 \ {'filename': 'fnameB', 'text': 'B'}]
1740 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1741 \ {'filename': 'fnameD', 'text': 'D'},
1742 \ {'filename': 'fnameE', 'text': 'E'}]
1743
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001744 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001745 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001746 silent! Xnewer 99
1747 call g:Xsetlist(list1)
1748 call g:Xsetlist(list2)
1749 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001750 call assert_equal(3, len(li))
1751 call assert_equal('C', li[0]['text'])
1752 call assert_equal('D', li[1]['text'])
1753 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001754 silent! Xolder
1755 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001756 call assert_equal(2, len(li))
1757 call assert_equal('A', li[0]['text'])
1758 call assert_equal('B', li[1]['text'])
1759
1760 " {action} is specified ' '.
1761 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001762 silent! Xnewer 99
1763 call g:Xsetlist(list1)
1764 call g:Xsetlist(list2, ' ')
1765 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001766 call assert_equal(3, len(li))
1767 call assert_equal('C', li[0]['text'])
1768 call assert_equal('D', li[1]['text'])
1769 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001770 silent! Xolder
1771 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001772 call assert_equal(2, len(li))
1773 call assert_equal('A', li[0]['text'])
1774 call assert_equal('B', li[1]['text'])
1775
1776 " {action} is specified 'a'.
1777 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001778 silent! Xnewer 99
1779 call g:Xsetlist(list1)
1780 call g:Xsetlist(list2, 'a')
1781 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001782 call assert_equal(5, len(li))
1783 call assert_equal('A', li[0]['text'])
1784 call assert_equal('B', li[1]['text'])
1785 call assert_equal('C', li[2]['text'])
1786 call assert_equal('D', li[3]['text'])
1787 call assert_equal('E', li[4]['text'])
1788
1789 " {action} is specified 'r'.
1790 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001791 silent! Xnewer 99
1792 call g:Xsetlist(list1)
1793 call g:Xsetlist(list2, 'r')
1794 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001795 call assert_equal(3, len(li))
1796 call assert_equal('C', li[0]['text'])
1797 call assert_equal('D', li[1]['text'])
1798 call assert_equal('E', li[2]['text'])
1799
1800 " Test for wrong value.
1801 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001802 call assert_fails("call g:Xsetlist(0)", 'E714:')
1803 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1804 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1805 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1806 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001807endfunc
1808
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001809func Test_setqflist_invalid_nr()
1810 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001811 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001812endfunc
1813
Bram Moolenaar99234f22020-02-10 22:56:54 +01001814func Test_setqflist_user_sets_buftype()
1815 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1816 set buftype=quickfix
1817 call setqflist([], 'a')
1818 enew
1819endfunc
1820
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001821func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001822 call XquickfixSetListWithAct('c')
1823 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001824endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001825
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001826func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001827 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001828
Bram Moolenaar049cba92016-06-26 14:38:04 +02001829 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001830 call assert_equal(1, l[0].lnum)
1831 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001832 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001833 call assert_equal(2, l[1].lnum)
1834 call assert_equal(1, l[1].col)
1835 call assert_equal(4070, len(l[1].text))
1836 call assert_equal(3, l[2].lnum)
1837 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001838 call assert_equal(4070, len(l[2].text))
1839 call assert_equal(4, l[3].lnum)
1840 call assert_equal(1, l[3].col)
1841 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001842
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001843 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001844endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001845
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001846func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001847 call s:setup_commands(a:cchar)
1848
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001849 let testfile = 'samples/quickfix.txt'
1850
1851 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001852 exe 'Xgetfile' testfile
1853 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001854
1855 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001856 Xexpr readfile(testfile)
1857 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001858
1859 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001860 Xexpr join(readfile(testfile), "\n")
1861 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001862
1863 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001864 exe 'edit' testfile
1865 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001866 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001867endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001868
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001869func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001870 call s:long_lines_tests('c')
1871 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001872endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001873
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001874func Test_cgetfile_on_long_lines()
1875 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1876 " are read at a time.
1877 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1878 let lines = [
1879 \ '/tmp/file1:1:1:aaa',
1880 \ '/tmp/file2:1:1:%s',
1881 \ '/tmp/file3:1:1:bbb',
1882 \ '/tmp/file4:1:1:ccc',
1883 \ ]
1884 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1885 call writefile(lines, 'Xcqetfile.txt')
1886 cgetfile Xcqetfile.txt
1887 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1888 endfor
1889 call delete('Xcqetfile.txt')
1890endfunc
1891
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001892func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001893 let l = []
1894 for i in range(1, 20)
1895 call add(l, 'Line' . i)
1896 endfor
1897 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001898endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001899
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001900func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001901 call s:create_test_file('Xqftestfile1')
1902 call s:create_test_file('Xqftestfile2')
1903 call s:create_test_file('Xqftestfile3')
1904
1905 new | only
1906 edit Xqftestfile1
1907 let file1_winid = win_getid()
1908 new Xqftestfile2
1909 let file2_winid = win_getid()
1910 cgetexpr ['Xqftestfile1:5:Line5',
1911 \ 'Xqftestfile1:6:Line6',
1912 \ 'Xqftestfile2:10:Line10',
1913 \ 'Xqftestfile2:11:Line11',
1914 \ 'Xqftestfile3:15:Line15',
1915 \ 'Xqftestfile3:16:Line16']
1916
1917 new
1918 let winid = win_getid()
1919 cfirst | cnext
1920 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001921 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001922 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001923 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001924 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001925
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001926 " Test for 'switchbuf' set to search for files in windows in the current
1927 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001928 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001929 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001930 cfirst | cnext
1931 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001932 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001933 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001934 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001935 call assert_equal(file2_winid, win_getid())
1936
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001937 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1938 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001939 enew | only
1940 set switchbuf=usetab
1941 tabedit Xqftestfile1
1942 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001943 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001944 tabfirst
1945 cfirst | cnext
1946 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001947 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001948 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001949 6cnext
1950 call assert_equal(4, tabpagenr())
1951 2cpfile
1952 call assert_equal(2, tabpagenr())
1953 2cnfile
1954 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001955 tabfirst | tabonly | enew
1956
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001957 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001958 set switchbuf=split
1959 cfirst | cnext
1960 call assert_equal(1, winnr('$'))
1961 cnext | cnext
1962 call assert_equal(2, winnr('$'))
1963 cnext | cnext
1964 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001965
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001966 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001967 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001968 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001969 cfirst | cnext
1970 call assert_equal(1, tabpagenr('$'))
1971 cnext | cnext
1972 call assert_equal(2, tabpagenr('$'))
1973 cnext | cnext
1974 call assert_equal(3, tabpagenr('$'))
1975 tabfirst | enew | tabonly | only
1976
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001977 set switchbuf=uselast
1978 split
1979 let last_winid = win_getid()
1980 copen
1981 exe "normal 1G\<CR>"
1982 call assert_equal(last_winid, win_getid())
1983 enew | only
1984
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001985 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1986 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001987 set switchbuf=
1988 edit Xqftestfile1
1989 let file1_winid = win_getid()
1990 new Xqftestfile2
1991 let file2_winid = win_getid()
1992 copen
1993 exe "normal 1G\<CR>"
1994 call assert_equal(file1_winid, win_getid())
1995 copen
1996 exe "normal 3G\<CR>"
1997 call assert_equal(file2_winid, win_getid())
1998 copen | only
1999 exe "normal 5G\<CR>"
2000 call assert_equal(2, winnr('$'))
2001 call assert_equal(1, bufwinnr('Xqftestfile3'))
2002
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002003 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002004 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002005 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002006 set switchbuf=usetab
2007 tabedit Xqftestfile1
2008 tabedit Xqftestfile2
2009 tabedit Xqftestfile3
2010 tabfirst
2011 copen | only
2012 clast
2013 call assert_equal(4, tabpagenr())
2014 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002015
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002016 " Jumping to a file that is not present in any of the tabpages and the
2017 " current tabpage doesn't have any usable windows, should open it in a new
2018 " window in the current tabpage.
2019 copen | only
2020 cfirst
2021 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002022 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002023
2024 " If opening a file changes 'switchbuf', then the new value should be
2025 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002026 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002027 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
2028 enew | only
2029 set switchbuf&vim
2030 cexpr "Xqftestfile1:1:10"
2031 call assert_equal('split', &switchbuf)
2032 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2033 enew | only
2034 set switchbuf=useopen
2035 cexpr "Xqftestfile1:1:10"
2036 call assert_equal('usetab', &switchbuf)
2037 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2038 enew | only
2039 set switchbuf=useopen
2040 cexpr "Xqftestfile1:1:10"
2041 call assert_equal('', &switchbuf)
2042
Bram Moolenaar049cba92016-06-26 14:38:04 +02002043 call delete('Xqftestfile1')
2044 call delete('Xqftestfile2')
2045 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002046 set switchbuf&vim
2047
2048 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002049endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002050
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002051func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002052 call s:setup_commands(a:cchar)
2053
2054 enew | only
2055
Bram Moolenaarc1542742016-07-20 21:44:37 +02002056 let fname = 'Xqftestfile' . a:cchar
2057 call s:create_test_file(fname)
2058 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002059
Bram Moolenaarc1542742016-07-20 21:44:37 +02002060 Xgetexpr [fname . ':5:Line5',
2061 \ fname . ':10:Line10',
2062 \ fname . ':15:Line15',
2063 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002064
2065 6,14delete
2066 call append(6, ['Buffer', 'Window'])
2067
2068 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002069 call assert_equal(5, l[0].lnum)
2070 call assert_equal(6, l[2].lnum)
2071 call assert_equal(13, l[3].lnum)
2072
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002073 " If a file doesn't have any quickfix entries, then deleting lines in the
2074 " file should not update the quickfix list
2075 call g:Xsetlist([], 'f')
2076 1,2delete
2077 call assert_equal([], g:Xgetlist())
2078
Bram Moolenaar049cba92016-06-26 14:38:04 +02002079 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002080 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002081endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002082
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002083func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002084 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002085 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002086 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002087 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002088endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002089
2090" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002091func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002092 call s:setup_commands(a:cchar)
2093
2094 " The following lines are used for the grep test. Don't remove.
2095 " Grep_Test_Text: Match 1
2096 " Grep_Test_Text: Match 2
2097 " GrepAdd_Test_Text: Match 1
2098 " GrepAdd_Test_Text: Match 2
2099 enew! | only
2100 set makeef&vim
2101 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002102 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002103 Xopen
2104 call assert_true(w:quickfix_title =~ '^:grep')
2105 Xclose
2106 enew
2107 set makeef=Temp_File_##
2108 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002109 call assert_true(len(g:Xgetlist()) == 9)
2110
2111 " Try with 'grepprg' set to 'internal'
2112 set grepprg=internal
2113 silent Xgrep Grep_Test_Text: test_quickfix.vim
2114 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2115 call assert_true(len(g:Xgetlist()) == 9)
2116 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002117
2118 call writefile(['Vim'], 'XtestTempFile')
2119 set makeef=XtestTempFile
2120 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002121 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002122 call assert_false(filereadable('XtestTempFile'))
2123 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002124endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002125
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002126func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002127 " The grepprg may not be set on non-Unix systems
2128 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002129
2130 call s:test_xgrep('c')
2131 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002132endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002133
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002134func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002135 " Use one 'errorformat' for two windows. Add an expression to each of them,
2136 " make sure they each keep their own state.
2137 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2138 call mkdir('Xone/a', 'p')
2139 call mkdir('Xtwo/a', 'p')
2140 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2141 call writefile(lines, 'Xone/a/one.txt')
2142 call writefile(lines, 'Xtwo/a/two.txt')
2143
2144 new one
2145 let one_id = win_getid()
2146 lexpr ""
2147 new two
2148 let two_id = win_getid()
2149 lexpr ""
2150
2151 laddexpr "Entering dir 'Xtwo/a'"
2152 call win_gotoid(one_id)
2153 laddexpr "Entering dir 'Xone/a'"
2154 call win_gotoid(two_id)
2155 laddexpr 'two.txt:5:two two two'
2156 call win_gotoid(one_id)
2157 laddexpr 'one.txt:3:one one one'
2158
2159 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002160 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2161 call assert_equal(3, loc_one[1].lnum)
2162
2163 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002164 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2165 call assert_equal(5, loc_two[1].lnum)
2166
2167 call win_gotoid(one_id)
2168 bwipe!
2169 call win_gotoid(two_id)
2170 bwipe!
2171 call delete('Xone', 'rf')
2172 call delete('Xtwo', 'rf')
2173endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002174
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002175func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002176 call s:setup_commands(a:cchar)
2177
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002178 " Calling lbottom without any errors should fail
2179 if a:cchar == 'l'
2180 call assert_fails('lbottom', 'E776:')
2181 endif
2182
Bram Moolenaar875feea2017-06-11 16:07:51 +02002183 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002184 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002185 let wid = win_getid()
2186 call assert_equal(1, line('.'))
2187 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002188 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002189 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002190 call win_gotoid(wid)
2191 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002192 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002193endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002194
2195" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002196func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002197 call XbottomTests('c')
2198 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002199endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002200
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002201func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002202 call s:setup_commands(a:cchar)
2203
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002204 " clear all lists after the first one, then replace the first one.
2205 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002206 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002207 let entry = {'filename': 'foo', 'lnum': 42}
2208 call g:Xsetlist([entry], 'r')
2209 call g:Xsetlist([entry, entry])
2210 call g:Xsetlist([entry, entry, entry])
2211 let res = split(execute(a:cchar . 'hist'), "\n")
2212 call assert_equal(3, len(res))
2213 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2214 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2215 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2216 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002217
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002218 " Test for changing the quickfix lists
2219 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2220 exe '1' . a:cchar . 'hist'
2221 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2222 exe '3' . a:cchar . 'hist'
2223 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2224 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2225 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2226
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002227 call g:Xsetlist([], 'f')
2228 let l = split(execute(a:cchar . 'hist'), "\n")
2229 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002230 if a:cchar == 'c'
2231 call assert_fails('4chist', 'E16:')
2232 else
2233 call assert_fails('4lhist', 'E776:')
2234 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002235
2236 " An empty list should still show the stack history
2237 call g:Xsetlist([])
2238 let res = split(execute(a:cchar . 'hist'), "\n")
2239 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2240
2241 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002242endfunc
2243
2244func Test_history()
2245 call HistoryTest('c')
2246 call HistoryTest('l')
2247endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002248
2249func Test_duplicate_buf()
2250 " make sure we can get the highest buffer number
2251 edit DoesNotExist
2252 edit DoesNotExist2
2253 let last_buffer = bufnr("$")
2254
2255 " make sure only one buffer is created
2256 call writefile(['this one', 'that one'], 'Xgrepthis')
2257 vimgrep one Xgrepthis
2258 vimgrep one Xgrepthis
2259 call assert_equal(last_buffer + 1, bufnr("$"))
2260
2261 call delete('Xgrepthis')
2262endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002263
2264" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002265func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002266 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002267
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002268 " Error cases
2269 call assert_fails('call g:Xgetlist(99)', 'E715:')
2270 call assert_fails('call g:Xsetlist(99)', 'E714:')
2271 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002272
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002273 " Set and get the title
2274 call g:Xsetlist([])
2275 Xopen
2276 wincmd p
2277 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2278 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2279 call assert_equal(0, s)
2280 let d = g:Xgetlist({"title":1})
2281 call assert_equal('Sample', d.title)
2282 " Try setting title to a non-string value
2283 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2284 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2285
2286 Xopen
2287 call assert_equal('Sample', w:quickfix_title)
2288 Xclose
2289
2290 " Tests for action argument
2291 silent! Xolder 999
2292 let qfnr = g:Xgetlist({'all':1}).nr
2293 call g:Xsetlist([], 'r', {'title' : 'N1'})
2294 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2295 call g:Xsetlist([], ' ', {'title' : 'N2'})
2296 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2297
2298 let res = g:Xgetlist({'nr': 0})
2299 call assert_equal(qfnr + 1, res.nr)
2300 call assert_equal(['nr'], keys(res))
2301
2302 call g:Xsetlist([], ' ', {'title' : 'N3'})
2303 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2304
2305 " Changing the title of an earlier quickfix list
2306 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2307 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2308
2309 " Changing the title of an invalid quickfix list
2310 call assert_equal(-1, g:Xsetlist([], ' ',
2311 \ {'title' : 'SomeTitle', 'nr' : 99}))
2312 call assert_equal(-1, g:Xsetlist([], ' ',
2313 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2314
2315 if a:cchar == 'c'
2316 copen
2317 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2318 cclose
2319 endif
2320
2321 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002322 call assert_fails('call g:Xgetlist([])', 'E715:')
2323 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002324 let s = g:Xsetlist([], 'a', {'abc':1})
2325 call assert_equal(-1, s)
2326
2327 call assert_equal({}, g:Xgetlist({'abc':1}))
2328 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2329 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2330
2331 if a:cchar == 'l'
2332 call assert_equal({}, getloclist(99, {'title': 1}))
2333 endif
2334
2335 " Context related tests
2336 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2337 call assert_equal(0, s)
2338 call test_garbagecollect_now()
2339 let d = g:Xgetlist({'context':1})
2340 call assert_equal([1,2,3], d.context)
2341 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2342 let d = g:Xgetlist({'context':1})
2343 call assert_equal({'color':'green'}, d.context)
2344 call g:Xsetlist([], 'a', {'context':"Context info"})
2345 let d = g:Xgetlist({'context':1})
2346 call assert_equal("Context info", d.context)
2347 call g:Xsetlist([], 'a', {'context':246})
2348 let d = g:Xgetlist({'context':1})
2349 call assert_equal(246, d.context)
2350 " set other Vim data types as context
2351 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2352 if has('channel')
2353 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2354 endif
2355 if has('job')
2356 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2357 endif
2358 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2359 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2360 call g:Xsetlist([], 'a', {'context' : ''})
2361 call test_garbagecollect_now()
2362 if a:cchar == 'l'
2363 " Test for copying context across two different location lists
2364 new | only
2365 let w1_id = win_getid()
2366 let l = [1]
2367 call setloclist(0, [], 'a', {'context':l})
2368 new
2369 let w2_id = win_getid()
2370 call add(l, 2)
2371 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2372 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2373 unlet! l
2374 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2375 only
2376 call setloclist(0, [], 'f')
2377 call assert_equal('', getloclist(0, {'context':1}).context)
2378 endif
2379
2380 " Test for changing the context of previous quickfix lists
2381 call g:Xsetlist([], 'f')
2382 Xexpr "One"
2383 Xexpr "Two"
2384 Xexpr "Three"
2385 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2386 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2387 " Also, check for setting the context using quickfix list number zero.
2388 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2389 call test_garbagecollect_now()
2390 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2391 call assert_equal([1], l.context)
2392 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2393 call assert_equal([2], l.context)
2394 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2395 call assert_equal([3], l.context)
2396
2397 " Test for changing the context through reference and for garbage
2398 " collection of quickfix context
2399 let l = ["red"]
2400 call g:Xsetlist([], ' ', {'context' : l})
2401 call add(l, "blue")
2402 let x = g:Xgetlist({'context' : 1})
2403 call add(x.context, "green")
2404 call assert_equal(["red", "blue", "green"], l)
2405 call assert_equal(["red", "blue", "green"], x.context)
2406 unlet l
2407 call test_garbagecollect_now()
2408 let m = g:Xgetlist({'context' : 1})
2409 call assert_equal(["red", "blue", "green"], m.context)
2410
2411 " Test for setting/getting items
2412 Xexpr ""
2413 let qfprev = g:Xgetlist({'nr':0})
2414 let s = g:Xsetlist([], ' ', {'title':'Green',
2415 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2416 call assert_equal(0, s)
2417 let qfcur = g:Xgetlist({'nr':0})
2418 call assert_true(qfcur.nr == qfprev.nr + 1)
2419 let l = g:Xgetlist({'items':1})
2420 call assert_equal('F1', bufname(l.items[0].bufnr))
2421 call assert_equal(10, l.items[0].lnum)
2422 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2423 \ {'filename':'F2', 'lnum':30}]})
2424 let l = g:Xgetlist({'items':1})
2425 call assert_equal('F2', bufname(l.items[2].bufnr))
2426 call assert_equal(30, l.items[2].lnum)
2427 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2428 let l = g:Xgetlist({'items':1})
2429 call assert_equal('F3', bufname(l.items[0].bufnr))
2430 call assert_equal(40, l.items[0].lnum)
2431 call g:Xsetlist([], 'r', {'items' : []})
2432 let l = g:Xgetlist({'items':1})
2433 call assert_equal(0, len(l.items))
2434
2435 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2436 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2437 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2438 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2439
2440 " Test for getting id of window associated with a location list window
2441 if a:cchar == 'l'
2442 only
2443 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2444 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002445 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002446 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2447 wincmd w
2448 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2449 only
2450 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002451
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002452 " The following used to crash Vim with address sanitizer
2453 call g:Xsetlist([], 'f')
2454 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2455 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002456
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002457 " Try setting the items using a string
2458 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002459
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002460 " Save and restore the quickfix stack
2461 call g:Xsetlist([], 'f')
2462 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2463 Xexpr "File1:10:Line1"
2464 Xexpr "File2:20:Line2"
2465 Xexpr "File3:30:Line3"
2466 let last_qf = g:Xgetlist({'nr':'$'}).nr
2467 call assert_equal(3, last_qf)
2468 let qstack = []
2469 for i in range(1, last_qf)
2470 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2471 endfor
2472 call g:Xsetlist([], 'f')
2473 for i in range(len(qstack))
2474 call g:Xsetlist([], ' ', qstack[i])
2475 endfor
2476 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2477 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2478 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2479 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2480 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002481
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002482 " Swap two quickfix lists
2483 Xexpr "File1:10:Line10"
2484 Xexpr "File2:20:Line20"
2485 Xexpr "File3:30:Line30"
2486 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2487 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2488 let l1=g:Xgetlist({'nr':1,'all':1})
2489 let l2=g:Xgetlist({'nr':2,'all':1})
2490 let save_id = l1.id
2491 let l1.id=l2.id
2492 let l2.id=save_id
2493 call g:Xsetlist([], 'r', l1)
2494 call g:Xsetlist([], 'r', l2)
2495 let newl1=g:Xgetlist({'nr':1,'all':1})
2496 let newl2=g:Xgetlist({'nr':2,'all':1})
2497 call assert_equal('Fruits', newl1.title)
2498 call assert_equal(['Fruits'], newl1.context)
2499 call assert_equal('Line20', newl1.items[0].text)
2500 call assert_equal('Colors', newl2.title)
2501 call assert_equal(['Colors'], newl2.context)
2502 call assert_equal('Line10', newl2.items[0].text)
2503 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002504
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002505 " Cannot specify both a non-empty list argument and a dict argument
2506 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002507endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002508
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002509func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002510 call Xproperty_tests('c')
2511 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002512endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002513
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002514" Test for setting the current index in the location/quickfix list
2515func Xtest_setqfidx(cchar)
2516 call s:setup_commands(a:cchar)
2517
2518 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2519 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2520 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2521
2522 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2523 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2524 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2525 Xolder 2
2526 Xopen
2527 call assert_equal(3, line('.'))
2528 Xnewer
2529 call assert_equal(2, line('.'))
2530 Xnewer
2531 call assert_equal(2, line('.'))
2532 " Update the current index with the quickfix window open
2533 wincmd w
2534 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2535 Xopen
2536 call assert_equal(3, line('.'))
2537 Xclose
2538
2539 " Set the current index to the last entry
2540 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2541 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2542 " A large value should set the index to the last index
2543 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2544 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2545 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2546 " Invalid index values
2547 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2548 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2549 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2550 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2551 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2552 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2553 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2554
2555 call g:Xsetlist([], 'f')
2556 new | only
2557endfunc
2558
2559func Test_setqfidx()
2560 call Xtest_setqfidx('c')
2561 call Xtest_setqfidx('l')
2562endfunc
2563
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002564" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002565func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002566 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002567endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002568
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002569func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002570 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2571 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2572
2573 let g:acmds = []
2574 cexpr "F1:10:Line 10"
2575 caddexpr "F1:20:Line 20"
2576 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002577 cexpr ""
2578 caddexpr ""
2579 cgetexpr ""
2580 silent! cexpr non_existing_func()
2581 silent! caddexpr non_existing_func()
2582 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002583 let l = ['precexpr',
2584 \ 'postcexpr',
2585 \ 'precaddexpr',
2586 \ 'postcaddexpr',
2587 \ 'precgetexpr',
2588 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002589 \ 'precexpr',
2590 \ 'postcexpr',
2591 \ 'precaddexpr',
2592 \ 'postcaddexpr',
2593 \ 'precgetexpr',
2594 \ 'postcgetexpr',
2595 \ 'precexpr',
2596 \ 'precaddexpr',
2597 \ 'precgetexpr']
2598 call assert_equal(l, g:acmds)
2599
2600 let g:acmds = []
2601 enew! | call append(0, "F2:10:Line 10")
2602 cbuffer!
2603 enew! | call append(0, "F2:20:Line 20")
2604 cgetbuffer
2605 enew! | call append(0, "F2:30:Line 30")
2606 caddbuffer
2607 new
2608 let bnum = bufnr('%')
2609 bunload
2610 exe 'silent! cbuffer! ' . bnum
2611 exe 'silent! cgetbuffer ' . bnum
2612 exe 'silent! caddbuffer ' . bnum
2613 enew!
2614 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002615 \ 'postcbuffer',
2616 \ 'precgetbuffer',
2617 \ 'postcgetbuffer',
2618 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002619 \ 'postcaddbuffer',
2620 \ 'precbuffer',
2621 \ 'precgetbuffer',
2622 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002623 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002624
2625 call writefile(['Xtest:1:Line1'], 'Xtest')
2626 call writefile([], 'Xempty')
2627 let g:acmds = []
2628 cfile Xtest
2629 caddfile Xtest
2630 cgetfile Xtest
2631 cfile Xempty
2632 caddfile Xempty
2633 cgetfile Xempty
2634 silent! cfile do_not_exist
2635 silent! caddfile do_not_exist
2636 silent! cgetfile do_not_exist
2637 let l = ['precfile',
2638 \ 'postcfile',
2639 \ 'precaddfile',
2640 \ 'postcaddfile',
2641 \ 'precgetfile',
2642 \ 'postcgetfile',
2643 \ 'precfile',
2644 \ 'postcfile',
2645 \ 'precaddfile',
2646 \ 'postcaddfile',
2647 \ 'precgetfile',
2648 \ 'postcgetfile',
2649 \ 'precfile',
2650 \ 'postcfile',
2651 \ 'precaddfile',
2652 \ 'postcaddfile',
2653 \ 'precgetfile',
2654 \ 'postcgetfile']
2655 call assert_equal(l, g:acmds)
2656
2657 let g:acmds = []
2658 helpgrep quickfix
2659 silent! helpgrep non_existing_help_topic
2660 vimgrep test Xtest
2661 vimgrepadd test Xtest
2662 silent! vimgrep non_existing_test Xtest
2663 silent! vimgrepadd non_existing_test Xtest
2664 set makeprg=
2665 silent! make
2666 set makeprg&
2667 let l = ['prehelpgrep',
2668 \ 'posthelpgrep',
2669 \ 'prehelpgrep',
2670 \ 'posthelpgrep',
2671 \ 'previmgrep',
2672 \ 'postvimgrep',
2673 \ 'previmgrepadd',
2674 \ 'postvimgrepadd',
2675 \ 'previmgrep',
2676 \ 'postvimgrep',
2677 \ 'previmgrepadd',
2678 \ 'postvimgrepadd',
2679 \ 'premake',
2680 \ 'postmake']
2681 call assert_equal(l, g:acmds)
2682
2683 if has('unix')
2684 " Run this test only on Unix-like systems. The grepprg may not be set on
2685 " non-Unix systems.
2686 " The following lines are used for the grep test. Don't remove.
2687 " Grep_Autocmd_Text: Match 1
2688 " GrepAdd_Autocmd_Text: Match 2
2689 let g:acmds = []
2690 silent grep Grep_Autocmd_Text test_quickfix.vim
2691 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2692 silent grep abc123def Xtest
2693 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002694 set grepprg=internal
2695 silent grep Grep_Autocmd_Text test_quickfix.vim
2696 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2697 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2698 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2699 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002700 let l = ['pregrep',
2701 \ 'postgrep',
2702 \ 'pregrepadd',
2703 \ 'postgrepadd',
2704 \ 'pregrep',
2705 \ 'postgrep',
2706 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002707 \ 'postgrepadd',
2708 \ 'pregrep',
2709 \ 'postgrep',
2710 \ 'pregrepadd',
2711 \ 'postgrepadd',
2712 \ 'prelgrep',
2713 \ 'postlgrep',
2714 \ 'prelgrepadd',
2715 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002716 call assert_equal(l, g:acmds)
2717 endif
2718
2719 call delete('Xtest')
2720 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002721 au! QuickFixCmdPre
2722 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002723endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002724
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002725func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002726 set efm=%m
2727 lgetexpr '?'
2728
2729 try
2730 call DoesNotExit()
2731 catch
2732 lgetexpr '1'
2733 finally
2734 lgetexpr '1'
2735 endtry
2736
2737 call assert_equal('1', getloclist(0)[0].text)
2738
2739 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002740endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002741
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002742func Test_caddbuffer_wrong()
2743 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002744 let save_efm = &efm
2745 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2746 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2747 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002748 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002749 bwipe!
2750endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002751
2752func Test_caddexpr_wrong()
2753 " This used to cause a memory access in freed memory.
2754 cbuffer
2755 cbuffer
2756 copen
2757 let save_efm = &efm
2758 set efm=%
2759 call assert_fails('caddexpr ""', 'E376:')
2760 let &efm = save_efm
2761endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002762
2763func Test_dirstack_cleanup()
2764 " This used to cause a memory access in freed memory.
2765 let save_efm = &efm
2766 lexpr '0'
2767 lopen
2768 fun X(c)
2769 let save_efm=&efm
2770 set efm=%D%f
2771 if a:c == 'c'
2772 caddexpr '::'
2773 else
2774 laddexpr ':0:0'
2775 endif
2776 let &efm=save_efm
2777 endfun
2778 call X('c')
2779 call X('l')
2780 call setqflist([], 'r')
2781 caddbuffer
2782 let &efm = save_efm
2783endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002784
2785" Tests for jumping to entries from the location list window and quickfix
2786" window
2787func Test_cwindow_jump()
2788 set efm=%f%%%l%%%m
2789 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2790 lopen | only
2791 lfirst
2792 call assert_true(winnr('$') == 2)
2793 call assert_true(winnr() == 1)
2794 " Location list for the new window should be set
2795 call assert_true(getloclist(0)[2].text == 'Line 30')
2796
2797 " Open a scratch buffer
2798 " Open a new window and create a location list
2799 " Open the location list window and close the other window
2800 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002801 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002802 " should not be used.
2803 enew | only
2804 set buftype=nofile
2805 below new
2806 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2807 lopen
2808 2wincmd c
2809 lnext
2810 call assert_true(winnr('$') == 3)
2811 call assert_true(winnr() == 2)
2812
2813 " Open two windows with two different location lists
2814 " Open the location list window and close the previous window
2815 " Jump to an entry in the location list window
2816 " Should open the file in the first window and not set the location list.
2817 enew | only
2818 lgetexpr ["F1%5%Line 5"]
2819 below new
2820 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2821 lopen
2822 2wincmd c
2823 lnext
2824 call assert_true(winnr() == 1)
2825 call assert_true(getloclist(0)[0].text == 'Line 5')
2826
2827 enew | only
2828 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2829 copen
2830 cnext
2831 call assert_true(winnr('$') == 2)
2832 call assert_true(winnr() == 1)
2833
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002834 " open the quickfix buffer in two windows and jump to an entry. Should open
2835 " the file in the first quickfix window.
2836 enew | only
2837 copen
2838 let bnum = bufnr('')
2839 exe 'sbuffer ' . bnum
2840 wincmd b
2841 cfirst
2842 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002843 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002844 enew | only
2845 exe 'sb' bnum
2846 exe 'botright sb' bnum
2847 wincmd t
2848 clast
2849 call assert_equal(2, winnr())
2850 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2851 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2852
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002853 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002854 " window by wrapping around the window list.
2855 enew | only
2856 call setloclist(0, [], 'f')
2857 new | new
2858 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2859 lopen
2860 1close
2861 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2862 lnext
2863 call assert_equal(3, winnr())
2864 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2865
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002866 enew | only
2867 set efm&vim
2868endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002869
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002870func Test_cwindow_highlight()
2871 CheckScreendump
2872
2873 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002874 call setline(1, ['some', 'text', 'with', 'matches'])
2875 write XCwindow
2876 vimgrep e XCwindow
2877 redraw
2878 cwindow 4
2879 END
2880 call writefile(lines, 'XtestCwindow')
2881 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2882 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2883
2884 call term_sendkeys(buf, ":cnext\<CR>")
2885 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2886
2887 " clean up
2888 call StopVimInTerminal(buf)
2889 call delete('XtestCwindow')
2890 call delete('XCwindow')
2891endfunc
2892
Bram Moolenaaree85df32017-03-19 14:19:50 +01002893func XvimgrepTests(cchar)
2894 call s:setup_commands(a:cchar)
2895
2896 call writefile(['Editor:VIM vim',
2897 \ 'Editor:Emacs EmAcS',
2898 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002899 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002900
2901 " Error cases
2902 call assert_fails('Xvimgrep /abc *', 'E682:')
2903
2904 let @/=''
2905 call assert_fails('Xvimgrep // *', 'E35:')
2906
2907 call assert_fails('Xvimgrep abc', 'E683:')
2908 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2909 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2910
2911 Xexpr ""
2912 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002913 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002914 let l = g:Xgetlist()
2915 call assert_equal(2, len(l))
2916 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2917
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002918 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002919 let l = g:Xgetlist()
2920 call assert_equal(2, len(l))
2921 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002922 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002923 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002924 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002925
2926 1Xvimgrep ?Editor? Xtestfile*
2927 let l = g:Xgetlist()
2928 call assert_equal(1, len(l))
2929 call assert_equal('Editor:VIM vim', l[0].text)
2930
2931 edit +3 Xtestfile2
2932 Xvimgrep +\cemacs+j Xtestfile1
2933 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002934 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002935 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2936
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002937 " Test for unloading a buffer after vimgrep searched the buffer
2938 %bwipe
2939 Xvimgrep /Editor/j Xtestfile*
2940 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2941 call assert_equal([], getbufinfo('Xtestfile2'))
2942
Bram Moolenaaree85df32017-03-19 14:19:50 +01002943 call delete('Xtestfile1')
2944 call delete('Xtestfile2')
2945endfunc
2946
2947" Tests for the :vimgrep command
2948func Test_vimgrep()
2949 call XvimgrepTests('c')
2950 call XvimgrepTests('l')
2951endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002952
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002953func Test_vimgrep_wildcards_expanded_once()
2954 new X[id-01] file.txt
2955 call setline(1, 'some text to search for')
2956 vimgrep text %
2957 bwipe!
2958endfunc
2959
Bram Moolenaar1c299432018-10-28 14:36:09 +01002960" Test for incsearch highlighting of the :vimgrep pattern
2961" This test used to cause "E315: ml_get: invalid lnum" errors.
2962func Test_vimgrep_incsearch()
2963 enew
2964 set incsearch
2965 call test_override("char_avail", 1)
2966
2967 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2968 let l = getqflist()
2969 call assert_equal(2, len(l))
2970
2971 call test_override("ALL", 0)
2972 set noincsearch
2973endfunc
2974
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002975" Test vimgrep with the last search pattern not set
2976func Test_vimgrep_with_no_last_search_pat()
2977 let lines =<< trim [SCRIPT]
2978 call assert_fails('vimgrep // *', 'E35:')
2979 call writefile(v:errors, 'Xresult')
2980 qall!
2981 [SCRIPT]
2982 call writefile(lines, 'Xscript')
2983 if RunVim([], [], '--clean -S Xscript')
2984 call assert_equal([], readfile('Xresult'))
2985 endif
2986 call delete('Xscript')
2987 call delete('Xresult')
2988endfunc
2989
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002990" Test vimgrep without swap file
2991func Test_vimgrep_without_swap_file()
2992 let lines =<< trim [SCRIPT]
2993 vimgrep grep test_c*
2994 call writefile(['done'], 'Xresult')
2995 qall!
2996 [SCRIPT]
2997 call writefile(lines, 'Xscript')
2998 if RunVim([], [], '--clean -n -S Xscript Xscript')
2999 call assert_equal(['done'], readfile('Xresult'))
3000 endif
3001 call delete('Xscript')
3002 call delete('Xresult')
3003endfunc
3004
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003005func Test_vimgrep_existing_swapfile()
3006 call writefile(['match apple with apple'], 'Xapple')
3007 call writefile(['swapfile'], '.Xapple.swp')
3008 let g:foundSwap = 0
3009 let g:ignoreSwapExists = 1
3010 augroup grep
3011 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3012 augroup END
3013 vimgrep apple Xapple
3014 call assert_equal(1, g:foundSwap)
3015 call assert_match('.Xapple.swo', swapname(''))
3016
3017 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003018 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003019 augroup grep
3020 au! SwapExists
3021 augroup END
3022 unlet g:ignoreSwapExists
3023endfunc
3024
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003025func XfreeTests(cchar)
3026 call s:setup_commands(a:cchar)
3027
3028 enew | only
3029
3030 " Deleting the quickfix stack should work even When the current list is
3031 " somewhere in the middle of the stack
3032 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3033 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3034 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3035 Xolder
3036 call g:Xsetlist([], 'f')
3037 call assert_equal(0, len(g:Xgetlist()))
3038
3039 " After deleting the stack, adding a new list should create a stack with a
3040 " single list.
3041 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3042 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3043
3044 " Deleting the stack from a quickfix window should update/clear the
3045 " quickfix/location list window.
3046 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3047 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3048 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3049 Xolder
3050 Xwindow
3051 call g:Xsetlist([], 'f')
3052 call assert_equal(2, winnr('$'))
3053 call assert_equal(1, line('$'))
3054 Xclose
3055
3056 " Deleting the stack from a non-quickfix window should update/clear the
3057 " quickfix/location list window.
3058 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3059 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3060 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3061 Xolder
3062 Xwindow
3063 wincmd p
3064 call g:Xsetlist([], 'f')
3065 call assert_equal(0, len(g:Xgetlist()))
3066 wincmd p
3067 call assert_equal(2, winnr('$'))
3068 call assert_equal(1, line('$'))
3069
3070 " After deleting the location list stack, if the location list window is
3071 " opened, then a new location list should be created. So opening the
3072 " location list window again should not create a new window.
3073 if a:cchar == 'l'
3074 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3075 wincmd p
3076 lopen
3077 call assert_equal(2, winnr('$'))
3078 endif
3079 Xclose
3080endfunc
3081
Bram Moolenaar74240d32017-12-10 15:26:15 +01003082" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003083func Test_qf_free()
3084 call XfreeTests('c')
3085 call XfreeTests('l')
3086endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003087
3088" Test for buffer overflow when parsing lines and adding new entries to
3089" the quickfix list.
3090func Test_bufoverflow()
3091 set efm=%f:%l:%m
3092 cgetexpr ['File1:100:' . repeat('x', 1025)]
3093
3094 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3095 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3096
3097 set efm=%DEntering\ directory\ %f,%f:%l:%m
3098 cgetexpr ['Entering directory ' . repeat('a', 1006),
3099 \ 'File1:10:Hello World']
3100 set efm&vim
3101endfunc
3102
Bram Moolenaar875feea2017-06-11 16:07:51 +02003103" Tests for getting the quickfix stack size
3104func XsizeTests(cchar)
3105 call s:setup_commands(a:cchar)
3106
3107 call g:Xsetlist([], 'f')
3108 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003109 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3110 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003111
3112 Xexpr "File1:10:Line1"
3113 Xexpr "File2:20:Line2"
3114 Xexpr "File3:30:Line3"
3115 Xolder | Xolder
3116 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3117 call g:Xsetlist([], 'f')
3118
3119 Xexpr "File1:10:Line1"
3120 Xexpr "File2:20:Line2"
3121 Xexpr "File3:30:Line3"
3122 Xolder | Xolder
3123 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3124 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3125endfunc
3126
3127func Test_Qf_Size()
3128 call XsizeTests('c')
3129 call XsizeTests('l')
3130endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003131
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003132func Test_cclose_from_copen()
3133 augroup QF_Test
3134 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003135 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003136 augroup END
3137 copen
3138 augroup QF_Test
3139 au!
3140 augroup END
3141 augroup! QF_Test
3142endfunc
3143
Bram Moolenaar18141832017-06-25 21:17:25 +02003144func Test_cclose_in_autocmd()
3145 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3146 " event will be triggered.
3147 call test_override('starting', 1)
3148 augroup QF_Test
3149 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003150 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003151 augroup END
3152 copen
3153 augroup QF_Test
3154 au!
3155 augroup END
3156 augroup! QF_Test
3157 call test_override('starting', 0)
3158endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003159
Bram Moolenaar379fb762018-08-30 15:58:28 +02003160" Check that ":file" without an argument is possible even when "curbuf_lock"
3161" is set.
3162func Test_file_from_copen()
3163 " Works without argument.
3164 augroup QF_Test
3165 au!
3166 au FileType qf file
3167 augroup END
3168 copen
3169
3170 augroup QF_Test
3171 au!
3172 augroup END
3173 cclose
3174
3175 " Fails with argument.
3176 augroup QF_Test
3177 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003178 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003179 augroup END
3180 copen
3181 augroup QF_Test
3182 au!
3183 augroup END
3184 cclose
3185
3186 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003187endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003188
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003189func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003190 augroup QF_Test
3191 au!
3192 au FileType qf resize 5
3193 augroup END
3194 try
3195 " This should succeed without any exception. No other buffers are
3196 " involved in the autocmd.
3197 copen
3198 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003199 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003200 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003201 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003202 augroup! QF_Test
3203 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003204endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003205
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003206func Test_vimgrep_with_textlock()
3207 new
3208
3209 " Simple way to execute something with "textwinlock" set.
3210 " Check that vimgrep without jumping can be executed.
3211 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3212 normal ax
3213 let qflist = getqflist()
3214 call assert_true(len(qflist) > 0)
3215 call assert_match('RunTheTest', qflist[0].text)
3216 call setqflist([], 'r')
3217 au! InsertCharPre
3218
3219 " Check that vimgrepadd without jumping can be executed.
3220 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3221 normal ax
3222 let qflist = getqflist()
3223 call assert_true(len(qflist) > 0)
3224 call assert_match('RunTheTest', qflist[0].text)
3225 call setqflist([], 'r')
3226 au! InsertCharPre
3227
3228 " Check that lvimgrep without jumping can be executed.
3229 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3230 normal ax
3231 let qflist = getloclist(0)
3232 call assert_true(len(qflist) > 0)
3233 call assert_match('RunTheTest', qflist[0].text)
3234 call setloclist(0, [], 'r')
3235 au! InsertCharPre
3236
3237 " Check that lvimgrepadd without jumping can be executed.
3238 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3239 normal ax
3240 let qflist = getloclist(0)
3241 call assert_true(len(qflist) > 0)
3242 call assert_match('RunTheTest', qflist[0].text)
3243 call setloclist(0, [], 'r')
3244 au! InsertCharPre
3245
3246 " trying to jump will give an error
3247 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3248 call assert_fails('normal ax', 'E565:')
3249 au! InsertCharPre
3250
3251 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3252 call assert_fails('normal ax', 'E565:')
3253 au! InsertCharPre
3254
3255 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3256 call assert_fails('normal ax', 'E565:')
3257 au! InsertCharPre
3258
3259 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3260 call assert_fails('normal ax', 'E565:')
3261 au! InsertCharPre
3262
3263 bwipe!
3264endfunc
3265
Bram Moolenaara8788f42017-07-19 17:06:20 +02003266" Tests for the quickfix buffer b:changedtick variable
3267func Xchangedtick_tests(cchar)
3268 call s:setup_commands(a:cchar)
3269
3270 new | only
3271
3272 Xexpr "" | Xexpr "" | Xexpr ""
3273
3274 Xopen
3275 Xolder
3276 Xolder
3277 Xaddexpr "F1:10:Line10"
3278 Xaddexpr "F2:20:Line20"
3279 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3280 call g:Xsetlist([], 'f')
3281 call assert_equal(8, getbufvar('%', 'changedtick'))
3282 Xclose
3283endfunc
3284
3285func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003286 call Xchangedtick_tests('c')
3287 call Xchangedtick_tests('l')
3288endfunc
3289
3290" Tests for parsing an expression using setqflist()
3291func Xsetexpr_tests(cchar)
3292 call s:setup_commands(a:cchar)
3293
3294 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003295 call g:Xsetlist([], ' ', {'lines' : t})
3296 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003297
3298 let l = g:Xgetlist()
3299 call assert_equal(3, len(l))
3300 call assert_equal(20, l[1].lnum)
3301 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003302 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003303 let l = g:Xgetlist()
3304 call assert_equal(1, len(l))
3305 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003306 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3307 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003308
3309 call g:Xsetlist([], 'f')
3310 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003311 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3312 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3313 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3314 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003315 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3316 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003317
3318 " Adding entries using a custom efm
3319 set efm&
3320 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3321 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3322 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3323 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3324 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3325 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3326 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3327 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003328endfunc
3329
3330func Test_setexpr()
3331 call Xsetexpr_tests('c')
3332 call Xsetexpr_tests('l')
3333endfunc
3334
3335" Tests for per quickfix/location list directory stack
3336func Xmultidirstack_tests(cchar)
3337 call s:setup_commands(a:cchar)
3338
3339 call g:Xsetlist([], 'f')
3340 Xexpr "" | Xexpr ""
3341
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003342 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3343 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3344 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3345 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003346
3347 let l1 = g:Xgetlist({'nr':1, 'items':1})
3348 let l2 = g:Xgetlist({'nr':2, 'items':1})
3349 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3350 call assert_equal(3, l1.items[1].lnum)
3351 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3352 call assert_equal(5, l2.items[1].lnum)
3353endfunc
3354
3355func Test_multidirstack()
3356 call mkdir('Xone/a', 'p')
3357 call mkdir('Xtwo/a', 'p')
3358 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3359 call writefile(lines, 'Xone/a/one.txt')
3360 call writefile(lines, 'Xtwo/a/two.txt')
3361 let save_efm = &efm
3362 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3363
3364 call Xmultidirstack_tests('c')
3365 call Xmultidirstack_tests('l')
3366
3367 let &efm = save_efm
3368 call delete('Xone', 'rf')
3369 call delete('Xtwo', 'rf')
3370endfunc
3371
3372" Tests for per quickfix/location list file stack
3373func Xmultifilestack_tests(cchar)
3374 call s:setup_commands(a:cchar)
3375
3376 call g:Xsetlist([], 'f')
3377 Xexpr "" | Xexpr ""
3378
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003379 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3380 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3381 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3382 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003383
3384 let l1 = g:Xgetlist({'nr':1, 'items':1})
3385 let l2 = g:Xgetlist({'nr':2, 'items':1})
3386 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3387 call assert_equal(3, l1.items[1].lnum)
3388 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3389 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003390
3391 " Test for start of a new error line in the same line where a previous
3392 " error line ends with a file stack.
3393 let efm_val = 'Error\ l%l\ in\ %f,'
3394 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3395 let l = g:Xgetlist({'lines' : [
3396 \ '(one.txt',
3397 \ 'Error l4 in one.txt',
3398 \ ') (two.txt',
3399 \ 'Error l6 in two.txt',
3400 \ ')',
3401 \ 'Error l8 in one.txt'
3402 \ ], 'efm' : efm_val})
3403 call assert_equal(3, len(l.items))
3404 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3405 call assert_equal(4, l.items[0].lnum)
3406 call assert_equal('one.txt', l.items[0].text)
3407 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3408 call assert_equal(6, l.items[1].lnum)
3409 call assert_equal('two.txt', l.items[1].text)
3410 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3411 call assert_equal(8, l.items[2].lnum)
3412 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003413endfunc
3414
3415func Test_multifilestack()
3416 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3417 call writefile(lines, 'one.txt')
3418 call writefile(lines, 'two.txt')
3419 let save_efm = &efm
3420 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3421
3422 call Xmultifilestack_tests('c')
3423 call Xmultifilestack_tests('l')
3424
3425 let &efm = save_efm
3426 call delete('one.txt')
3427 call delete('two.txt')
3428endfunc
3429
3430" Tests for per buffer 'efm' setting
3431func Test_perbuf_efm()
3432 call writefile(["File1-10-Line10"], 'one.txt')
3433 call writefile(["File2#20#Line20"], 'two.txt')
3434 set efm=%f#%l#%m
3435 new | only
3436 new
3437 setlocal efm=%f-%l-%m
3438 cfile one.txt
3439 wincmd w
3440 caddfile two.txt
3441
3442 let l = getqflist()
3443 call assert_equal(10, l[0].lnum)
3444 call assert_equal('Line20', l[1].text)
3445
3446 set efm&
3447 new | only
3448 call delete('one.txt')
3449 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003450endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003451
3452" Open multiple help windows using ":lhelpgrep
3453" This test used to crash Vim
3454func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003455 new | only
3456 lhelpgrep window
3457 lopen
3458 e#
3459 lhelpgrep buffer
3460 call assert_equal(3, winnr('$'))
3461 call assert_true(len(getloclist(1)) != 0)
3462 call assert_true(len(getloclist(2)) != 0)
3463 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003464endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003465
3466" Tests for adding new quickfix lists using setqflist()
3467func XaddQf_tests(cchar)
3468 call s:setup_commands(a:cchar)
3469
3470 " Create a new list using ' ' for action
3471 call g:Xsetlist([], 'f')
3472 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3473 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3474 call assert_equal(1, l.nr)
3475 call assert_equal('Test1', l.title)
3476
3477 " Create a new list using ' ' for action and '$' for 'nr'
3478 call g:Xsetlist([], 'f')
3479 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3480 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3481 call assert_equal(1, l.nr)
3482 call assert_equal('Test2', l.title)
3483
3484 " Create a new list using 'a' for action
3485 call g:Xsetlist([], 'f')
3486 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3487 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3488 call assert_equal(1, l.nr)
3489 call assert_equal('Test3', l.title)
3490
3491 " Create a new list using 'a' for action and '$' for 'nr'
3492 call g:Xsetlist([], 'f')
3493 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3494 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3495 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3496 call assert_equal(1, l.nr)
3497 call assert_equal('Test4', l.title)
3498
3499 " Adding a quickfix list should remove all the lists following the current
3500 " list.
3501 Xexpr "" | Xexpr "" | Xexpr ""
3502 silent! 10Xolder
3503 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3504 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3505 call assert_equal(2, l.nr)
3506 call assert_equal('Test5', l.title)
3507
3508 " Add a quickfix list using '$' as the list number.
3509 let lastqf = g:Xgetlist({'nr':'$'}).nr
3510 silent! 99Xolder
3511 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3512 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3513 call assert_equal(lastqf + 1, l.nr)
3514 call assert_equal('Test6', l.title)
3515
3516 " Add a quickfix list using 'nr' set to one more than the quickfix
3517 " list size.
3518 let lastqf = g:Xgetlist({'nr':'$'}).nr
3519 silent! 99Xolder
3520 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3521 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3522 call assert_equal(lastqf + 1, l.nr)
3523 call assert_equal('Test7', l.title)
3524
3525 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3526 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3527 silent! 99Xolder
3528 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3529 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3530 call assert_equal(10, l.nr)
3531 call assert_equal('Test8', l.title)
3532
3533 " Add a quickfix list using 'nr' set to a value greater than 10
3534 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3535
3536 " Try adding a quickfix list with 'nr' set to a value greater than the
3537 " quickfix list size but less than 10.
3538 call g:Xsetlist([], 'f')
3539 Xexpr "" | Xexpr "" | Xexpr ""
3540 silent! 99Xolder
3541 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3542
3543 " Add a quickfix list using 'nr' set to a some string or list
3544 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3545endfunc
3546
3547func Test_add_qf()
3548 call XaddQf_tests('c')
3549 call XaddQf_tests('l')
3550endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003551
3552" Test for getting the quickfix list items from some text without modifying
3553" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003554func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003555 call s:setup_commands(a:cchar)
3556 call g:Xsetlist([], 'f')
3557
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003558 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003559 call assert_equal(2, len(l))
3560 call assert_equal(30, l[1].lnum)
3561
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003562 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3563 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3564 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3565 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003566
Bram Moolenaar36538222017-09-02 19:51:44 +02003567 " Parse text using a custom efm
3568 set efm&
3569 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3570 call assert_equal('Line30', l[0].text)
3571 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3572 call assert_equal('File3:30:Line30', l[0].text)
3573 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3574 call assert_equal({}, l)
3575 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3576 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3577
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003578 " Make sure that the quickfix stack is not modified
3579 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3580endfunc
3581
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003582func Test_get_list_from_lines()
3583 call XgetListFromLines('c')
3584 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003585endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003586
3587" Tests for the quickfix list id
3588func Xqfid_tests(cchar)
3589 call s:setup_commands(a:cchar)
3590
3591 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003592 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003593 Xexpr ''
3594 let start_id = g:Xgetlist({'id' : 0}).id
3595 Xexpr '' | Xexpr ''
3596 Xolder
3597 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3598 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3599 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003600 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003601 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003602 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3603 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003604
3605 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3606 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003607 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003608 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3609 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3610 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3611
3612 let qfid = g:Xgetlist({'id':0, 'nr':0})
3613 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003614 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003615endfunc
3616
3617func Test_qf_id()
3618 call Xqfid_tests('c')
3619 call Xqfid_tests('l')
3620endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003621
3622func Xqfjump_tests(cchar)
3623 call s:setup_commands(a:cchar)
3624
3625 call writefile(["Line1\tFoo", "Line2"], 'F1')
3626 call writefile(["Line1\tBar", "Line2"], 'F2')
3627 call writefile(["Line1\tBaz", "Line2"], 'F3')
3628
3629 call g:Xsetlist([], 'f')
3630
3631 " Tests for
3632 " Jumping to a line using a pattern
3633 " Jumping to a column greater than the last column in a line
3634 " Jumping to a line greater than the last line in the file
3635 let l = []
3636 for i in range(1, 7)
3637 call add(l, {})
3638 endfor
3639 let l[0].filename='F1'
3640 let l[0].pattern='Line1'
3641 let l[1].filename='F2'
3642 let l[1].pattern='Line1'
3643 let l[2].filename='F3'
3644 let l[2].pattern='Line1'
3645 let l[3].filename='F3'
3646 let l[3].lnum=1
3647 let l[3].col=9
3648 let l[3].vcol=1
3649 let l[4].filename='F3'
3650 let l[4].lnum=99
3651 let l[5].filename='F3'
3652 let l[5].lnum=1
3653 let l[5].col=99
3654 let l[5].vcol=1
3655 let l[6].filename='F3'
3656 let l[6].pattern='abcxyz'
3657
3658 call g:Xsetlist([], ' ', {'items' : l})
3659 Xopen | only
3660 2Xnext
3661 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003662 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003663 Xnext
3664 call assert_equal(7, col('.'))
3665 Xnext
3666 call assert_equal(2, line('.'))
3667 Xnext
3668 call assert_equal(9, col('.'))
3669 2
3670 Xnext
3671 call assert_equal(2, line('.'))
3672
3673 if a:cchar == 'l'
3674 " When jumping to a location list entry in the location list window and
3675 " no usable windows are available, then a new window should be opened.
3676 enew! | new | only
3677 call g:Xsetlist([], 'f')
3678 setlocal buftype=nofile
3679 new
3680 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']})
3681 Xopen
3682 let winid = win_getid()
3683 wincmd p
3684 close
3685 call win_gotoid(winid)
3686 Xnext
3687 call assert_equal(3, winnr('$'))
3688 call assert_equal(1, winnr())
3689 call assert_equal(2, line('.'))
3690
3691 " When jumping to an entry in the location list window and the window
3692 " associated with the location list is not present and a window containing
3693 " the file is already present, then that window should be used.
3694 close
3695 belowright new
3696 call g:Xsetlist([], 'f')
3697 edit F3
3698 call win_gotoid(winid)
3699 Xlast
3700 call assert_equal(3, winnr())
3701 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3702 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3703 endif
3704
3705 " Cleanup
3706 enew!
3707 new | only
3708
3709 call delete('F1')
3710 call delete('F2')
3711 call delete('F3')
3712endfunc
3713
3714func Test_qfjump()
3715 call Xqfjump_tests('c')
3716 call Xqfjump_tests('l')
3717endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003718
3719" Tests for the getqflist() and getloclist() functions when the list is not
3720" present or is empty
3721func Xgetlist_empty_tests(cchar)
3722 call s:setup_commands(a:cchar)
3723
3724 " Empty quickfix stack
3725 call g:Xsetlist([], 'f')
3726 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3727 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3728 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3729 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3730 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3731 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3732 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3733 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003734 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003735 if a:cchar == 'c'
3736 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003737 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003738 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3739 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003740 else
3741 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3742 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003743 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003744 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003745 \ g:Xgetlist({'all' : 0}))
3746 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003747
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003748 " Quickfix window with empty stack
3749 silent! Xopen
3750 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003751 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003752 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3753 Xclose
3754
Bram Moolenaara6d48492017-12-12 22:45:31 +01003755 " Empty quickfix list
3756 Xexpr ""
3757 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3758 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3759 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3760 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3761 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3762 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3763 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3764 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003765 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003766
3767 let qfid = g:Xgetlist({'id' : 0}).id
3768 call g:Xsetlist([], 'f')
3769
3770 " Non-existing quickfix identifier
3771 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3772 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3773 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3774 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3775 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3776 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3777 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3778 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003779 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003780 if a:cchar == 'c'
3781 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3782 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003783 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003784 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3785 else
3786 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3787 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003788 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3789 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003790 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3791 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003792
3793 " Non-existing quickfix list number
3794 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3795 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3796 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3797 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3798 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3799 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3800 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3801 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003802 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003803 if a:cchar == 'c'
3804 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3805 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003806 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3807 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003808 else
3809 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3810 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003811 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3812 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003813 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003814endfunc
3815
3816func Test_getqflist()
3817 call Xgetlist_empty_tests('c')
3818 call Xgetlist_empty_tests('l')
3819endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003820
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003821func Test_getqflist_invalid_nr()
3822 " The following commands used to crash Vim
3823 cexpr ""
3824 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3825
3826 " Cleanup
3827 call setqflist([], 'r')
3828endfunc
3829
Bram Moolenaarb254af32017-12-18 19:48:58 +01003830" Tests for the quickfix/location list changedtick
3831func Xqftick_tests(cchar)
3832 call s:setup_commands(a:cchar)
3833
3834 call g:Xsetlist([], 'f')
3835
3836 Xexpr "F1:10:Line10"
3837 let qfid = g:Xgetlist({'id' : 0}).id
3838 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3839 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3840 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3841 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3842 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3843 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3844 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3845 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3846 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3847
3848 enew!
3849 call append(0, ["F5:50:L50", "F6:60:L60"])
3850 Xaddbuffer
3851 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3852 enew!
3853
3854 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3855 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3856 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3857 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3858 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3859 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3860 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3861 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3862 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3863 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3864 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3865
3866 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3867 Xfile Xone
3868 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3869 Xaddfile Xone
3870 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3871
3872 " Test case for updating a non-current quickfix list
3873 call g:Xsetlist([], 'f')
3874 Xexpr "F1:1:L1"
3875 Xexpr "F2:2:L2"
3876 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3877 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3878 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3879
3880 call delete("Xone")
3881endfunc
3882
3883func Test_qf_tick()
3884 call Xqftick_tests('c')
3885 call Xqftick_tests('l')
3886endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003887
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003888" Test helpgrep with lang specifier
3889func Xtest_helpgrep_with_lang_specifier(cchar)
3890 call s:setup_commands(a:cchar)
3891 Xhelpgrep Vim@en
3892 call assert_equal('help', &filetype)
3893 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3894 new | only
3895endfunc
3896
3897func Test_helpgrep_with_lang_specifier()
3898 call Xtest_helpgrep_with_lang_specifier('c')
3899 call Xtest_helpgrep_with_lang_specifier('l')
3900endfunc
3901
Bram Moolenaar12237442017-12-19 12:38:52 +01003902" The following test used to crash Vim.
3903" Open the location list window and close the regular window associated with
3904" the location list. When the garbage collection runs now, it incorrectly
3905" marks the location list context as not in use and frees the context.
3906func Test_ll_window_ctx()
3907 call setloclist(0, [], 'f')
3908 call setloclist(0, [], 'a', {'context' : []})
3909 lopen | only
3910 call test_garbagecollect_now()
3911 echo getloclist(0, {'context' : 1}).context
3912 enew | only
3913endfunc
3914
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003915" The following test used to crash vim
3916func Test_lfile_crash()
3917 sp Xtest
3918 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003919 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003920 au! QuickFixCmdPre
3921endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003922
3923" The following test used to crash vim
3924func Test_lbuffer_crash()
3925 sv Xtest
3926 augroup QF_Test
3927 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003928 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003929 augroup END
3930 lbuffer
3931 augroup QF_Test
3932 au!
3933 augroup END
3934endfunc
3935
3936" The following test used to crash vim
3937func Test_lexpr_crash()
3938 augroup QF_Test
3939 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003940 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003941 augroup END
3942 lexpr ""
3943 augroup QF_Test
3944 au!
3945 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003946
Bram Moolenaar3c097222017-12-21 20:54:49 +01003947 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003948 augroup QF_Test
3949 au!
3950 au BufNew * call setloclist(0, [], 'f')
3951 augroup END
3952 lexpr 'x:1:x'
3953 augroup QF_Test
3954 au!
3955 augroup END
3956
3957 enew | only
3958 lexpr ''
3959 lopen
3960 augroup QF_Test
3961 au!
3962 au FileType * call setloclist(0, [], 'f')
3963 augroup END
3964 lexpr ''
3965 augroup QF_Test
3966 au!
3967 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003968endfunc
3969
3970" The following test used to crash Vim
3971func Test_lvimgrep_crash()
3972 sv Xtest
3973 augroup QF_Test
3974 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003975 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003976 augroup END
3977 lvimgrep quickfix test_quickfix.vim
3978 augroup QF_Test
3979 au!
3980 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003981
3982 new | only
3983 augroup QF_Test
3984 au!
3985 au BufEnter * call setloclist(0, [], 'r')
3986 augroup END
3987 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3988 augroup QF_Test
3989 au!
3990 augroup END
3991
Bram Moolenaar3c097222017-12-21 20:54:49 +01003992 enew | only
3993endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003994
Bram Moolenaar2573af32020-03-14 17:21:34 +01003995func Test_lvimgrep_crash2()
3996 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003997 call assert_fails('lvimgrep x x', 'E471:')
3998 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003999
4000 au! BufNewFile
4001endfunc
4002
Bram Moolenaarde046542017-12-26 13:53:11 +01004003" Test for the position of the quickfix and location list window
4004func Test_qfwin_pos()
4005 " Open two windows
4006 new | only
4007 new
4008 cexpr ['F1:10:L10']
4009 copen
4010 " Quickfix window should be the bottom most window
4011 call assert_equal(3, winnr())
4012 close
4013 " Open at the very top
4014 wincmd t
4015 topleft copen
4016 call assert_equal(1, winnr())
4017 close
4018 " open left of the current window
4019 wincmd t
4020 below new
4021 leftabove copen
4022 call assert_equal(2, winnr())
4023 close
4024 " open right of the current window
4025 rightbelow copen
4026 call assert_equal(3, winnr())
4027 close
4028endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004029
4030" Tests for quickfix/location lists changed by autocommands when
4031" :vimgrep/:lvimgrep commands are running.
4032func Test_vimgrep_autocmd()
4033 call setqflist([], 'f')
4034 call writefile(['stars'], 'Xtest1.txt')
4035 call writefile(['stars'], 'Xtest2.txt')
4036
4037 " Test 1:
4038 " When searching for a pattern using :vimgrep, if the quickfix list is
4039 " changed by an autocmd, the results should be added to the correct quickfix
4040 " list.
4041 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4042 silent vimgrep stars Xtest*.txt
4043 call assert_equal(1, getqflist({'nr' : 0}).nr)
4044 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4045 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4046 au! BufRead Xtest2.txt
4047
4048 " Test 2:
4049 " When searching for a pattern using :vimgrep, if the quickfix list is
4050 " freed, then a error should be given.
4051 silent! %bwipe!
4052 call setqflist([], 'f')
4053 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4054 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4055 au! BufRead Xtest2.txt
4056
4057 " Test 3:
4058 " When searching for a pattern using :lvimgrep, if the location list is
4059 " freed, then the command should error out.
4060 silent! %bwipe!
4061 let g:save_winid = win_getid()
4062 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4063 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4064 au! BufRead Xtest2.txt
4065
4066 call delete('Xtest1.txt')
4067 call delete('Xtest2.txt')
4068 call setqflist([], 'f')
4069endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004070
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004071" Test for an autocmd changing the current directory when running vimgrep
4072func Xvimgrep_autocmd_cd(cchar)
4073 call s:setup_commands(a:cchar)
4074
4075 %bwipe
4076 let save_cwd = getcwd()
4077
4078 augroup QF_Test
4079 au!
4080 autocmd BufRead * silent cd %:p:h
4081 augroup END
4082
4083 10Xvimgrep /vim/ Xdir/**
4084 let l = g:Xgetlist()
4085 call assert_equal('f1.txt', bufname(l[0].bufnr))
4086 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4087
4088 augroup QF_Test
4089 au!
4090 augroup END
4091
4092 exe 'cd ' . save_cwd
4093endfunc
4094
4095func Test_vimgrep_autocmd_cd()
4096 call mkdir('Xdir/a', 'p')
4097 call mkdir('Xdir/b', 'p')
4098 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4099 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4100 call Xvimgrep_autocmd_cd('c')
4101 call Xvimgrep_autocmd_cd('l')
4102 %bwipe
4103 call delete('Xdir', 'rf')
4104endfunc
4105
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004106" The following test used to crash Vim
4107func Test_lhelpgrep_autocmd()
4108 lhelpgrep quickfix
4109 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4110 lhelpgrep buffer
4111 call assert_equal('help', &filetype)
4112 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4113 lhelpgrep tabpage
4114 call assert_equal('help', &filetype)
4115 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4116 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004117
4118 new | only
4119 augroup QF_Test
4120 au!
4121 au BufEnter * call setqflist([], 'f')
4122 augroup END
4123 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004124 " run the test with a help window already open
4125 help
4126 wincmd w
4127 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004128 augroup QF_Test
4129 au! BufEnter
4130 augroup END
4131
4132 new | only
4133 augroup QF_Test
4134 au!
4135 au BufEnter * call setqflist([], 'r')
4136 augroup END
4137 call assert_fails('helpgrep quickfix', 'E925:')
4138 augroup QF_Test
4139 au! BufEnter
4140 augroup END
4141
4142 new | only
4143 augroup QF_Test
4144 au!
4145 au BufEnter * call setloclist(0, [], 'r')
4146 augroup END
4147 call assert_fails('lhelpgrep quickfix', 'E926:')
4148 augroup QF_Test
4149 au! BufEnter
4150 augroup END
4151
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004152 new | only
4153endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004154
4155" Test for shortening/simplifying the file name when opening the
4156" quickfix window or when displaying the quickfix list
4157func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004158 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004159 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004160 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004161 let fname = getcwd() . '/test_quickfix.vim'
4162 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4163 call assert_equal(fname, bufname('test_quickfix.vim'))
4164 " Opening the quickfix window should simplify the file path
4165 cwindow
4166 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4167 cclose
4168 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004169 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004170 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4171 call assert_equal(fname, bufname('test_quickfix.vim'))
4172 " Displaying the quickfix list should simplify the file path
4173 silent! clist
4174 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004175 " Add a few entries for the same file with different paths and check whether
4176 " the buffer name is shortened
4177 %bwipe
4178 call setqflist([], 'f')
4179 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4180 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4181 \ {'filename' : fname, 'lnum' : 30}], ' ')
4182 copen
4183 call assert_equal(['test_quickfix.vim|10| ',
4184 \ 'test_quickfix.vim|20| ',
4185 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4186 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004187endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004188
4189" Quickfix title tests
4190" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4191" Otherwise due to indentation, the title is set with spaces at the beginning
4192" of the command.
4193func Test_qftitle()
4194 call writefile(["F1:1:Line1"], 'Xerr')
4195
4196 " :cexpr
4197 exe "cexpr readfile('Xerr')"
4198 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4199
4200 " :cgetexpr
4201 exe "cgetexpr readfile('Xerr')"
4202 call assert_equal(":cgetexpr readfile('Xerr')",
4203 \ getqflist({'title' : 1}).title)
4204
4205 " :caddexpr
4206 call setqflist([], 'f')
4207 exe "caddexpr readfile('Xerr')"
4208 call assert_equal(":caddexpr readfile('Xerr')",
4209 \ getqflist({'title' : 1}).title)
4210
4211 " :cbuffer
4212 new Xerr
4213 exe "cbuffer"
4214 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4215
4216 " :cgetbuffer
4217 edit Xerr
4218 exe "cgetbuffer"
4219 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4220
4221 " :caddbuffer
4222 call setqflist([], 'f')
4223 edit Xerr
4224 exe "caddbuffer"
4225 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4226
4227 " :cfile
4228 exe "cfile Xerr"
4229 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4230
4231 " :cgetfile
4232 exe "cgetfile Xerr"
4233 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4234
4235 " :caddfile
4236 call setqflist([], 'f')
4237 exe "caddfile Xerr"
4238 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4239
4240 " :grep
4241 set grepprg=internal
4242 exe "grep F1 Xerr"
4243 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4244
4245 " :grepadd
4246 call setqflist([], 'f')
4247 exe "grepadd F1 Xerr"
4248 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4249 set grepprg&vim
4250
4251 " :vimgrep
4252 exe "vimgrep F1 Xerr"
4253 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4254
4255 " :vimgrepadd
4256 call setqflist([], 'f')
4257 exe "vimgrepadd F1 Xerr"
4258 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4259
4260 call setqflist(['F1:10:L10'], ' ')
4261 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4262
4263 call setqflist([], 'f')
4264 call setqflist(['F1:10:L10'], 'a')
4265 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4266
4267 call setqflist([], 'f')
4268 call setqflist(['F1:10:L10'], 'r')
4269 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4270
4271 close
4272 call delete('Xerr')
4273
4274 call setqflist([], ' ', {'title' : 'Errors'})
4275 copen
4276 call assert_equal('Errors', w:quickfix_title)
4277 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4278 call assert_equal('Errors', w:quickfix_title)
4279 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004280
4281 " Switching to another quickfix list in one tab page should update the
4282 " quickfix window title and statusline in all the other tab pages also
4283 call setqflist([], 'f')
4284 %bw!
4285 cgetexpr ['file_one:1:1: error in the first quickfix list']
4286 call setqflist([], 'a', {'title': 'first quickfix list'})
4287 cgetexpr ['file_two:2:1: error in the second quickfix list']
4288 call setqflist([], 'a', {'title': 'second quickfix list'})
4289 copen
4290 wincmd t
4291 tabnew two
4292 copen
4293 wincmd t
4294 colder
4295 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4296 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4297 call assert_equal(1, tabpagewinnr(1))
4298 call assert_equal(1, tabpagewinnr(2))
4299 tabnew
4300 call setqflist([], 'a', {'title': 'new quickfix title'})
4301 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4302 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4303 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004304endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004305
4306func Test_lbuffer_with_bwipe()
4307 new
4308 new
4309 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004310 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004311 augroup END
4312 lbuffer
4313 augroup nasty
4314 au!
4315 augroup END
4316endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004317
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004318" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4319" running
4320func Xexpr_acmd_freelist(cchar)
4321 call s:setup_commands(a:cchar)
4322
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004323 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004324 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004325 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004326 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004327 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004328 augroup nasty
4329 au!
4330 augroup END
4331endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004332
4333func Test_cexpr_acmd_freelist()
4334 call Xexpr_acmd_freelist('c')
4335 call Xexpr_acmd_freelist('l')
4336endfunc
4337
4338" Test for commands that create a new quickfix/location list and jump to the
4339" first error automatically.
4340func Xjumpto_first_error_test(cchar)
4341 call s:setup_commands(a:cchar)
4342
4343 call s:create_test_file('Xtestfile1')
4344 call s:create_test_file('Xtestfile2')
4345 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4346
4347 " Test for cexpr/lexpr
4348 enew
4349 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004350 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004351 call assert_equal(2, line('.'))
4352
4353 " Test for cfile/lfile
4354 enew
4355 call writefile(l, 'Xerr')
4356 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004357 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004358 call assert_equal(2, line('.'))
4359
4360 " Test for cbuffer/lbuffer
4361 edit Xerr
4362 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004363 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004364 call assert_equal(2, line('.'))
4365
4366 call delete('Xerr')
4367 call delete('Xtestfile1')
4368 call delete('Xtestfile2')
4369endfunc
4370
4371func Test_jumpto_first_error()
4372 call Xjumpto_first_error_test('c')
4373 call Xjumpto_first_error_test('l')
4374endfunc
4375
4376" Test for a quickfix autocmd changing the quickfix/location list before
4377" jumping to the first error in the new list.
4378func Xautocmd_changelist(cchar)
4379 call s:setup_commands(a:cchar)
4380
4381 " Test for cfile/lfile
4382 call s:create_test_file('Xtestfile1')
4383 call s:create_test_file('Xtestfile2')
4384 Xexpr 'Xtestfile1:2:Line2'
4385 autocmd QuickFixCmdPost * Xolder
4386 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4387 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004388 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004389 call assert_equal(4, line('.'))
4390 autocmd! QuickFixCmdPost
4391
4392 " Test for cbuffer/lbuffer
4393 call g:Xsetlist([], 'f')
4394 Xexpr 'Xtestfile1:2:Line2'
4395 autocmd QuickFixCmdPost * Xolder
4396 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4397 edit Xerr
4398 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004399 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004400 call assert_equal(4, line('.'))
4401 autocmd! QuickFixCmdPost
4402
4403 " Test for cexpr/lexpr
4404 call g:Xsetlist([], 'f')
4405 Xexpr 'Xtestfile1:2:Line2'
4406 autocmd QuickFixCmdPost * Xolder
4407 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004408 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004409 call assert_equal(4, line('.'))
4410 autocmd! QuickFixCmdPost
4411
Bram Moolenaar851332e2018-07-03 19:16:00 +02004412 " The grepprg may not be set on non-Unix systems
4413 if has('unix')
4414 " Test for grep/lgrep
4415 call g:Xsetlist([], 'f')
4416 Xexpr 'Xtestfile1:2:Line2'
4417 autocmd QuickFixCmdPost * Xolder
4418 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004419 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004420 call assert_equal(5, line('.'))
4421 autocmd! QuickFixCmdPost
4422 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004423
4424 " Test for vimgrep/lvimgrep
4425 call g:Xsetlist([], 'f')
4426 Xexpr 'Xtestfile1:2:Line2'
4427 autocmd QuickFixCmdPost * Xolder
4428 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004429 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004430 call assert_equal(5, line('.'))
4431 autocmd! QuickFixCmdPost
4432
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004433 " Test for autocommands clearing the quickfix list before jumping to the
4434 " first error. This should not result in an error
4435 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4436 let v:errmsg = ''
4437 " Test for cfile/lfile
4438 Xfile Xerr
4439 call assert_true(v:errmsg !~# 'E42:')
4440 " Test for cbuffer/lbuffer
4441 edit Xerr
4442 Xbuffer
4443 call assert_true(v:errmsg !~# 'E42:')
4444 " Test for cexpr/lexpr
4445 Xexpr 'Xtestfile2:4:Line4'
4446 call assert_true(v:errmsg !~# 'E42:')
4447 " Test for grep/lgrep
4448 " The grepprg may not be set on non-Unix systems
4449 if has('unix')
4450 silent Xgrep Line5 Xtestfile2
4451 call assert_true(v:errmsg !~# 'E42:')
4452 endif
4453 " Test for vimgrep/lvimgrep
4454 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4455 autocmd! QuickFixCmdPost
4456
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004457 call delete('Xerr')
4458 call delete('Xtestfile1')
4459 call delete('Xtestfile2')
4460endfunc
4461
4462func Test_autocmd_changelist()
4463 call Xautocmd_changelist('c')
4464 call Xautocmd_changelist('l')
4465endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004466
4467" Tests for the ':filter /pat/ clist' command
4468func Test_filter_clist()
4469 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4470 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4471 \ split(execute('filter /Line 15/ clist'), "\n"))
4472 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4473 \ split(execute('filter /Xfile1/ clist'), "\n"))
4474 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4475
4476 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4477 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4478 call assert_equal([' 2 pqr:pat2: '],
4479 \ split(execute('filter /pqr/ clist'), "\n"))
4480 call assert_equal([' 1 abc:pat1: '],
4481 \ split(execute('filter /pat1/ clist'), "\n"))
4482endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004483
4484" Tests for the "CTRL-W <CR>" command.
4485func Xview_result_split_tests(cchar)
4486 call s:setup_commands(a:cchar)
4487
4488 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4489 call g:Xsetlist([])
4490 Xopen
4491 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004492 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004493 call assert_equal(l:win_count, winnr('$'))
4494 Xclose
4495endfunc
4496
4497func Test_view_result_split()
4498 call Xview_result_split_tests('c')
4499 call Xview_result_split_tests('l')
4500endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004501
4502" Test that :cc sets curswant
4503func Test_curswant()
4504 helpgrep quickfix
4505 normal! llll
4506 1cc
4507 call assert_equal(getcurpos()[4], virtcol('.'))
4508 cclose | helpclose
4509endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004510
4511" Test for opening a file from the quickfix window using CTRL-W <Enter>
4512" doesn't leave an empty buffer around.
4513func Test_splitview()
4514 call s:create_test_file('Xtestfile1')
4515 call s:create_test_file('Xtestfile2')
4516 new | only
4517 let last_bufnr = bufnr('Test_sv_1', 1)
4518 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4519 cgetexpr l
4520 copen
4521 let numbufs = len(getbufinfo())
4522 exe "normal \<C-W>\<CR>"
4523 copen
4524 exe "normal j\<C-W>\<CR>"
4525 " Make sure new empty buffers are not created
4526 call assert_equal(numbufs, len(getbufinfo()))
4527 " Creating a new buffer should use the next available buffer number
4528 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4529 bwipe Test_sv_1
4530 bwipe Test_sv_2
4531 new | only
4532
4533 " When split opening files from location list window, make sure that two
4534 " windows doesn't refer to the same location list
4535 lgetexpr l
4536 let locid = getloclist(0, {'id' : 0}).id
4537 lopen
4538 exe "normal \<C-W>\<CR>"
4539 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4540 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4541 new | only
4542
4543 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004544 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004545 lhelpgrep window
4546 let locid = getloclist(0, {'id' : 0}).id
4547 lwindow
4548 exe "normal j\<C-W>\<CR>"
4549 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4550 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4551 new | only
4552
Bram Moolenaar406cd902020-02-18 21:54:41 +01004553 " Using :split or :vsplit from a quickfix window should behave like a :new
4554 " or a :vnew command
4555 copen
4556 split
4557 call assert_equal(3, winnr('$'))
4558 let l = getwininfo()
4559 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4560 close
4561 copen
4562 vsplit
4563 let l = getwininfo()
4564 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4565 new | only
4566
Bram Moolenaarb2443732018-11-11 22:50:27 +01004567 call delete('Xtestfile1')
4568 call delete('Xtestfile2')
4569endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004570
4571" Test for parsing entries using visual screen column
4572func Test_viscol()
4573 enew
4574 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4575 edit Xfile1
4576
4577 " Use byte offset for column number
4578 set efm&
4579 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4580 call assert_equal([5, 8], [col('.'), virtcol('.')])
4581 cnext
4582 call assert_equal([9, 12], [col('.'), virtcol('.')])
4583 cnext
4584 call assert_equal([14, 20], [col('.'), virtcol('.')])
4585
4586 " Use screen column offset for column number
4587 set efm=%f:%l:%v:%m
4588 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4589 call assert_equal([5, 8], [col('.'), virtcol('.')])
4590 cnext
4591 call assert_equal([9, 12], [col('.'), virtcol('.')])
4592 cnext
4593 call assert_equal([14, 20], [col('.'), virtcol('.')])
4594 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4595 call assert_equal([5, 8], [col('.'), virtcol('.')])
4596 cnext
4597 call assert_equal([10, 16], [col('.'), virtcol('.')])
4598 cnext
4599 call assert_equal([14, 20], [col('.'), virtcol('.')])
4600
4601 enew
4602 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4603
4604 " Use byte offset for column number
4605 set efm&
4606 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4607 call assert_equal([8, 10], [col('.'), virtcol('.')])
4608 cnext
4609 call assert_equal([11, 17], [col('.'), virtcol('.')])
4610 cnext
4611 call assert_equal([16, 25], [col('.'), virtcol('.')])
4612
4613 " Use screen column offset for column number
4614 set efm=%f:%l:%v:%m
4615 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4616 call assert_equal([8, 10], [col('.'), virtcol('.')])
4617 cnext
4618 call assert_equal([11, 17], [col('.'), virtcol('.')])
4619 cnext
4620 call assert_equal([16, 25], [col('.'), virtcol('.')])
4621
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004622 " Use screen column number with a multi-line error message
4623 enew
4624 call writefile(["à test"], 'Xfile1')
4625 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4626 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4627 call assert_equal('Xfile1', @%)
4628 call assert_equal([0, 1, 4, 0], getpos('.'))
4629
4630 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4631 " does not break this
4632 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4633 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4634 call assert_equal('Xfile1', @%)
4635 call assert_equal([0, 1, 3, 0], getpos('.'))
4636
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004637 enew | only
4638 set efm&
4639 call delete('Xfile1')
4640endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004641
4642" Test for the quickfix window buffer
4643func Xqfbuf_test(cchar)
4644 call s:setup_commands(a:cchar)
4645
4646 " Quickfix buffer should be reused across closing and opening a quickfix
4647 " window
4648 Xexpr "F1:10:Line10"
4649 Xopen
4650 let qfbnum = bufnr('')
4651 Xclose
4652 " Even after the quickfix window is closed, the buffer should be loaded
4653 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004654 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004655 Xopen
4656 " Buffer should be reused when opening the window again
4657 call assert_equal(qfbnum, bufnr(''))
4658 Xclose
4659
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004660 " When quickfix buffer is wiped out, getqflist() should return 0
4661 %bw!
4662 Xexpr ""
4663 Xopen
4664 bw!
4665 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4666
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004667 if a:cchar == 'l'
4668 %bwipe
4669 " For a location list, when both the file window and the location list
4670 " window for the list are closed, then the buffer should be freed.
4671 new | only
4672 lexpr "F1:10:Line10"
4673 let wid = win_getid()
4674 lopen
4675 let qfbnum = bufnr('')
4676 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4677 close
4678 " When the location list window is closed, the buffer name should not
4679 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004680 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004681 call assert_true(bufloaded(qfbnum))
4682
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004683 " After deleting a location list buffer using ":bdelete", opening the
4684 " location list window should mark the buffer as a location list buffer.
4685 exe "bdelete " . qfbnum
4686 lopen
4687 call assert_equal("quickfix", &buftype)
4688 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4689 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4690 call assert_false(&swapfile)
4691 lclose
4692
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004693 " When the location list is cleared for the window, the buffer should be
4694 " removed
4695 call setloclist(0, [], 'f')
4696 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004697 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004698
4699 " When the location list is freed with the location list window open, the
4700 " location list buffer should not be lost. It should be reused when the
4701 " location list is again populated.
4702 lexpr "F1:10:Line10"
4703 lopen
4704 let wid = win_getid()
4705 let qfbnum = bufnr('')
4706 wincmd p
4707 call setloclist(0, [], 'f')
4708 lexpr "F1:10:Line10"
4709 lopen
4710 call assert_equal(wid, win_getid())
4711 call assert_equal(qfbnum, bufnr(''))
4712 lclose
4713
4714 " When the window with the location list is closed, the buffer should be
4715 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004716 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004717 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004718 endif
4719endfunc
4720
4721func Test_qfbuf()
4722 call Xqfbuf_test('c')
4723 call Xqfbuf_test('l')
4724endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004725
4726" If there is an autocmd to use only one window, then opening the location
4727" list window used to crash Vim.
4728func Test_winonly_autocmd()
4729 call s:create_test_file('Xtest1')
4730 " Autocmd to show only one Vim window at a time
4731 autocmd WinEnter * only
4732 new
4733 " Load the location list
4734 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4735 let loclistid = getloclist(0, {'id' : 0}).id
4736 " Open the location list window. Only this window will be shown and the file
4737 " window is closed.
4738 lopen
4739 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4740 " Jump to an entry in the location list and make sure that the cursor is
4741 " positioned correctly.
4742 ll 3
4743 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004744 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004745 call assert_equal(15, line('.'))
4746 " Cleanup
4747 autocmd! WinEnter
4748 new | only
4749 call delete('Xtest1')
4750endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004751
4752" Test to make sure that an empty quickfix buffer is not reused for loading
4753" a normal buffer.
4754func Test_empty_qfbuf()
4755 enew | only
4756 call writefile(["Test"], 'Xfile1')
4757 call setqflist([], 'f')
4758 copen | only
4759 let qfbuf = bufnr('')
4760 edit Xfile1
4761 call assert_notequal(qfbuf, bufnr(''))
4762 enew
4763 call delete('Xfile1')
4764endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004765
4766" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004767" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004768func Xtest_below(cchar)
4769 call s:setup_commands(a:cchar)
4770
4771 " No quickfix/location list
4772 call assert_fails('Xbelow', 'E42:')
4773 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004774 call assert_fails('Xbefore', 'E42:')
4775 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004776
4777 " Empty quickfix/location list
4778 call g:Xsetlist([])
4779 call assert_fails('Xbelow', 'E42:')
4780 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004781 call assert_fails('Xbefore', 'E42:')
4782 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004783
4784 call s:create_test_file('X1')
4785 call s:create_test_file('X2')
4786 call s:create_test_file('X3')
4787 call s:create_test_file('X4')
4788
4789 " Invalid entries
4790 edit X1
4791 call g:Xsetlist(["E1", "E2"])
4792 call assert_fails('Xbelow', 'E42:')
4793 call assert_fails('Xabove', 'E42:')
4794 call assert_fails('3Xbelow', 'E42:')
4795 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004796 call assert_fails('Xbefore', 'E42:')
4797 call assert_fails('Xafter', 'E42:')
4798 call assert_fails('3Xbefore', 'E42:')
4799 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004800
4801 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004802 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 +02004803 edit +7 X2
4804 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004805 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004806 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004807 normal 7G
4808 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004809 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004810 call assert_fails('Xbefore', 'E553:')
4811
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004812 normal 2j
4813 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004814 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004815 normal 7G
4816 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004817 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004818
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004819 " Last error in this file
4820 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004821 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004822 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004823 normal gg
4824 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004825 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004826 call assert_fails('Xafter', 'E553:')
4827
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004828 " First error in this file
4829 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004830 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004831 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004832 normal G
4833 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004834 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004835 call assert_fails('Xbefore', 'E553:')
4836
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004837 normal gg
4838 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004839 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004840 normal gg
4841 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004842 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004843
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004844 normal G
4845 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004846 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004847 normal G
4848 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004849 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004850
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004851 edit X4
4852 call assert_fails('Xabove', 'E42:')
4853 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004854 call assert_fails('Xbefore', 'E42:')
4855 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004856 if a:cchar == 'l'
4857 " If a buffer has location list entries from some other window but not
4858 " from the current window, then the commands should fail.
4859 edit X1 | split | call setloclist(0, [], 'f')
4860 call assert_fails('Xabove', 'E776:')
4861 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004862 call assert_fails('Xbefore', 'E776:')
4863 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004864 close
4865 endif
4866
4867 " Test for lines with multiple quickfix entries
4868 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4869 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4870 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4871 edit +1 X2
4872 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004873 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004874 normal 1G
4875 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004876 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004877
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004878 normal gg
4879 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004880 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004881 normal gg
4882 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004883 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004884
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004885 normal G
4886 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004887 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004888 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004889 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004890 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004891
4892 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004893 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004894 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004895 normal G
4896 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004897 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004898
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004899 normal 10G
4900 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004901 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004902 normal 10G$
4903 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004904 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004905
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004906 normal 10G
4907 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004908 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004909 normal 9G
4910 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004911 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004912
4913 " Invalid range
4914 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004915 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004916 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004917 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004918 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004919 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004920 endif
4921
4922 call delete('X1')
4923 call delete('X2')
4924 call delete('X3')
4925 call delete('X4')
4926endfunc
4927
4928func Test_cbelow()
4929 call Xtest_below('c')
4930 call Xtest_below('l')
4931endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004932
4933func Test_quickfix_count()
4934 let commands = [
4935 \ 'cNext',
4936 \ 'cNfile',
4937 \ 'cabove',
4938 \ 'cbelow',
4939 \ 'cfirst',
4940 \ 'clast',
4941 \ 'cnewer',
4942 \ 'cnext',
4943 \ 'cnfile',
4944 \ 'colder',
4945 \ 'cprevious',
4946 \ 'crewind',
4947 \
4948 \ 'lNext',
4949 \ 'lNfile',
4950 \ 'labove',
4951 \ 'lbelow',
4952 \ 'lfirst',
4953 \ 'llast',
4954 \ 'lnewer',
4955 \ 'lnext',
4956 \ 'lnfile',
4957 \ 'lolder',
4958 \ 'lprevious',
4959 \ 'lrewind',
4960 \ ]
4961 for cmd in commands
4962 call assert_fails('-1' .. cmd, 'E16:')
4963 call assert_fails('.' .. cmd, 'E16:')
4964 call assert_fails('%' .. cmd, 'E16:')
4965 call assert_fails('$' .. cmd, 'E16:')
4966 endfor
4967endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004968
4969" Test for aborting quickfix commands using QuickFixCmdPre
4970func Xtest_qfcmd_abort(cchar)
4971 call s:setup_commands(a:cchar)
4972
4973 call g:Xsetlist([], 'f')
4974
4975 " cexpr/lexpr
4976 let e = ''
4977 try
4978 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4979 catch /.*/
4980 let e = v:exception
4981 endtry
4982 call assert_equal('AbortCmd', e)
4983 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4984
4985 " cfile/lfile
4986 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4987 let e = ''
4988 try
4989 Xfile Xfile1
4990 catch /.*/
4991 let e = v:exception
4992 endtry
4993 call assert_equal('AbortCmd', e)
4994 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4995 call delete('Xfile1')
4996
4997 " cgetbuffer/lgetbuffer
4998 enew!
4999 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5000 let e = ''
5001 try
5002 Xgetbuffer
5003 catch /.*/
5004 let e = v:exception
5005 endtry
5006 call assert_equal('AbortCmd', e)
5007 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5008 enew!
5009
5010 " vimgrep/lvimgrep
5011 let e = ''
5012 try
5013 Xvimgrep /func/ test_quickfix.vim
5014 catch /.*/
5015 let e = v:exception
5016 endtry
5017 call assert_equal('AbortCmd', e)
5018 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5019
5020 " helpgrep/lhelpgrep
5021 let e = ''
5022 try
5023 Xhelpgrep quickfix
5024 catch /.*/
5025 let e = v:exception
5026 endtry
5027 call assert_equal('AbortCmd', e)
5028 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5029
5030 " grep/lgrep
5031 if has('unix')
5032 let e = ''
5033 try
5034 silent Xgrep func test_quickfix.vim
5035 catch /.*/
5036 let e = v:exception
5037 endtry
5038 call assert_equal('AbortCmd', e)
5039 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5040 endif
5041endfunc
5042
5043func Test_qfcmd_abort()
5044 augroup QF_Test
5045 au!
5046 autocmd QuickFixCmdPre * throw "AbortCmd"
5047 augroup END
5048
5049 call Xtest_qfcmd_abort('c')
5050 call Xtest_qfcmd_abort('l')
5051
5052 augroup QF_Test
5053 au!
5054 augroup END
5055endfunc
5056
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005057" Test for using a file in one of the parent directories.
5058func Test_search_in_dirstack()
5059 call mkdir('Xtestdir/a/b/c', 'p')
5060 let save_cwd = getcwd()
5061 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5062 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5063 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5064 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5065
5066 let lines = "Entering dir Xtestdir\n" .
5067 \ "Entering dir a\n" .
5068 \ "Entering dir b\n" .
5069 \ "Xfile2:2:X2_L2\n" .
5070 \ "Leaving dir a\n" .
5071 \ "Xfile1:2:X1_L2\n" .
5072 \ "Xfile3:1:X3_L1\n" .
5073 \ "Entering dir c\n" .
5074 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005075 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005076 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005077 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005078 call assert_equal(11, getqflist({'size' : 0}).size)
5079 call assert_equal(4, getqflist({'idx' : 0}).idx)
5080 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005081 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005082 cnext
5083 call assert_equal(6, getqflist({'idx' : 0}).idx)
5084 call assert_equal('X1_L2', getline('.'))
5085 cnext
5086 call assert_equal(7, getqflist({'idx' : 0}).idx)
5087 call assert_equal(1, line('$'))
5088 call assert_equal('', getline(1))
5089 cnext
5090 call assert_equal(9, getqflist({'idx' : 0}).idx)
5091 call assert_equal(1, line('$'))
5092 call assert_equal('', getline(1))
5093
5094 set efm&
5095 exe 'cd ' . save_cwd
5096 call delete('Xtestdir', 'rf')
5097endfunc
5098
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005099" Test for :cquit
5100func Test_cquit()
5101 " Exit Vim with a non-zero value
5102 if RunVim([], ["cquit 7"], '')
5103 call assert_equal(7, v:shell_error)
5104 endif
5105
5106 if RunVim([], ["50cquit"], '')
5107 call assert_equal(50, v:shell_error)
5108 endif
5109
5110 " Exit Vim with default value
5111 if RunVim([], ["cquit"], '')
5112 call assert_equal(1, v:shell_error)
5113 endif
5114
5115 " Exit Vim with zero value
5116 if RunVim([], ["cquit 0"], '')
5117 call assert_equal(0, v:shell_error)
5118 endif
5119
5120 " Exit Vim with negative value
5121 call assert_fails('-3cquit', 'E16:')
5122endfunc
5123
Bram Moolenaar858ba062020-05-31 23:11:59 +02005124" Test for getting a specific item from a quickfix list
5125func Xtest_getqflist_by_idx(cchar)
5126 call s:setup_commands(a:cchar)
5127 " Empty list
5128 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5129 Xexpr ['F1:10:L10', 'F1:20:L20']
5130 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5131 call assert_equal(bufnr('F1'), l[0].bufnr)
5132 call assert_equal(20, l[0].lnum)
5133 call assert_equal('L20', l[0].text)
5134 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5135 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5136 %bwipe!
5137endfunc
5138
5139func Test_getqflist_by_idx()
5140 call Xtest_getqflist_by_idx('c')
5141 call Xtest_getqflist_by_idx('l')
5142endfunc
5143
5144" Test for the 'quickfixtextfunc' setting
5145func Tqfexpr(info)
5146 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005147 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005148 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005149 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005150 endif
5151
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005152 let l = []
5153 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5154 let e = qfl[idx]
5155 let s = ''
5156 if e.bufnr != 0
5157 let bname = bufname(e.bufnr)
5158 let s ..= fnamemodify(bname, ':.')
5159 endif
5160 let s ..= '-'
5161 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5162 let s ..= e.text
5163 call add(l, s)
5164 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005165
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005166 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005167endfunc
5168
5169func Xtest_qftextfunc(cchar)
5170 call s:setup_commands(a:cchar)
5171
5172 set efm=%f:%l:%c:%m
5173 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005174 call assert_equal('Tqfexpr', &quickfixtextfunc)
5175 call assert_equal('',
5176 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005177 call g:Xsetlist([
5178 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5179 \ 'end_col': 7, 'text': 'green'},
5180 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5181 \ 'end_col': 8, 'text': 'blue'},
5182 \ ])
5183
Bram Moolenaar858ba062020-05-31 23:11:59 +02005184 Xwindow
5185 call assert_equal('F1-L10C2-green', getline(1))
5186 call assert_equal('F1-L20C4-blue', getline(2))
5187 Xclose
5188 set quickfixtextfunc&vim
5189 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005190 call assert_equal('F1|10 col 2-7| green', getline(1))
5191 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005192 Xclose
5193 set efm&
5194 set quickfixtextfunc&
5195
5196 " Test for per list 'quickfixtextfunc' setting
5197 func PerQfText(info)
5198 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005199 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005200 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005201 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005202 endif
5203 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005204 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005205 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005206 let l = []
5207 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5208 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5209 endfor
5210 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005211 endfunc
5212 set quickfixtextfunc=Tqfexpr
5213 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5214 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5215 Xwindow
5216 call assert_equal('Line 10, Col 2', getline(1))
5217 call assert_equal('Line 20, Col 4', getline(2))
5218 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005219 call assert_equal(function('PerQfText'),
5220 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005221 " Add entries to the list when the quickfix buffer is hidden
5222 Xaddexpr ['F1:30:6:red']
5223 Xwindow
5224 call assert_equal('Line 30, Col 6', getline(3))
5225 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005226 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005227 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005228 set quickfixtextfunc&
5229 delfunc PerQfText
5230
5231 " Non-existing function
5232 set quickfixtextfunc=Tabc
5233 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5234 call assert_fails("Xwindow", 'E117:')
5235 Xclose
5236 set quickfixtextfunc&
5237
5238 " set option to a non-function
5239 set quickfixtextfunc=[10,\ 20]
5240 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5241 call assert_fails("Xwindow", 'E117:')
5242 Xclose
5243 set quickfixtextfunc&
5244
5245 " set option to a function with different set of arguments
5246 func Xqftext(a, b, c)
5247 return a:a .. a:b .. a:c
5248 endfunc
5249 set quickfixtextfunc=Xqftext
5250 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5251 call assert_fails("Xwindow", 'E119:')
5252 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005253
5254 " set option to a function that returns a list with non-strings
5255 func Xqftext2(d)
5256 return ['one', [], 'two']
5257 endfunc
5258 set quickfixtextfunc=Xqftext2
5259 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5260 \ 'E730:')
5261 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005262 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5263 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005264 Xclose
5265
Bram Moolenaar858ba062020-05-31 23:11:59 +02005266 set quickfixtextfunc&
5267 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005268 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005269
5270 " set the global option to a lambda function
5271 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5272 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5273 Xwindow
5274 call assert_equal(['green', 'blue'], getline(1, '$'))
5275 Xclose
5276 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)
5277 set quickfixtextfunc&
5278
5279 " use a lambda function that returns an empty list
5280 set quickfixtextfunc={d\ ->\ []}
5281 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5282 Xwindow
5283 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5284 \ getline(1, '$'))
5285 Xclose
5286 set quickfixtextfunc&
5287
5288 " use a lambda function that returns a list with empty strings
5289 set quickfixtextfunc={d\ ->\ ['',\ '']}
5290 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5291 Xwindow
5292 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5293 \ getline(1, '$'))
5294 Xclose
5295 set quickfixtextfunc&
5296
5297 " set the per-quickfix list text function to a lambda function
5298 call g:Xsetlist([], ' ',
5299 \ {'quickfixtextfunc' :
5300 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5301 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5302 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5303 Xwindow
5304 call assert_equal('Line 10, Col 2', getline(1))
5305 call assert_equal('Line 20, Col 4', getline(2))
5306 Xclose
5307 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5308 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005309endfunc
5310
5311func Test_qftextfunc()
5312 call Xtest_qftextfunc('c')
5313 call Xtest_qftextfunc('l')
5314endfunc
5315
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005316func Test_qftextfunc_callback()
5317 let lines =<< trim END
5318 set efm=%f:%l:%c:%m
5319
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005320 #" Test for using a function name
5321 LET &qftf = 'g:Tqfexpr'
5322 cexpr "F0:0:0:L0"
5323 copen
5324 call assert_equal('F0-L0C0-L0', getline(1))
5325 cclose
5326
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005327 #" Test for using a function()
5328 set qftf=function('g:Tqfexpr')
5329 cexpr "F1:1:1:L1"
5330 copen
5331 call assert_equal('F1-L1C1-L1', getline(1))
5332 cclose
5333
5334 #" Using a funcref variable to set 'quickfixtextfunc'
5335 VAR Fn = function('g:Tqfexpr')
5336 LET &qftf = Fn
5337 cexpr "F2:2:2:L2"
5338 copen
5339 call assert_equal('F2-L2C2-L2', getline(1))
5340 cclose
5341
5342 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5343 LET Fn = function('g:Tqfexpr')
5344 LET &qftf = string(Fn)
5345 cexpr "F3:3:3:L3"
5346 copen
5347 call assert_equal('F3-L3C3-L3', getline(1))
5348 cclose
5349
5350 #" Test for using a funcref()
5351 set qftf=funcref('g:Tqfexpr')
5352 cexpr "F4:4:4:L4"
5353 copen
5354 call assert_equal('F4-L4C4-L4', getline(1))
5355 cclose
5356
5357 #" Using a funcref variable to set 'quickfixtextfunc'
5358 LET Fn = funcref('g:Tqfexpr')
5359 LET &qftf = Fn
5360 cexpr "F5:5:5:L5"
5361 copen
5362 call assert_equal('F5-L5C5-L5', getline(1))
5363 cclose
5364
5365 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5366 LET Fn = funcref('g:Tqfexpr')
5367 LET &qftf = string(Fn)
5368 cexpr "F5:5:5:L5"
5369 copen
5370 call assert_equal('F5-L5C5-L5', getline(1))
5371 cclose
5372
5373 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005374 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005375 LET optval = substitute(optval, ' ', '\\ ', 'g')
5376 exe "set qftf=" .. optval
5377 cexpr "F6:6:6:L6"
5378 copen
5379 call assert_equal('F6-L6C6-L6', getline(1))
5380 cclose
5381
5382 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005383 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005384 cexpr "F7:7:7:L7"
5385 copen
5386 call assert_equal('F7-L7C7-L7', getline(1))
5387 cclose
5388
5389 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005390 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005391 cexpr "F8:8:8:L8"
5392 copen
5393 call assert_equal('F8-L8C8-L8', getline(1))
5394 cclose
5395
5396 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005397 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005398 LET &qftf = Lambda
5399 cexpr "F9:9:9:L9"
5400 copen
5401 call assert_equal('F9-L9C9-L9', getline(1))
5402 cclose
5403
5404 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005405 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005406 LET &qftf = string(Lambda)
5407 cexpr "F9:9:9:L9"
5408 copen
5409 call assert_equal('F9-L9C9-L9', getline(1))
5410 cclose
5411 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005412 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005413
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005414 " Test for using a script-local function name
5415 func s:TqfFunc2(info)
5416 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5417 return ''
5418 endfunc
5419 let g:TqfFunc2Args = []
5420 set quickfixtextfunc=s:TqfFunc2
5421 cexpr "F10:10:10:L10"
5422 cclose
5423 call assert_equal([1, 1], g:TqfFunc2Args)
5424
5425 let &quickfixtextfunc = 's:TqfFunc2'
5426 cexpr "F11:11:11:L11"
5427 cclose
5428 call assert_equal([1, 1], g:TqfFunc2Args)
5429 delfunc s:TqfFunc2
5430
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005431 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5432 func SetQftfFunc()
5433 let params = {'qftf': function('g:DictQftfFunc')}
5434 let &quickfixtextfunc = params.qftf
5435 endfunc
5436 func g:DictQftfFunc(_) dict
5437 endfunc
5438 call SetQftfFunc()
5439 new
5440 call SetQftfFunc()
5441 bw
5442 call test_garbagecollect_now()
5443 new
5444 set qftf=
5445 wincmd w
5446 set qftf=
5447 :%bw!
5448
5449 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5450 " to cause a crash.
5451 let &qftf = ''
5452 func SetLocalQftfFunc()
5453 let params = {'qftf': function('g:DictQftfFunc')}
5454 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5455 endfunc
5456 call SetLocalQftfFunc()
5457 call test_garbagecollect_now()
5458 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5459 delfunc g:DictQftfFunc
5460 delfunc SetQftfFunc
5461 delfunc SetLocalQftfFunc
5462 set efm&
5463endfunc
5464
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005465" Test for updating a location list for some other window and check that
5466" 'qftextfunc' uses the correct location list.
5467func Test_qftextfunc_other_loclist()
5468 %bw!
5469 call setloclist(0, [], 'f')
5470
5471 " create a window and a location list for it and open the location list
5472 " window
5473 lexpr ['F1:10:12:one', 'F1:20:14:two']
5474 let w1_id = win_getid()
5475 call setloclist(0, [], ' ',
5476 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5477 \ 'quickfixtextfunc':
5478 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5479 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5480 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5481 lwindow
5482 let w2_id = win_getid()
5483
5484 " create another window and a location list for it and open the location
5485 " list window
5486 topleft new
5487 let w3_id = win_getid()
5488 call setloclist(0, [], ' ',
5489 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5490 \ 'quickfixtextfunc':
5491 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5492 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5493 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5494 lwindow
5495 let w4_id = win_getid()
5496
5497 topleft new
5498 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5499 let w5_id = win_getid()
5500
5501 " change the location list for some other window
5502 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5503 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5504 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5505 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5506 \ getbufline(winbufnr(w2_id), 1, '$'))
5507 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5508 \ getbufline(winbufnr(w4_id), 1, '$'))
5509 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5510 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5511 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5512 \ getbufline(winbufnr(w2_id), 1, '$'))
5513 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5514 \ getbufline(winbufnr(w4_id), 1, '$'))
5515
5516 call win_gotoid(w5_id)
5517 lwindow
5518 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5519 \ getline(1, '$'))
5520 %bw!
5521endfunc
5522
Bram Moolenaarec98e932020-06-08 19:35:59 +02005523" Running :lhelpgrep command more than once in a help window, doesn't jump to
5524" the help topic
5525func Test_lhelpgrep_from_help_window()
5526 call mkdir('Xtestdir/doc', 'p')
5527 call writefile(['window'], 'Xtestdir/doc/a.txt')
5528 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5529 let save_rtp = &rtp
5530 let &rtp = 'Xtestdir'
5531 lhelpgrep window
5532 lhelpgrep buffer
5533 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5534 lhelpgrep window
5535 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5536 let &rtp = save_rtp
5537 call delete('Xtestdir', 'rf')
5538 new | only!
5539endfunc
5540
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005541" Test for the crash fixed by 7.3.715
5542func Test_setloclist_crash()
5543 %bw!
5544 let g:BufNum = bufnr()
5545 augroup QF_Test
5546 au!
5547 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5548 augroup END
5549
5550 try
5551 lvimgrep /.*/ *.mak
5552 catch /E926:/
5553 endtry
5554 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5555 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5556
5557 augroup QF_Test
5558 au!
5559 augroup END
5560 unlet g:BufNum
5561 %bw!
5562endfunc
5563
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005564" Test for adding an invalid entry with the quickfix window open and making
5565" sure that the window contents are not changed
5566func Test_add_invalid_entry_with_qf_window()
5567 call setqflist([], 'f')
5568 cexpr "Xfile1:10:aa"
5569 copen
5570 call setqflist(['bb'], 'a')
5571 call assert_equal(1, line('$'))
5572 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005573 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())
5574
5575 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5576 call assert_equal(1 , line('$'))
5577 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5578 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())
5579
5580 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')
5581 call assert_equal(1 , line('$'))
5582 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5583 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())
5584
5585 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')
5586 call assert_equal(1 , line('$'))
5587 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5588 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())
5589
5590 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')
5591 call assert_equal(1 , line('$'))
5592 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5593 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())
5594
5595 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')
5596 call assert_equal(1 , line('$'))
5597 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5598 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())
5599
5600 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')
5601 call assert_equal(1 , line('$'))
5602 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5603 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())
5604
5605 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')
5606 call assert_equal(1 , line('$'))
5607 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5608 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 +01005609 cclose
5610endfunc
5611
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005612" Test for very weird problem: autocommand causes a failure, resulting opening
5613" the quickfix window to fail. This still splits the window, but otherwise
5614" should not mess up buffers.
5615func Test_quickfix_window_fails_to_open()
5616 CheckScreendump
5617
5618 let lines =<< trim END
5619 anything
5620 try
5621 anything
5622 endtry
5623 END
5624 call writefile(lines, 'XquickfixFails')
5625
5626 let lines =<< trim END
5627 split XquickfixFails
5628 silent vimgrep anything %
5629 normal o
5630 au BufLeave * ++once source XquickfixFails
5631 " This will trigger the autocommand, which causes an error, what follows
5632 " is aborted but the window was already split.
5633 silent! cwindow
5634 END
5635 call writefile(lines, 'XtestWinFails')
5636 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5637 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5638
5639 " clean up
5640 call term_sendkeys(buf, ":bwipe!\<CR>")
5641 call term_wait(buf)
5642 call StopVimInTerminal(buf)
5643 call delete('XtestWinFails')
5644 call delete('XquickfixFails')
5645endfunc
5646
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005647" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005648" is changed.
5649func Xqfbuf_update(cchar)
5650 call s:setup_commands(a:cchar)
5651
5652 Xexpr "F1:1:line1"
5653 Xopen
5654 call assert_equal(['F1|1| line1'], getline(1, '$'))
5655 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5656
5657 " Test setqflist() using the 'lines' key in 'what'
5658 " add a new entry
5659 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5660 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5661 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5662 " replace all the entries with a single entry
5663 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5664 call assert_equal(['F3|3| line3'], getline(1, '$'))
5665 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5666 " remove all the entries
5667 call g:Xsetlist([], 'r', {'lines' : []})
5668 call assert_equal([''], getline(1, '$'))
5669 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5670 " add a new list
5671 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5672 call assert_equal(['F4|4| line4'], getline(1, '$'))
5673 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5674
5675 " Test setqflist() using the 'items' key in 'what'
5676 " add a new entry
5677 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5678 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5679 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5680 " replace all the entries with a single entry
5681 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5682 call assert_equal(['F6|6| line6'], getline(1, '$'))
5683 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5684 " remove all the entries
5685 call g:Xsetlist([], 'r', {'items' : []})
5686 call assert_equal([''], getline(1, '$'))
5687 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5688 " add a new list
5689 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5690 call assert_equal(['F7|7| line7'], getline(1, '$'))
5691 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5692
5693 call g:Xsetlist([], ' ', {})
5694 call assert_equal([''], getline(1, '$'))
5695 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5696
5697 Xclose
5698endfunc
5699
5700func Test_qfbuf_update()
5701 call Xqfbuf_update('c')
5702 call Xqfbuf_update('l')
5703endfunc
5704
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005705func Test_vimgrep_noswapfile()
5706 set noswapfile
5707 call writefile(['one', 'two', 'three'], 'Xgreppie')
5708 vimgrep two Xgreppie
5709 call assert_equal('two', getline('.'))
5710
5711 call delete('Xgreppie')
5712 set swapfile
5713endfunc
5714
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005715" Test for the :vimgrep 'f' flag (fuzzy match)
5716func Xvimgrep_fuzzy_match(cchar)
5717 call s:setup_commands(a:cchar)
5718
5719 Xvimgrep /three one/f Xfile*
5720 let l = g:Xgetlist()
5721 call assert_equal(2, len(l))
5722 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5723 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5724 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5725 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5726
5727 Xvimgrep /the/f Xfile*
5728 let l = g:Xgetlist()
5729 call assert_equal(3, len(l))
5730 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5731 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5732 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5733 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5734 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5735 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5736
5737 Xvimgrep /aaa/fg Xfile*
5738 let l = g:Xgetlist()
5739 call assert_equal(4, len(l))
5740 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5741 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5742 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5743 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5744 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5745 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5746 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5747 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5748
5749 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5750endfunc
5751
5752func Test_vimgrep_fuzzy_match()
5753 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5754 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5755 call Xvimgrep_fuzzy_match('c')
5756 call Xvimgrep_fuzzy_match('l')
5757 call delete('Xfile1')
5758 call delete('Xfile2')
5759endfunc
5760
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005761func Test_locationlist_open_in_newtab()
5762 call s:create_test_file('Xqftestfile1')
5763 call s:create_test_file('Xqftestfile2')
5764 call s:create_test_file('Xqftestfile3')
5765
5766 %bwipe!
5767
5768 lgetexpr ['Xqftestfile1:5:Line5',
5769 \ 'Xqftestfile2:10:Line10',
5770 \ 'Xqftestfile3:16:Line16']
5771
5772 silent! llast
5773 call assert_equal(1, tabpagenr('$'))
5774 call assert_equal('Xqftestfile3', bufname())
5775
5776 set switchbuf=newtab
5777
5778 silent! lfirst
5779 call assert_equal(2, tabpagenr('$'))
5780 call assert_equal('Xqftestfile1', bufname())
5781
5782 silent! lnext
5783 call assert_equal(3, tabpagenr('$'))
5784 call assert_equal('Xqftestfile2', bufname())
5785
5786 call delete('Xqftestfile1')
5787 call delete('Xqftestfile2')
5788 call delete('Xqftestfile3')
5789 set switchbuf&vim
5790
5791 %bwipe!
5792endfunc
5793
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005794" Test for win_gettype() in quickfix and location list windows
5795func Test_win_gettype()
5796 copen
5797 call assert_equal("quickfix", win_gettype())
5798 let wid = win_getid()
5799 wincmd p
5800 call assert_equal("quickfix", win_gettype(wid))
5801 cclose
5802 lexpr ''
5803 lopen
5804 call assert_equal("loclist", win_gettype())
5805 let wid = win_getid()
5806 wincmd p
5807 call assert_equal("loclist", win_gettype(wid))
5808 lclose
5809endfunc
5810
Christian Brabandt0b226f62021-12-01 10:54:24 +00005811fun Test_vimgrep_nomatch()
5812 call XexprTests('c')
5813 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5814 copen
5815 if has("win32")
5816 call assert_fails('vimgrep foo *.zzz', 'E479:')
5817 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'}]
5818 else
5819 call assert_fails('vimgrep foo *.zzz', 'E480:')
5820 let expected = []
5821 endif
5822 call assert_equal(expected, getqflist())
5823 cclose
5824endfunc
5825
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005826" Test for opening the quickfix window in two tab pages and then closing one
5827" of the quickfix windows. This should not make the quickfix buffer unlisted.
5828" (github issue #9300).
5829func Test_two_qf_windows()
5830 cexpr "F1:1:line1"
5831 copen
5832 tabnew
5833 copen
5834 call assert_true(&buflisted)
5835 cclose
5836 tabfirst
5837 call assert_true(&buflisted)
5838 let bnum = bufnr()
5839 cclose
5840 " if all the quickfix windows are closed, then buffer should be unlisted.
5841 call assert_false(buflisted(bnum))
5842 %bw!
5843
5844 " Repeat the test for a location list
5845 lexpr "F2:2:line2"
5846 lopen
5847 let bnum = bufnr()
5848 tabnew
5849 exe "buffer" bnum
5850 tabfirst
5851 lclose
5852 tablast
5853 call assert_true(buflisted(bnum))
5854 tabclose
5855 lopen
5856 call assert_true(buflisted(bnum))
5857 lclose
5858 call assert_false(buflisted(bnum))
5859 %bw!
5860endfunc
5861
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005862" Weird sequence of commands that caused entering a wiped-out buffer
5863func Test_lopen_bwipe()
5864 func R()
5865 silent! tab lopen
5866 e x
5867 silent! lfile
5868 endfunc
5869
5870 cal R()
5871 cal R()
5872 cal R()
5873 bw!
5874 delfunc R
5875endfunc
5876
Bram Moolenaare3537ae2022-02-08 15:05:20 +00005877" Another sequence of commands that caused all buffers to be wiped out
5878func Test_lopen_bwipe_all()
5879 let lines =<< trim END
5880 func R()
5881 silent! tab lopen
5882 e foo
5883 silent! lfile
5884 endfunc
5885 cal R()
5886 exe "norm \<C-W>\<C-V>0"
5887 cal R()
5888 bwipe
5889
5890 call writefile(['done'], 'Xresult')
5891 qall!
5892 END
5893 call writefile(lines, 'Xscript')
5894 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
5895 call assert_equal(['done'], readfile('Xresult'))
5896 endif
5897
5898 call delete('Xscript')
5899 call delete('Xresult')
5900endfunc
5901
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005902
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005903" vim: shiftwidth=2 sts=2 expandtab