blob: ccfa340f6cfd5f1a7abf403163fd4ce7ac4f748c [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 Moolenaar4791fcd2022-02-23 12:06:00 +0000748func Test_helpgrep_restore_cpo_aucmd()
749 let save_cpo = &cpo
750 augroup QF_Test
751 au!
752 autocmd BufNew * set cpo=acd
753 augroup END
754
755 helpgrep quickfix
756 call assert_equal('acd', &cpo)
757 %bw!
758
759 set cpo&vim
760 augroup QF_Test
761 au!
762 autocmd BufReadPost * set cpo=
763 augroup END
764
765 helpgrep buffer
766 call assert_equal('', &cpo)
767
768 augroup QF_Test
769 au!
770 augroup END
771 %bw!
772 let &cpo = save_cpo
773endfunc
774
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200775def Test_vim9_cexpr()
776 var text = 'somefile:95:error'
777 cexpr text
778 var l = getqflist()
779 assert_equal(1, l->len())
780 assert_equal(95, l[0].lnum)
781 assert_equal('error', l[0].text)
782
783 text = 'somefile:77:warning'
784 caddexpr text
785 l = getqflist()
786 assert_equal(2, l->len())
787 assert_equal(77, l[1].lnum)
788 assert_equal('warning', l[1].text)
789enddef
790
Bram Moolenaar6920c722016-01-22 22:44:10 +0100791func Test_errortitle()
792 augroup QfBufWinEnter
793 au!
794 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
795 augroup END
796 copen
797 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'')'}]
798 call setqflist(a)
799 call assert_equal(':setqflist()', g:a)
800 augroup QfBufWinEnter
801 au!
802 augroup END
803 augroup! QfBufWinEnter
804endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100805
Bram Moolenaar5584df62016-03-18 21:00:51 +0100806func Test_vimgreptitle()
807 augroup QfBufWinEnter
808 au!
809 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
810 augroup END
811 try
812 vimgrep /pattern/j file
813 catch /E480/
814 endtry
815 copen
816 call assert_equal(': vimgrep /pattern/j file', g:a)
817 augroup QfBufWinEnter
818 au!
819 augroup END
820 augroup! QfBufWinEnter
821endfunc
822
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100823func Test_bufwinenter_once()
824 augroup QfBufWinEnter
825 au!
826 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
827 augroup END
828 let g:got_afile = ''
829 copen
830 call assert_equal('got quickfix', g:got_afile)
831
832 cclose
833 unlet g:got_afile
834 augroup QfBufWinEnter
835 au!
836 augroup END
837 augroup! QfBufWinEnter
838endfunc
839
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100840func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200841 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100842
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200843 Xgetexpr ['file:1:1:message']
844 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100845 if a:cchar == 'c'
846 call setqflist(l, 'r')
847 else
848 call setloclist(0, l, 'r')
849 endif
850
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200851 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100852 if a:cchar == 'c'
853 let title = ':setqflist()'
854 else
855 let title = ':setloclist()'
856 endif
857 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200858 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100859endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100860
861" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100862func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200863 call XqfTitleTests('c')
864 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100865endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100866
867" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100868func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100869 let save_efm = &efm
870 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
871 cgetexpr ['WWWW', 'EEEE', 'CCCC']
872 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
873 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
874 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
875 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
876 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
877 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
878 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
879 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
880 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100881endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100882
883" This will test for problems in quickfix:
884" A. incorrectly copying location lists which caused the location list to show
885" a different name than the file that was actually being displayed.
886" B. not reusing the window for which the location list window is opened but
887" instead creating new windows.
888" C. make sure that the location list window is not reused instead of the
889" window it belongs to.
890"
891" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100892func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100893 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
894 let word = substitute(base, '\v(.*)\..*', '\1', '')
895
896 setl modifiable
897 setl noreadonly
898 setl noswapfile
899 setl bufhidden=delete
900 %del _
901 " For problem 2:
902 " 'buftype' has to be set to reproduce the constant opening of new windows
903 setl buftype=nofile
904
905 call setline(1, word)
906
907 setl nomodified
908 setl nomodifiable
909 setl readonly
910 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100911endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100912
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100913func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200914 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100915
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200916 augroup testgroup
917 au!
918 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
919 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100920
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200921 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100922
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200923 let qflist = []
924 for word in words
925 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
926 " NOTE: problem 1:
927 " intentionally not setting 'lnum' so that the quickfix entries are not
928 " valid
929 eval qflist->setloclist(0, ' ')
930 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100931
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200932 " Test A
933 lrewind
934 enew
935 lopen
936 4lnext
937 vert split
938 wincmd L
939 lopen
940 wincmd p
941 lnext
942 let fileName = expand("%")
943 wincmd p
944 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
945 let fileName = substitute(fileName, '\\', '/', 'g')
946 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
947 call assert_equal("test://bar.txt", fileName)
948 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100949
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200950 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100951
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200952 " Test B:
953 lrewind
954 lopen
955 2
956 exe "normal \<CR>"
957 wincmd p
958 3
959 exe "normal \<CR>"
960 wincmd p
961 4
962 exe "normal \<CR>"
963 call assert_equal(2, winnr('$'))
964 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100965
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200966 " Test C:
967 lrewind
968 lopen
969 " Let's move the location list window to the top to check whether it (the
970 " first window found) will be reused when we try to open new windows:
971 wincmd K
972 2
973 exe "normal \<CR>"
974 wincmd p
975 3
976 exe "normal \<CR>"
977 wincmd p
978 4
979 exe "normal \<CR>"
980 1wincmd w
981 call assert_equal('quickfix', &buftype)
982 2wincmd w
983 let bufferName = expand("%")
984 let bufferName = substitute(bufferName, '\\', '/', 'g')
985 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100986
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200987 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100988
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200989 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100990endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100991
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100992func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200993 augroup testgroup
994 au!
995 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
996 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100997
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200998 func! R(n)
999 quit
1000 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +01001001
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001002 new
1003 let q = []
1004 call add(q, {'filename': 'test_curwin.txt' })
1005 call setloclist(0, q)
1006 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +01001007
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001008 augroup! testgroup
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00001009 delfunc R
Bram Moolenaaree85df32017-03-19 14:19:50 +01001010endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001011
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001012func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001013 call writefile(['loclistfoo'], 'loclistfoo')
1014 call writefile(['loclistbar'], 'loclistbar')
1015 set switchbuf=usetab
1016
1017 edit loclistfoo
1018 tabedit loclistbar
1019 silent lgrep loclistfoo loclist*
1020 call assert_equal(1, tabpagenr())
1021
1022 enew | only | tabonly
1023 set switchbuf&vim
1024 call delete('loclistfoo')
1025 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001026endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +02001027
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001028" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001029func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001030 " The 'errorformat' setting is different on non-Unix systems.
1031 " This test works only on Unix-like systems.
1032 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001033
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001034 let l =<< trim [DATA]
1035 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1036 "Xtestfile", line 6 col 19; this is an error
1037 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1038 Xtestfile:9: parse error before `asd'
1039 make: *** [vim] Error 1
1040 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001041
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001042 2 returned
1043 "Xtestfile", line 11 col 1; this is an error
1044 "Xtestfile", line 12 col 2; this is another error
1045 "Xtestfile", line 14:10; this is an error in column 10
1046 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1047 "Xtestfile", linenr 16: yet another problem
1048 Error in "Xtestfile" at line 17:
1049 x should be a dot
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1051 ^
1052 Error in "Xtestfile" at line 18:
1053 x should be a dot
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1055 .............^
1056 Error in "Xtestfile" at line 19:
1057 x should be a dot
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1059 --------------^
1060 Error in "Xtestfile" at line 20:
1061 x should be a dot
1062 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1063 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001064
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001065 Does anyone know what is the problem and how to correction it?
1066 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1067 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1068 [DATA]
1069
1070 call writefile(l, 'Xerrorfile1')
1071 call writefile(l[:-2], 'Xerrorfile2')
1072
1073 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001074 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1075 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1076 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1077 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1078 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1079 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1080 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1081 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1082 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1083 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1084 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1085 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1086 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1087 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1088 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1089 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1090 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1091 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1092 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1093 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1094 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1095[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001096 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001097
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001098 let save_efm = &efm
1099 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1100 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001101
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001102 exe 'cf Xerrorfile2'
1103 clast
1104 copen
1105 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1106 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001107
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001108 exe 'cf Xerrorfile1'
1109 call assert_equal([4, 12], [line('.'), col('.')])
1110 cn
1111 call assert_equal([6, 19], [line('.'), col('.')])
1112 cn
1113 call assert_equal([9, 2], [line('.'), col('.')])
1114 cn
1115 call assert_equal([10, 2], [line('.'), col('.')])
1116 cn
1117 call assert_equal([11, 1], [line('.'), col('.')])
1118 cn
1119 call assert_equal([12, 2], [line('.'), col('.')])
1120 cn
1121 call assert_equal([14, 10], [line('.'), col('.')])
1122 cn
1123 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1124 cn
1125 call assert_equal([16, 2], [line('.'), col('.')])
1126 cn
1127 call assert_equal([17, 6], [line('.'), col('.')])
1128 cn
1129 call assert_equal([18, 7], [line('.'), col('.')])
1130 cn
1131 call assert_equal([19, 8], [line('.'), col('.')])
1132 cn
1133 call assert_equal([20, 9], [line('.'), col('.')])
1134 clast
1135 cprev
1136 cprev
1137 wincmd w
1138 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1139 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001140
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001141 let &efm = save_efm
1142 call delete('Xerrorfile1')
1143 call delete('Xerrorfile2')
1144 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001145endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001146
Bram Moolenaarab47c612016-06-14 22:02:26 +02001147" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001148func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001149 call s:setup_commands(a:cchar)
1150
Bram Moolenaarab47c612016-06-14 22:02:26 +02001151 let save_efm=&efm
1152 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1153
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001154 let lines = ["Entering dir 'dir1/a'",
1155 \ 'habits2.txt:1:Nine Healthy Habits',
1156 \ "Entering dir 'b'",
1157 \ 'habits3.txt:2:0 Hours of television',
1158 \ 'habits2.txt:7:5 Small meals',
1159 \ "Entering dir 'dir1/c'",
1160 \ 'habits4.txt:3:1 Hour of exercise',
1161 \ "Leaving dir 'dir1/c'",
1162 \ "Leaving dir 'dir1/a'",
1163 \ 'habits1.txt:4:2 Liters of water',
1164 \ "Entering dir 'dir2'",
1165 \ 'habits5.txt:5:3 Cups of hot green tea',
1166 \ "Leaving dir 'dir2'"
1167 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001168
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001169 Xexpr ""
1170 for l in lines
1171 Xaddexpr l
1172 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001173
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001174 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001175
1176 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1177 call assert_equal(1, qf[1].lnum)
1178 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1179 call assert_equal(2, qf[3].lnum)
1180 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1181 call assert_equal(7, qf[4].lnum)
1182 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1183 call assert_equal(3, qf[6].lnum)
1184 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1185 call assert_equal(4, qf[9].lnum)
1186 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1187 call assert_equal(5, qf[11].lnum)
1188
1189 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001190endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001191
1192" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001193func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001194 " Create the directory stack and files
1195 call mkdir('dir1')
1196 call mkdir('dir1/a')
1197 call mkdir('dir1/a/b')
1198 call mkdir('dir1/c')
1199 call mkdir('dir2')
1200
1201 let lines = ["Nine Healthy Habits",
1202 \ "0 Hours of television",
1203 \ "1 Hour of exercise",
1204 \ "2 Liters of water",
1205 \ "3 Cups of hot green tea",
1206 \ "4 Short mental breaks",
1207 \ "5 Small meals",
1208 \ "6 AM wake up time",
1209 \ "7 Minutes of laughter",
1210 \ "8 Hours of sleep (at least)",
1211 \ "9 PM end of the day and off to bed"
1212 \ ]
1213 call writefile(lines, 'habits1.txt')
1214 call writefile(lines, 'dir1/a/habits2.txt')
1215 call writefile(lines, 'dir1/a/b/habits3.txt')
1216 call writefile(lines, 'dir1/c/habits4.txt')
1217 call writefile(lines, 'dir2/habits5.txt')
1218
1219 call s:dir_stack_tests('c')
1220 call s:dir_stack_tests('l')
1221
1222 call delete('dir1', 'rf')
1223 call delete('dir2', 'rf')
1224 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001225endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001226
Bram Moolenaar9b457942016-10-09 16:10:05 +02001227" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001228func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001229 call s:setup_commands(a:cchar)
1230
1231 let save_efm = &efm
1232
1233 let &efm =
1234 \ '%Eerror %m %l,' .
1235 \ '%-Wignored %m %l,' .
1236 \ '%+Cmore ignored %m %l,' .
1237 \ '%Zignored end'
1238 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1239 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1240 call assert_equal([['resync', 1, 4, 'E']], l)
1241
1242 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001243endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001244
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001245func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001246 call Xefm_ignore_continuations('c')
1247 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001248endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001249
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001250" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001251func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001252 call s:setup_commands(a:cchar)
1253
Bram Moolenaar049cba92016-06-26 14:38:04 +02001254 let save_efm = &efm
1255
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001256 set efm=%f:%l:%m,%f:%f:%l:%m
1257 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1258
1259 set efm=%f:%l:%m,%f:%l:%r:%m
1260 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1261
1262 set efm=%f:%l:%m,%O:%f:%l:%m
1263 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1264
1265 set efm=%f:%l:%m,%f:%l:%*[^a-z
1266 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1267
1268 set efm=%f:%l:%m,%f:%l:%*c
1269 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1270
1271 set efm=%f:%l:%m,%L%M%N
1272 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1273
1274 set efm=%f:%l:%m,%f:%l:%m:%R
1275 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1276
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001277 " Invalid regular expression
1278 set efm=%\\%%k
1279 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1280
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001281 set efm=
1282 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1283
1284 set efm=%DEntering\ dir\ abc,%f:%l:%m
1285 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1286
1287 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001288endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001289
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001290func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001291 call Xinvalid_efm_Tests('c')
1292 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001293endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001294
1295" TODO:
1296" Add tests for the following formats in 'errorformat'
1297" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001298func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001299 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001300
1301 " Test for %s format in efm
1302 set efm=%f:%s
1303 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001304 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001305 call assert_equal('^\VLine search text\$', l[0].pattern)
1306 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001307
Bram Moolenaaree85df32017-03-19 14:19:50 +01001308 let l = split(execute('clist', ''), "\n")
1309 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1310
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001311 " Test for a long line
1312 cexpr 'Xtestfile:' . repeat('a', 1026)
1313 let l = getqflist()
1314 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1315
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001316 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001317 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001318 [Xtestfile1]
1319 (1,17) error: ';' missing
1320 (21,2) warning: variable 'z' not defined
1321 (67,3) error: end of file found before string ended
1322 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001323
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001324 [Xtestfile2]
1325 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001326
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001327 [Xtestfile3]
1328 NEW compiler v1.1
1329 (2,2) warning: variable 'x' not defined
1330 (67,3) warning: 's' already defined
1331 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001332 [DATA]
1333
Bram Moolenaaree85df32017-03-19 14:19:50 +01001334 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001335 " To exercise the push/pop file functionality in quickfix, the test files
1336 " need to be created.
1337 call writefile(['Line1'], 'Xtestfile1')
1338 call writefile(['Line2'], 'Xtestfile2')
1339 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001340 cexpr ""
1341 for l in lines
1342 caddexpr l
1343 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001344 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001345 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001346 call assert_equal(21, l[2].lnum)
1347 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001348 call assert_equal('w', l[2].type)
1349 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001350 call delete('Xtestfile1')
1351 call delete('Xtestfile2')
1352 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001353
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001354 " Test for %P, %Q with non-existing files
1355 cexpr lines
1356 let l = getqflist()
1357 call assert_equal(14, len(l))
1358 call assert_equal('[Xtestfile1]', l[0].text)
1359 call assert_equal('[Xtestfile2]', l[6].text)
1360 call assert_equal('[Xtestfile3]', l[9].text)
1361
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001362 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001363 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001364 Error 275
1365 line 42
1366 column 3
1367 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001368 [DATA]
1369
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001370 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1371 cgetexpr lines
1372 let l = getqflist()
1373 call assert_equal(275, l[0].nr)
1374 call assert_equal(42, l[0].lnum)
1375 call assert_equal(3, l[0].col)
1376 call assert_equal('E', l[0].type)
1377 call assert_equal("\n' ' expected after '--'", l[0].text)
1378
1379 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001380 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001381 Error in line 147 of foo.c:
1382 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001383 [DATA]
1384
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001385 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1386 cgetexpr lines
1387 let l = getqflist()
1388 call assert_equal(147, l[0].lnum)
1389 call assert_equal('E', l[0].type)
1390 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001391
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001392 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001393 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001394 ==============================================================
1395 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1396 --------------------------------------------------------------
1397 Traceback (most recent call last):
1398 File "unittests/dbfacadeTest.py", line 89, in testFoo
1399 self.assertEquals(34, dtid)
1400 File "/usr/lib/python2.2/unittest.py", line 286, in
1401 failUnlessEqual
1402 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001403 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001404
1405 --------------------------------------------------------------
1406 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001407 [DATA]
1408
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001409 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001410 cgetexpr lines
1411 let l = getqflist()
1412 call assert_equal(8, len(l))
1413 call assert_equal(89, l[4].lnum)
1414 call assert_equal(1, l[4].valid)
1415 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001416 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001417
Bram Moolenaard76ce852018-05-01 15:02:04 +02001418 " Test for %o
1419 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001420 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1421 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001422 let l = getqflist()
1423 call assert_equal(1, len(l), string(l))
1424 call assert_equal('Language.PureScript.Types', l[0].module)
1425 copen
1426 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1427 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001428 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001429 cclose
1430 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001431 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001432
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001433 " Test for a long module name
1434 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1435 let l = getqflist()
1436 call assert_equal(repeat('m', 1024), l[0].module)
1437 call assert_equal(15, l[0].lnum)
1438 call assert_equal('message', l[0].text)
1439
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001440 " The following sequence of commands used to crash Vim
1441 set efm=%W%m
1442 cgetexpr ['msg1']
1443 let l = getqflist()
1444 call assert_equal(1, len(l), string(l))
1445 call assert_equal('msg1', l[0].text)
1446 set efm=%C%m
1447 lexpr 'msg2'
1448 let l = getloclist(0)
1449 call assert_equal(1, len(l), string(l))
1450 call assert_equal('msg2', l[0].text)
1451 lopen
1452 call setqflist([], 'r')
1453 caddbuf
1454 let l = getqflist()
1455 call assert_equal(1, len(l), string(l))
1456 call assert_equal('|| msg2', l[0].text)
1457
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001458 " When matching error lines, case should be ignored. Test for this.
1459 set noignorecase
1460 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1461 call assert_equal(10, l.items[0].lnum)
1462 call assert_equal('Line 20', l.items[0].text)
1463 set ignorecase&
1464
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001465 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001466 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001467endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001468
Bram Moolenaare9283662020-06-07 14:10:47 +02001469" Test for '%t' (error type) field in 'efm'
1470func Test_efm_error_type()
1471 let save_efm = &efm
1472
1473 " error type
1474 set efm=%f:%l:%t:%m
1475 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1476 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1477 let output = split(execute('clist'), "\n")
1478 call assert_equal([
1479 \ ' 1 Xfile1:10 error: msg1',
1480 \ ' 2 Xfile1:20 warning: msg2',
1481 \ ' 3 Xfile1:30 info: msg3',
1482 \ ' 4 Xfile1:40 note: msg4',
1483 \ ' 5 Xfile1:50 R: msg5'], output)
1484
1485 " error type and a error number
1486 set efm=%f:%l:%t:%n:%m
1487 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1488 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1489 let output = split(execute('clist'), "\n")
1490 call assert_equal([
1491 \ ' 1 Xfile1:10 error 2: msg1',
1492 \ ' 2 Xfile1:20 warning 4: msg2',
1493 \ ' 3 Xfile1:30 info 6: msg3',
1494 \ ' 4 Xfile1:40 note 8: msg4',
1495 \ ' 5 Xfile1:50 R 3: msg5'], output)
1496 let &efm = save_efm
1497endfunc
1498
haya14busae023d492022-02-08 18:09:29 +00001499" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1500func Test_efm_end_lnum_col()
1501 let save_efm = &efm
1502
1503 " single line
1504 set efm=%f:%l-%e:%c-%k:%t:%m
1505 cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1506 let output = split(execute('clist'), "\n")
1507 call assert_equal([
1508 \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1509 \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1510
1511 " multiple lines
1512 set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
1513 cexpr ["1)msg1", "Xfile1:14-24:1-2",
1514 \ "2)msg2", "Xfile1:24-34:3-4"]
1515 let output = split(execute('clist'), "\n")
1516 call assert_equal([
1517 \ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1518 \ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1519 let &efm = save_efm
1520endfunc
1521
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001522func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001523 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001524 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001525 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001526 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001527 colder
1528 cgetexpr []
1529 endfunc
1530 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001531 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001532 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001533 lolder
1534 lgetexpr []
1535 endfunc
1536 endif
1537
1538 augroup testgroup
1539 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001540 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001541 augroup END
1542
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001543 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001544 let words = [ "a", "b" ]
1545 let qflist = []
1546 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001547 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001548 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001549 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001550 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001551
1552 augroup! testgroup
1553endfunc
1554
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001555func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001556 call XquickfixChangedByAutocmd('c')
1557 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001558endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001559
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001560func Test_setloclist_in_autocommand()
1561 call writefile(['test1', 'test2'], 'Xfile')
1562 edit Xfile
1563 let s:bufnr = bufnr()
1564 call setloclist(1,
1565 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1566 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1567
1568 augroup Test_LocList
1569 au!
1570 autocmd BufEnter * call setloclist(1,
1571 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1572 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1573 augroup END
1574
1575 lopen
1576 call assert_fails('exe "normal j\<CR>"', 'E926:')
1577
1578 augroup Test_LocList
1579 au!
1580 augroup END
1581 call delete('Xfile')
1582endfunc
1583
Bram Moolenaar8b201792016-03-25 15:01:10 +01001584func Test_caddbuffer_to_empty()
1585 helpgr quickfix
1586 call setqflist([], 'r')
1587 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001588 try
1589 cn
1590 catch
1591 " number of matches is unknown
1592 call assert_true(v:exception =~ 'E553:')
1593 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001594 quit!
1595endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001596
1597func Test_cgetexpr_works()
1598 " this must not crash Vim
1599 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001600 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001601endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001602
1603" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001604func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001605 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001606
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001607 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001608 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001609 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001610 call assert_equal(2, len(l))
1611 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001612 call assert_equal(3, l[1].end_lnum)
1613 call assert_equal(4, l[1].col)
1614 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001615
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001616 Xnext
1617 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1618 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001619 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001620 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001621 call assert_equal(3, line('.'))
1622
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001623 " Appending entries to the list should not change the cursor position
1624 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001625 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001626 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001627 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001628 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1629 call assert_equal(1, line('.'))
1630 close
1631
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001632 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001633 \ {'bufnr': a:bnum, 'lnum': 4},
1634 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001635 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001636 call assert_equal(3, len(l))
1637 call assert_equal(5, l[2].lnum)
1638
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001639 call g:Xsetlist([])
1640 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001641 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001642
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001643 " Tests for setting the 'valid' flag
1644 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1645 Xwindow
1646 call assert_equal(1, winnr('$'))
1647 let l = g:Xgetlist()
1648 call g:Xsetlist(l)
1649 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001650 " Adding a non-valid entry should not mark the list as having valid entries
1651 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1652 Xwindow
1653 call assert_equal(1, winnr('$'))
1654
1655 " :cnext/:cprev should still work even with invalid entries in the list
1656 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1657 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1658 call g:Xsetlist(l)
1659 Xnext
1660 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1661 Xprev
1662 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1663 " :cnext/:cprev should still work after appending invalid entries to an
1664 " empty list
1665 call g:Xsetlist([])
1666 call g:Xsetlist(l, 'a')
1667 Xnext
1668 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1669 Xprev
1670 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1671
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001672 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1673 Xwindow
1674 call assert_equal(2, winnr('$'))
1675 Xclose
1676 let save_efm = &efm
1677 set efm=%m
1678 Xgetexpr 'TestMessage'
1679 let l = g:Xgetlist()
1680 call g:Xsetlist(l)
1681 call assert_equal(1, g:Xgetlist()[0].valid)
1682 let &efm = save_efm
1683
Bram Moolenaaree85df32017-03-19 14:19:50 +01001684 " Error cases:
1685 " Refer to a non-existing buffer and pass a non-dictionary type
1686 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1687 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1688 call g:Xsetlist([[1, 2,3]])
1689 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001690 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001691endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001692
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001693func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001694 new Xtestfile | only
1695 let bnum = bufnr('%')
1696 call setline(1, range(1,5))
1697
1698 call SetXlistTests('c', bnum)
1699 call SetXlistTests('l', bnum)
1700
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001701 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001702 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001703endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001704
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001705func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001706 call s:setup_commands(a:cchar)
1707
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001708 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001709 let @/ = 'Test_'
1710 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001711 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001712 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001713 Xvimgrep empty test_quickfix.vim
1714 call assert_true(len(g:Xgetlist()) > 0)
1715 Xvimgrep matches test_quickfix.vim
1716 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001717 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001718 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001719 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001720 call g:Xsetlist([], 'r')
1721 call assert_true(len(g:Xgetlist()) == 0)
1722 Xolder
1723 call assert_equal(testlen, len(g:Xgetlist()))
1724 Xnewer
1725 Xnewer
1726 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001727endfunc
1728
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001729func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001730 call Xlist_empty_middle('c')
1731 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001732endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001733
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001734func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 call s:setup_commands(a:cchar)
1736
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001737 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001738 Xvimgrep one test_quickfix.vim
1739 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001740 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001741 Xvimgrep two test_quickfix.vim
1742 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001743 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001744 Xvimgrep three test_quickfix.vim
1745 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001746 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001747 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001748 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001749 call g:Xsetlist([], 'r')
1750 call assert_true(len(g:Xgetlist()) == 0)
1751 Xnewer
1752 call assert_equal(twolen, len(g:Xgetlist()))
1753 Xnewer
1754 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001755endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001756
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001758 call Xlist_empty_older('c')
1759 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001760endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001761
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001762func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001763 call s:setup_commands(a:cchar)
1764
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001765 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1766 \ {'filename': 'fnameB', 'text': 'B'}]
1767 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1768 \ {'filename': 'fnameD', 'text': 'D'},
1769 \ {'filename': 'fnameE', 'text': 'E'}]
1770
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001771 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001772 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001773 silent! Xnewer 99
1774 call g:Xsetlist(list1)
1775 call g:Xsetlist(list2)
1776 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001777 call assert_equal(3, len(li))
1778 call assert_equal('C', li[0]['text'])
1779 call assert_equal('D', li[1]['text'])
1780 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001781 silent! Xolder
1782 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001783 call assert_equal(2, len(li))
1784 call assert_equal('A', li[0]['text'])
1785 call assert_equal('B', li[1]['text'])
1786
1787 " {action} is specified ' '.
1788 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001789 silent! Xnewer 99
1790 call g:Xsetlist(list1)
1791 call g:Xsetlist(list2, ' ')
1792 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001793 call assert_equal(3, len(li))
1794 call assert_equal('C', li[0]['text'])
1795 call assert_equal('D', li[1]['text'])
1796 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001797 silent! Xolder
1798 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001799 call assert_equal(2, len(li))
1800 call assert_equal('A', li[0]['text'])
1801 call assert_equal('B', li[1]['text'])
1802
1803 " {action} is specified 'a'.
1804 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001805 silent! Xnewer 99
1806 call g:Xsetlist(list1)
1807 call g:Xsetlist(list2, 'a')
1808 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001809 call assert_equal(5, len(li))
1810 call assert_equal('A', li[0]['text'])
1811 call assert_equal('B', li[1]['text'])
1812 call assert_equal('C', li[2]['text'])
1813 call assert_equal('D', li[3]['text'])
1814 call assert_equal('E', li[4]['text'])
1815
1816 " {action} is specified 'r'.
1817 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001818 silent! Xnewer 99
1819 call g:Xsetlist(list1)
1820 call g:Xsetlist(list2, 'r')
1821 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001822 call assert_equal(3, len(li))
1823 call assert_equal('C', li[0]['text'])
1824 call assert_equal('D', li[1]['text'])
1825 call assert_equal('E', li[2]['text'])
1826
1827 " Test for wrong value.
1828 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001829 call assert_fails("call g:Xsetlist(0)", 'E714:')
1830 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1831 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1832 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1833 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001834endfunc
1835
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001836func Test_setqflist_invalid_nr()
1837 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001838 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001839endfunc
1840
Bram Moolenaar99234f22020-02-10 22:56:54 +01001841func Test_setqflist_user_sets_buftype()
1842 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1843 set buftype=quickfix
1844 call setqflist([], 'a')
1845 enew
1846endfunc
1847
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001848func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001849 call XquickfixSetListWithAct('c')
1850 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001851endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001852
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001853func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001854 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001855
Bram Moolenaar049cba92016-06-26 14:38:04 +02001856 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001857 call assert_equal(1, l[0].lnum)
1858 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001859 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001860 call assert_equal(2, l[1].lnum)
1861 call assert_equal(1, l[1].col)
1862 call assert_equal(4070, len(l[1].text))
1863 call assert_equal(3, l[2].lnum)
1864 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001865 call assert_equal(4070, len(l[2].text))
1866 call assert_equal(4, l[3].lnum)
1867 call assert_equal(1, l[3].col)
1868 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001869
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001870 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001871endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001872
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001873func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001874 call s:setup_commands(a:cchar)
1875
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001876 let testfile = 'samples/quickfix.txt'
1877
1878 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001879 exe 'Xgetfile' testfile
1880 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001881
1882 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001883 Xexpr readfile(testfile)
1884 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001885
1886 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001887 Xexpr join(readfile(testfile), "\n")
1888 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001889
1890 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001891 exe 'edit' testfile
1892 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001893 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001894endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001895
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001896func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001897 call s:long_lines_tests('c')
1898 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001899endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001901func Test_cgetfile_on_long_lines()
1902 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1903 " are read at a time.
1904 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1905 let lines = [
1906 \ '/tmp/file1:1:1:aaa',
1907 \ '/tmp/file2:1:1:%s',
1908 \ '/tmp/file3:1:1:bbb',
1909 \ '/tmp/file4:1:1:ccc',
1910 \ ]
1911 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1912 call writefile(lines, 'Xcqetfile.txt')
1913 cgetfile Xcqetfile.txt
1914 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1915 endfor
1916 call delete('Xcqetfile.txt')
1917endfunc
1918
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001919func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001920 let l = []
1921 for i in range(1, 20)
1922 call add(l, 'Line' . i)
1923 endfor
1924 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001925endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001926
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001927func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001928 call s:create_test_file('Xqftestfile1')
1929 call s:create_test_file('Xqftestfile2')
1930 call s:create_test_file('Xqftestfile3')
1931
1932 new | only
1933 edit Xqftestfile1
1934 let file1_winid = win_getid()
1935 new Xqftestfile2
1936 let file2_winid = win_getid()
1937 cgetexpr ['Xqftestfile1:5:Line5',
1938 \ 'Xqftestfile1:6:Line6',
1939 \ 'Xqftestfile2:10:Line10',
1940 \ 'Xqftestfile2:11:Line11',
1941 \ 'Xqftestfile3:15:Line15',
1942 \ 'Xqftestfile3:16:Line16']
1943
1944 new
1945 let winid = win_getid()
1946 cfirst | cnext
1947 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001948 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001949 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001950 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001951 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001952
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001953 " Test for 'switchbuf' set to search for files in windows in the current
1954 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001955 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001956 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001957 cfirst | cnext
1958 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001959 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001960 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001961 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001962 call assert_equal(file2_winid, win_getid())
1963
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001964 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1965 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001966 enew | only
1967 set switchbuf=usetab
1968 tabedit Xqftestfile1
1969 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001970 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001971 tabfirst
1972 cfirst | cnext
1973 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001974 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001975 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001976 6cnext
1977 call assert_equal(4, tabpagenr())
1978 2cpfile
1979 call assert_equal(2, tabpagenr())
1980 2cnfile
1981 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001982 tabfirst | tabonly | enew
1983
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001984 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001985 set switchbuf=split
1986 cfirst | cnext
1987 call assert_equal(1, winnr('$'))
1988 cnext | cnext
1989 call assert_equal(2, winnr('$'))
1990 cnext | cnext
1991 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001992
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001993 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001994 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001995 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001996 cfirst | cnext
1997 call assert_equal(1, tabpagenr('$'))
1998 cnext | cnext
1999 call assert_equal(2, tabpagenr('$'))
2000 cnext | cnext
2001 call assert_equal(3, tabpagenr('$'))
2002 tabfirst | enew | tabonly | only
2003
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01002004 set switchbuf=uselast
2005 split
2006 let last_winid = win_getid()
2007 copen
2008 exe "normal 1G\<CR>"
2009 call assert_equal(last_winid, win_getid())
2010 enew | only
2011
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002012 " With an empty 'switchbuf', jumping to a quickfix entry should open the
2013 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002014 set switchbuf=
2015 edit Xqftestfile1
2016 let file1_winid = win_getid()
2017 new Xqftestfile2
2018 let file2_winid = win_getid()
2019 copen
2020 exe "normal 1G\<CR>"
2021 call assert_equal(file1_winid, win_getid())
2022 copen
2023 exe "normal 3G\<CR>"
2024 call assert_equal(file2_winid, win_getid())
2025 copen | only
2026 exe "normal 5G\<CR>"
2027 call assert_equal(2, winnr('$'))
2028 call assert_equal(1, bufwinnr('Xqftestfile3'))
2029
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002030 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02002031 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02002032 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002033 set switchbuf=usetab
2034 tabedit Xqftestfile1
2035 tabedit Xqftestfile2
2036 tabedit Xqftestfile3
2037 tabfirst
2038 copen | only
2039 clast
2040 call assert_equal(4, tabpagenr())
2041 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02002042
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002043 " Jumping to a file that is not present in any of the tabpages and the
2044 " current tabpage doesn't have any usable windows, should open it in a new
2045 " window in the current tabpage.
2046 copen | only
2047 cfirst
2048 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002049 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002050
2051 " If opening a file changes 'switchbuf', then the new value should be
2052 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002053 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002054 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
2055 enew | only
2056 set switchbuf&vim
2057 cexpr "Xqftestfile1:1:10"
2058 call assert_equal('split', &switchbuf)
2059 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2060 enew | only
2061 set switchbuf=useopen
2062 cexpr "Xqftestfile1:1:10"
2063 call assert_equal('usetab', &switchbuf)
2064 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2065 enew | only
2066 set switchbuf=useopen
2067 cexpr "Xqftestfile1:1:10"
2068 call assert_equal('', &switchbuf)
2069
Bram Moolenaar049cba92016-06-26 14:38:04 +02002070 call delete('Xqftestfile1')
2071 call delete('Xqftestfile2')
2072 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002073 set switchbuf&vim
2074
2075 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002076endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002077
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002078func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002079 call s:setup_commands(a:cchar)
2080
2081 enew | only
2082
Bram Moolenaarc1542742016-07-20 21:44:37 +02002083 let fname = 'Xqftestfile' . a:cchar
2084 call s:create_test_file(fname)
2085 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002086
Bram Moolenaarc1542742016-07-20 21:44:37 +02002087 Xgetexpr [fname . ':5:Line5',
2088 \ fname . ':10:Line10',
2089 \ fname . ':15:Line15',
2090 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002091
2092 6,14delete
2093 call append(6, ['Buffer', 'Window'])
2094
2095 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002096 call assert_equal(5, l[0].lnum)
2097 call assert_equal(6, l[2].lnum)
2098 call assert_equal(13, l[3].lnum)
2099
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002100 " If a file doesn't have any quickfix entries, then deleting lines in the
2101 " file should not update the quickfix list
2102 call g:Xsetlist([], 'f')
2103 1,2delete
2104 call assert_equal([], g:Xgetlist())
2105
Bram Moolenaar049cba92016-06-26 14:38:04 +02002106 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002107 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002108endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002109
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002110func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002111 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002112 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002113 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002114 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002115endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002116
2117" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002118func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002119 call s:setup_commands(a:cchar)
2120
2121 " The following lines are used for the grep test. Don't remove.
2122 " Grep_Test_Text: Match 1
2123 " Grep_Test_Text: Match 2
2124 " GrepAdd_Test_Text: Match 1
2125 " GrepAdd_Test_Text: Match 2
2126 enew! | only
2127 set makeef&vim
2128 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002129 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002130 Xopen
2131 call assert_true(w:quickfix_title =~ '^:grep')
2132 Xclose
2133 enew
2134 set makeef=Temp_File_##
2135 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002136 call assert_true(len(g:Xgetlist()) == 9)
2137
2138 " Try with 'grepprg' set to 'internal'
2139 set grepprg=internal
2140 silent Xgrep Grep_Test_Text: test_quickfix.vim
2141 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2142 call assert_true(len(g:Xgetlist()) == 9)
2143 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002144
2145 call writefile(['Vim'], 'XtestTempFile')
2146 set makeef=XtestTempFile
2147 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002148 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002149 call assert_false(filereadable('XtestTempFile'))
2150 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002151endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002152
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002153func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002154 " The grepprg may not be set on non-Unix systems
2155 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002156
2157 call s:test_xgrep('c')
2158 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002159endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002160
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002161func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002162 " Use one 'errorformat' for two windows. Add an expression to each of them,
2163 " make sure they each keep their own state.
2164 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2165 call mkdir('Xone/a', 'p')
2166 call mkdir('Xtwo/a', 'p')
2167 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2168 call writefile(lines, 'Xone/a/one.txt')
2169 call writefile(lines, 'Xtwo/a/two.txt')
2170
2171 new one
2172 let one_id = win_getid()
2173 lexpr ""
2174 new two
2175 let two_id = win_getid()
2176 lexpr ""
2177
2178 laddexpr "Entering dir 'Xtwo/a'"
2179 call win_gotoid(one_id)
2180 laddexpr "Entering dir 'Xone/a'"
2181 call win_gotoid(two_id)
2182 laddexpr 'two.txt:5:two two two'
2183 call win_gotoid(one_id)
2184 laddexpr 'one.txt:3:one one one'
2185
2186 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002187 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2188 call assert_equal(3, loc_one[1].lnum)
2189
2190 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002191 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2192 call assert_equal(5, loc_two[1].lnum)
2193
2194 call win_gotoid(one_id)
2195 bwipe!
2196 call win_gotoid(two_id)
2197 bwipe!
2198 call delete('Xone', 'rf')
2199 call delete('Xtwo', 'rf')
2200endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002201
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002202func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002203 call s:setup_commands(a:cchar)
2204
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002205 " Calling lbottom without any errors should fail
2206 if a:cchar == 'l'
2207 call assert_fails('lbottom', 'E776:')
2208 endif
2209
Bram Moolenaar875feea2017-06-11 16:07:51 +02002210 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002211 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002212 let wid = win_getid()
2213 call assert_equal(1, line('.'))
2214 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002215 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002216 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002217 call win_gotoid(wid)
2218 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002219 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002220endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002221
2222" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002223func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002224 call XbottomTests('c')
2225 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002226endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002227
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002228func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002229 call s:setup_commands(a:cchar)
2230
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002231 " clear all lists after the first one, then replace the first one.
2232 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002233 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002234 let entry = {'filename': 'foo', 'lnum': 42}
2235 call g:Xsetlist([entry], 'r')
2236 call g:Xsetlist([entry, entry])
2237 call g:Xsetlist([entry, entry, entry])
2238 let res = split(execute(a:cchar . 'hist'), "\n")
2239 call assert_equal(3, len(res))
2240 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2241 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2242 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2243 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002244
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002245 " Test for changing the quickfix lists
2246 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2247 exe '1' . a:cchar . 'hist'
2248 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2249 exe '3' . a:cchar . 'hist'
2250 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2251 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2252 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2253
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002254 call g:Xsetlist([], 'f')
2255 let l = split(execute(a:cchar . 'hist'), "\n")
2256 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002257 if a:cchar == 'c'
2258 call assert_fails('4chist', 'E16:')
2259 else
2260 call assert_fails('4lhist', 'E776:')
2261 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002262
2263 " An empty list should still show the stack history
2264 call g:Xsetlist([])
2265 let res = split(execute(a:cchar . 'hist'), "\n")
2266 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2267
2268 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002269endfunc
2270
2271func Test_history()
2272 call HistoryTest('c')
2273 call HistoryTest('l')
2274endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002275
2276func Test_duplicate_buf()
2277 " make sure we can get the highest buffer number
2278 edit DoesNotExist
2279 edit DoesNotExist2
2280 let last_buffer = bufnr("$")
2281
2282 " make sure only one buffer is created
2283 call writefile(['this one', 'that one'], 'Xgrepthis')
2284 vimgrep one Xgrepthis
2285 vimgrep one Xgrepthis
2286 call assert_equal(last_buffer + 1, bufnr("$"))
2287
2288 call delete('Xgrepthis')
2289endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002290
2291" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002292func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002293 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002294
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002295 " Error cases
2296 call assert_fails('call g:Xgetlist(99)', 'E715:')
2297 call assert_fails('call g:Xsetlist(99)', 'E714:')
2298 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002299
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002300 " Set and get the title
2301 call g:Xsetlist([])
2302 Xopen
2303 wincmd p
2304 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2305 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2306 call assert_equal(0, s)
2307 let d = g:Xgetlist({"title":1})
2308 call assert_equal('Sample', d.title)
2309 " Try setting title to a non-string value
2310 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2311 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2312
2313 Xopen
2314 call assert_equal('Sample', w:quickfix_title)
2315 Xclose
2316
2317 " Tests for action argument
2318 silent! Xolder 999
2319 let qfnr = g:Xgetlist({'all':1}).nr
2320 call g:Xsetlist([], 'r', {'title' : 'N1'})
2321 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2322 call g:Xsetlist([], ' ', {'title' : 'N2'})
2323 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2324
2325 let res = g:Xgetlist({'nr': 0})
2326 call assert_equal(qfnr + 1, res.nr)
2327 call assert_equal(['nr'], keys(res))
2328
2329 call g:Xsetlist([], ' ', {'title' : 'N3'})
2330 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2331
2332 " Changing the title of an earlier quickfix list
2333 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2334 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2335
2336 " Changing the title of an invalid quickfix list
2337 call assert_equal(-1, g:Xsetlist([], ' ',
2338 \ {'title' : 'SomeTitle', 'nr' : 99}))
2339 call assert_equal(-1, g:Xsetlist([], ' ',
2340 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2341
2342 if a:cchar == 'c'
2343 copen
2344 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2345 cclose
2346 endif
2347
2348 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002349 call assert_fails('call g:Xgetlist([])', 'E715:')
2350 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002351 let s = g:Xsetlist([], 'a', {'abc':1})
2352 call assert_equal(-1, s)
2353
2354 call assert_equal({}, g:Xgetlist({'abc':1}))
2355 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2356 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2357
2358 if a:cchar == 'l'
2359 call assert_equal({}, getloclist(99, {'title': 1}))
2360 endif
2361
2362 " Context related tests
2363 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2364 call assert_equal(0, s)
2365 call test_garbagecollect_now()
2366 let d = g:Xgetlist({'context':1})
2367 call assert_equal([1,2,3], d.context)
2368 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2369 let d = g:Xgetlist({'context':1})
2370 call assert_equal({'color':'green'}, d.context)
2371 call g:Xsetlist([], 'a', {'context':"Context info"})
2372 let d = g:Xgetlist({'context':1})
2373 call assert_equal("Context info", d.context)
2374 call g:Xsetlist([], 'a', {'context':246})
2375 let d = g:Xgetlist({'context':1})
2376 call assert_equal(246, d.context)
2377 " set other Vim data types as context
2378 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2379 if has('channel')
2380 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2381 endif
2382 if has('job')
2383 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2384 endif
2385 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2386 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2387 call g:Xsetlist([], 'a', {'context' : ''})
2388 call test_garbagecollect_now()
2389 if a:cchar == 'l'
2390 " Test for copying context across two different location lists
2391 new | only
2392 let w1_id = win_getid()
2393 let l = [1]
2394 call setloclist(0, [], 'a', {'context':l})
2395 new
2396 let w2_id = win_getid()
2397 call add(l, 2)
2398 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2399 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2400 unlet! l
2401 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2402 only
2403 call setloclist(0, [], 'f')
2404 call assert_equal('', getloclist(0, {'context':1}).context)
2405 endif
2406
2407 " Test for changing the context of previous quickfix lists
2408 call g:Xsetlist([], 'f')
2409 Xexpr "One"
2410 Xexpr "Two"
2411 Xexpr "Three"
2412 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2413 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2414 " Also, check for setting the context using quickfix list number zero.
2415 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2416 call test_garbagecollect_now()
2417 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2418 call assert_equal([1], l.context)
2419 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2420 call assert_equal([2], l.context)
2421 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2422 call assert_equal([3], l.context)
2423
2424 " Test for changing the context through reference and for garbage
2425 " collection of quickfix context
2426 let l = ["red"]
2427 call g:Xsetlist([], ' ', {'context' : l})
2428 call add(l, "blue")
2429 let x = g:Xgetlist({'context' : 1})
2430 call add(x.context, "green")
2431 call assert_equal(["red", "blue", "green"], l)
2432 call assert_equal(["red", "blue", "green"], x.context)
2433 unlet l
2434 call test_garbagecollect_now()
2435 let m = g:Xgetlist({'context' : 1})
2436 call assert_equal(["red", "blue", "green"], m.context)
2437
2438 " Test for setting/getting items
2439 Xexpr ""
2440 let qfprev = g:Xgetlist({'nr':0})
2441 let s = g:Xsetlist([], ' ', {'title':'Green',
2442 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2443 call assert_equal(0, s)
2444 let qfcur = g:Xgetlist({'nr':0})
2445 call assert_true(qfcur.nr == qfprev.nr + 1)
2446 let l = g:Xgetlist({'items':1})
2447 call assert_equal('F1', bufname(l.items[0].bufnr))
2448 call assert_equal(10, l.items[0].lnum)
2449 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2450 \ {'filename':'F2', 'lnum':30}]})
2451 let l = g:Xgetlist({'items':1})
2452 call assert_equal('F2', bufname(l.items[2].bufnr))
2453 call assert_equal(30, l.items[2].lnum)
2454 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2455 let l = g:Xgetlist({'items':1})
2456 call assert_equal('F3', bufname(l.items[0].bufnr))
2457 call assert_equal(40, l.items[0].lnum)
2458 call g:Xsetlist([], 'r', {'items' : []})
2459 let l = g:Xgetlist({'items':1})
2460 call assert_equal(0, len(l.items))
2461
2462 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2463 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2464 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2465 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2466
2467 " Test for getting id of window associated with a location list window
2468 if a:cchar == 'l'
2469 only
2470 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2471 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002472 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002473 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2474 wincmd w
2475 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2476 only
2477 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002478
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002479 " The following used to crash Vim with address sanitizer
2480 call g:Xsetlist([], 'f')
2481 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2482 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002483
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002484 " Try setting the items using a string
2485 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002486
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002487 " Save and restore the quickfix stack
2488 call g:Xsetlist([], 'f')
2489 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2490 Xexpr "File1:10:Line1"
2491 Xexpr "File2:20:Line2"
2492 Xexpr "File3:30:Line3"
2493 let last_qf = g:Xgetlist({'nr':'$'}).nr
2494 call assert_equal(3, last_qf)
2495 let qstack = []
2496 for i in range(1, last_qf)
2497 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2498 endfor
2499 call g:Xsetlist([], 'f')
2500 for i in range(len(qstack))
2501 call g:Xsetlist([], ' ', qstack[i])
2502 endfor
2503 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2504 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2505 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2506 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2507 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002508
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002509 " Swap two quickfix lists
2510 Xexpr "File1:10:Line10"
2511 Xexpr "File2:20:Line20"
2512 Xexpr "File3:30:Line30"
2513 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2514 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2515 let l1=g:Xgetlist({'nr':1,'all':1})
2516 let l2=g:Xgetlist({'nr':2,'all':1})
2517 let save_id = l1.id
2518 let l1.id=l2.id
2519 let l2.id=save_id
2520 call g:Xsetlist([], 'r', l1)
2521 call g:Xsetlist([], 'r', l2)
2522 let newl1=g:Xgetlist({'nr':1,'all':1})
2523 let newl2=g:Xgetlist({'nr':2,'all':1})
2524 call assert_equal('Fruits', newl1.title)
2525 call assert_equal(['Fruits'], newl1.context)
2526 call assert_equal('Line20', newl1.items[0].text)
2527 call assert_equal('Colors', newl2.title)
2528 call assert_equal(['Colors'], newl2.context)
2529 call assert_equal('Line10', newl2.items[0].text)
2530 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002531
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002532 " Cannot specify both a non-empty list argument and a dict argument
2533 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002534endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002535
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002536func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002537 call Xproperty_tests('c')
2538 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002539endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002540
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002541" Test for setting the current index in the location/quickfix list
2542func Xtest_setqfidx(cchar)
2543 call s:setup_commands(a:cchar)
2544
2545 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2546 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2547 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2548
2549 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2550 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2551 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2552 Xolder 2
2553 Xopen
2554 call assert_equal(3, line('.'))
2555 Xnewer
2556 call assert_equal(2, line('.'))
2557 Xnewer
2558 call assert_equal(2, line('.'))
2559 " Update the current index with the quickfix window open
2560 wincmd w
2561 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2562 Xopen
2563 call assert_equal(3, line('.'))
2564 Xclose
2565
2566 " Set the current index to the last entry
2567 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2568 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2569 " A large value should set the index to the last index
2570 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2571 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2572 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2573 " Invalid index values
2574 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2575 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2576 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2577 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2578 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2579 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2580 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2581
2582 call g:Xsetlist([], 'f')
2583 new | only
2584endfunc
2585
2586func Test_setqfidx()
2587 call Xtest_setqfidx('c')
2588 call Xtest_setqfidx('l')
2589endfunc
2590
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002591" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002592func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002593 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002594endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002595
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002596func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002597 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2598 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2599
2600 let g:acmds = []
2601 cexpr "F1:10:Line 10"
2602 caddexpr "F1:20:Line 20"
2603 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002604 cexpr ""
2605 caddexpr ""
2606 cgetexpr ""
2607 silent! cexpr non_existing_func()
2608 silent! caddexpr non_existing_func()
2609 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002610 let l = ['precexpr',
2611 \ 'postcexpr',
2612 \ 'precaddexpr',
2613 \ 'postcaddexpr',
2614 \ 'precgetexpr',
2615 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002616 \ 'precexpr',
2617 \ 'postcexpr',
2618 \ 'precaddexpr',
2619 \ 'postcaddexpr',
2620 \ 'precgetexpr',
2621 \ 'postcgetexpr',
2622 \ 'precexpr',
2623 \ 'precaddexpr',
2624 \ 'precgetexpr']
2625 call assert_equal(l, g:acmds)
2626
2627 let g:acmds = []
2628 enew! | call append(0, "F2:10:Line 10")
2629 cbuffer!
2630 enew! | call append(0, "F2:20:Line 20")
2631 cgetbuffer
2632 enew! | call append(0, "F2:30:Line 30")
2633 caddbuffer
2634 new
2635 let bnum = bufnr('%')
2636 bunload
2637 exe 'silent! cbuffer! ' . bnum
2638 exe 'silent! cgetbuffer ' . bnum
2639 exe 'silent! caddbuffer ' . bnum
2640 enew!
2641 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002642 \ 'postcbuffer',
2643 \ 'precgetbuffer',
2644 \ 'postcgetbuffer',
2645 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002646 \ 'postcaddbuffer',
2647 \ 'precbuffer',
2648 \ 'precgetbuffer',
2649 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002650 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002651
2652 call writefile(['Xtest:1:Line1'], 'Xtest')
2653 call writefile([], 'Xempty')
2654 let g:acmds = []
2655 cfile Xtest
2656 caddfile Xtest
2657 cgetfile Xtest
2658 cfile Xempty
2659 caddfile Xempty
2660 cgetfile Xempty
2661 silent! cfile do_not_exist
2662 silent! caddfile do_not_exist
2663 silent! cgetfile do_not_exist
2664 let l = ['precfile',
2665 \ 'postcfile',
2666 \ 'precaddfile',
2667 \ 'postcaddfile',
2668 \ 'precgetfile',
2669 \ 'postcgetfile',
2670 \ 'precfile',
2671 \ 'postcfile',
2672 \ 'precaddfile',
2673 \ 'postcaddfile',
2674 \ 'precgetfile',
2675 \ 'postcgetfile',
2676 \ 'precfile',
2677 \ 'postcfile',
2678 \ 'precaddfile',
2679 \ 'postcaddfile',
2680 \ 'precgetfile',
2681 \ 'postcgetfile']
2682 call assert_equal(l, g:acmds)
2683
2684 let g:acmds = []
2685 helpgrep quickfix
2686 silent! helpgrep non_existing_help_topic
2687 vimgrep test Xtest
2688 vimgrepadd test Xtest
2689 silent! vimgrep non_existing_test Xtest
2690 silent! vimgrepadd non_existing_test Xtest
2691 set makeprg=
2692 silent! make
2693 set makeprg&
2694 let l = ['prehelpgrep',
2695 \ 'posthelpgrep',
2696 \ 'prehelpgrep',
2697 \ 'posthelpgrep',
2698 \ 'previmgrep',
2699 \ 'postvimgrep',
2700 \ 'previmgrepadd',
2701 \ 'postvimgrepadd',
2702 \ 'previmgrep',
2703 \ 'postvimgrep',
2704 \ 'previmgrepadd',
2705 \ 'postvimgrepadd',
2706 \ 'premake',
2707 \ 'postmake']
2708 call assert_equal(l, g:acmds)
2709
2710 if has('unix')
2711 " Run this test only on Unix-like systems. The grepprg may not be set on
2712 " non-Unix systems.
2713 " The following lines are used for the grep test. Don't remove.
2714 " Grep_Autocmd_Text: Match 1
2715 " GrepAdd_Autocmd_Text: Match 2
2716 let g:acmds = []
2717 silent grep Grep_Autocmd_Text test_quickfix.vim
2718 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2719 silent grep abc123def Xtest
2720 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002721 set grepprg=internal
2722 silent grep Grep_Autocmd_Text test_quickfix.vim
2723 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2724 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2725 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2726 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002727 let l = ['pregrep',
2728 \ 'postgrep',
2729 \ 'pregrepadd',
2730 \ 'postgrepadd',
2731 \ 'pregrep',
2732 \ 'postgrep',
2733 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002734 \ 'postgrepadd',
2735 \ 'pregrep',
2736 \ 'postgrep',
2737 \ 'pregrepadd',
2738 \ 'postgrepadd',
2739 \ 'prelgrep',
2740 \ 'postlgrep',
2741 \ 'prelgrepadd',
2742 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002743 call assert_equal(l, g:acmds)
2744 endif
2745
2746 call delete('Xtest')
2747 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002748 au! QuickFixCmdPre
2749 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002750endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002751
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002752func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002753 set efm=%m
2754 lgetexpr '?'
2755
2756 try
2757 call DoesNotExit()
2758 catch
2759 lgetexpr '1'
2760 finally
2761 lgetexpr '1'
2762 endtry
2763
2764 call assert_equal('1', getloclist(0)[0].text)
2765
2766 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002767endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002768
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002769func Test_caddbuffer_wrong()
2770 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002771 let save_efm = &efm
2772 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2773 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2774 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002775 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002776 bwipe!
2777endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002778
2779func Test_caddexpr_wrong()
2780 " This used to cause a memory access in freed memory.
2781 cbuffer
2782 cbuffer
2783 copen
2784 let save_efm = &efm
2785 set efm=%
2786 call assert_fails('caddexpr ""', 'E376:')
2787 let &efm = save_efm
2788endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002789
2790func Test_dirstack_cleanup()
2791 " This used to cause a memory access in freed memory.
2792 let save_efm = &efm
2793 lexpr '0'
2794 lopen
2795 fun X(c)
2796 let save_efm=&efm
2797 set efm=%D%f
2798 if a:c == 'c'
2799 caddexpr '::'
2800 else
2801 laddexpr ':0:0'
2802 endif
2803 let &efm=save_efm
2804 endfun
2805 call X('c')
2806 call X('l')
2807 call setqflist([], 'r')
2808 caddbuffer
2809 let &efm = save_efm
2810endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002811
2812" Tests for jumping to entries from the location list window and quickfix
2813" window
2814func Test_cwindow_jump()
2815 set efm=%f%%%l%%%m
2816 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2817 lopen | only
2818 lfirst
2819 call assert_true(winnr('$') == 2)
2820 call assert_true(winnr() == 1)
2821 " Location list for the new window should be set
2822 call assert_true(getloclist(0)[2].text == 'Line 30')
2823
2824 " Open a scratch buffer
2825 " Open a new window and create a location list
2826 " Open the location list window and close the other window
2827 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002828 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002829 " should not be used.
2830 enew | only
2831 set buftype=nofile
2832 below new
2833 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2834 lopen
2835 2wincmd c
2836 lnext
2837 call assert_true(winnr('$') == 3)
2838 call assert_true(winnr() == 2)
2839
2840 " Open two windows with two different location lists
2841 " Open the location list window and close the previous window
2842 " Jump to an entry in the location list window
2843 " Should open the file in the first window and not set the location list.
2844 enew | only
2845 lgetexpr ["F1%5%Line 5"]
2846 below new
2847 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2848 lopen
2849 2wincmd c
2850 lnext
2851 call assert_true(winnr() == 1)
2852 call assert_true(getloclist(0)[0].text == 'Line 5')
2853
2854 enew | only
2855 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2856 copen
2857 cnext
2858 call assert_true(winnr('$') == 2)
2859 call assert_true(winnr() == 1)
2860
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002861 " open the quickfix buffer in two windows and jump to an entry. Should open
2862 " the file in the first quickfix window.
2863 enew | only
2864 copen
2865 let bnum = bufnr('')
2866 exe 'sbuffer ' . bnum
2867 wincmd b
2868 cfirst
2869 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002870 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002871 enew | only
2872 exe 'sb' bnum
2873 exe 'botright sb' bnum
2874 wincmd t
2875 clast
2876 call assert_equal(2, winnr())
2877 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2878 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2879
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002880 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002881 " window by wrapping around the window list.
2882 enew | only
2883 call setloclist(0, [], 'f')
2884 new | new
2885 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2886 lopen
2887 1close
2888 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2889 lnext
2890 call assert_equal(3, winnr())
2891 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2892
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002893 enew | only
2894 set efm&vim
2895endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002896
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002897func Test_cwindow_highlight()
2898 CheckScreendump
2899
2900 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002901 call setline(1, ['some', 'text', 'with', 'matches'])
2902 write XCwindow
2903 vimgrep e XCwindow
2904 redraw
2905 cwindow 4
2906 END
2907 call writefile(lines, 'XtestCwindow')
2908 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2909 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2910
2911 call term_sendkeys(buf, ":cnext\<CR>")
2912 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2913
2914 " clean up
2915 call StopVimInTerminal(buf)
2916 call delete('XtestCwindow')
2917 call delete('XCwindow')
2918endfunc
2919
Bram Moolenaaree85df32017-03-19 14:19:50 +01002920func XvimgrepTests(cchar)
2921 call s:setup_commands(a:cchar)
2922
2923 call writefile(['Editor:VIM vim',
2924 \ 'Editor:Emacs EmAcS',
2925 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002926 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002927
2928 " Error cases
2929 call assert_fails('Xvimgrep /abc *', 'E682:')
2930
2931 let @/=''
2932 call assert_fails('Xvimgrep // *', 'E35:')
2933
2934 call assert_fails('Xvimgrep abc', 'E683:')
2935 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2936 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2937
2938 Xexpr ""
2939 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002940 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002941 let l = g:Xgetlist()
2942 call assert_equal(2, len(l))
2943 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2944
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002945 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002946 let l = g:Xgetlist()
2947 call assert_equal(2, len(l))
2948 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002949 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002950 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002951 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002952
2953 1Xvimgrep ?Editor? Xtestfile*
2954 let l = g:Xgetlist()
2955 call assert_equal(1, len(l))
2956 call assert_equal('Editor:VIM vim', l[0].text)
2957
2958 edit +3 Xtestfile2
2959 Xvimgrep +\cemacs+j Xtestfile1
2960 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002961 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002962 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2963
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002964 " Test for unloading a buffer after vimgrep searched the buffer
2965 %bwipe
2966 Xvimgrep /Editor/j Xtestfile*
2967 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2968 call assert_equal([], getbufinfo('Xtestfile2'))
2969
Bram Moolenaaree85df32017-03-19 14:19:50 +01002970 call delete('Xtestfile1')
2971 call delete('Xtestfile2')
2972endfunc
2973
2974" Tests for the :vimgrep command
2975func Test_vimgrep()
2976 call XvimgrepTests('c')
2977 call XvimgrepTests('l')
2978endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002979
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002980func Test_vimgrep_wildcards_expanded_once()
2981 new X[id-01] file.txt
2982 call setline(1, 'some text to search for')
2983 vimgrep text %
2984 bwipe!
2985endfunc
2986
Bram Moolenaar1c299432018-10-28 14:36:09 +01002987" Test for incsearch highlighting of the :vimgrep pattern
2988" This test used to cause "E315: ml_get: invalid lnum" errors.
2989func Test_vimgrep_incsearch()
2990 enew
2991 set incsearch
2992 call test_override("char_avail", 1)
2993
2994 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2995 let l = getqflist()
2996 call assert_equal(2, len(l))
2997
2998 call test_override("ALL", 0)
2999 set noincsearch
3000endfunc
3001
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003002" Test vimgrep with the last search pattern not set
3003func Test_vimgrep_with_no_last_search_pat()
3004 let lines =<< trim [SCRIPT]
3005 call assert_fails('vimgrep // *', 'E35:')
3006 call writefile(v:errors, 'Xresult')
3007 qall!
3008 [SCRIPT]
3009 call writefile(lines, 'Xscript')
3010 if RunVim([], [], '--clean -S Xscript')
3011 call assert_equal([], readfile('Xresult'))
3012 endif
3013 call delete('Xscript')
3014 call delete('Xresult')
3015endfunc
3016
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02003017" Test vimgrep without swap file
3018func Test_vimgrep_without_swap_file()
3019 let lines =<< trim [SCRIPT]
3020 vimgrep grep test_c*
3021 call writefile(['done'], 'Xresult')
3022 qall!
3023 [SCRIPT]
3024 call writefile(lines, 'Xscript')
3025 if RunVim([], [], '--clean -n -S Xscript Xscript')
3026 call assert_equal(['done'], readfile('Xresult'))
3027 endif
3028 call delete('Xscript')
3029 call delete('Xresult')
3030endfunc
3031
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003032func Test_vimgrep_existing_swapfile()
3033 call writefile(['match apple with apple'], 'Xapple')
3034 call writefile(['swapfile'], '.Xapple.swp')
3035 let g:foundSwap = 0
3036 let g:ignoreSwapExists = 1
3037 augroup grep
3038 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
3039 augroup END
3040 vimgrep apple Xapple
3041 call assert_equal(1, g:foundSwap)
3042 call assert_match('.Xapple.swo', swapname(''))
3043
3044 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003045 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02003046 augroup grep
3047 au! SwapExists
3048 augroup END
3049 unlet g:ignoreSwapExists
3050endfunc
3051
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003052func XfreeTests(cchar)
3053 call s:setup_commands(a:cchar)
3054
3055 enew | only
3056
3057 " Deleting the quickfix stack should work even When the current list is
3058 " somewhere in the middle of the stack
3059 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3060 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3061 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3062 Xolder
3063 call g:Xsetlist([], 'f')
3064 call assert_equal(0, len(g:Xgetlist()))
3065
3066 " After deleting the stack, adding a new list should create a stack with a
3067 " single list.
3068 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3069 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3070
3071 " Deleting the stack from a quickfix window should update/clear the
3072 " quickfix/location list window.
3073 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3074 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3075 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3076 Xolder
3077 Xwindow
3078 call g:Xsetlist([], 'f')
3079 call assert_equal(2, winnr('$'))
3080 call assert_equal(1, line('$'))
3081 Xclose
3082
3083 " Deleting the stack from a non-quickfix window should update/clear the
3084 " quickfix/location list window.
3085 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3086 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3087 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3088 Xolder
3089 Xwindow
3090 wincmd p
3091 call g:Xsetlist([], 'f')
3092 call assert_equal(0, len(g:Xgetlist()))
3093 wincmd p
3094 call assert_equal(2, winnr('$'))
3095 call assert_equal(1, line('$'))
3096
3097 " After deleting the location list stack, if the location list window is
3098 " opened, then a new location list should be created. So opening the
3099 " location list window again should not create a new window.
3100 if a:cchar == 'l'
3101 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3102 wincmd p
3103 lopen
3104 call assert_equal(2, winnr('$'))
3105 endif
3106 Xclose
3107endfunc
3108
Bram Moolenaar74240d32017-12-10 15:26:15 +01003109" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003110func Test_qf_free()
3111 call XfreeTests('c')
3112 call XfreeTests('l')
3113endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003114
3115" Test for buffer overflow when parsing lines and adding new entries to
3116" the quickfix list.
3117func Test_bufoverflow()
3118 set efm=%f:%l:%m
3119 cgetexpr ['File1:100:' . repeat('x', 1025)]
3120
3121 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3122 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3123
3124 set efm=%DEntering\ directory\ %f,%f:%l:%m
3125 cgetexpr ['Entering directory ' . repeat('a', 1006),
3126 \ 'File1:10:Hello World']
3127 set efm&vim
3128endfunc
3129
Bram Moolenaar875feea2017-06-11 16:07:51 +02003130" Tests for getting the quickfix stack size
3131func XsizeTests(cchar)
3132 call s:setup_commands(a:cchar)
3133
3134 call g:Xsetlist([], 'f')
3135 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003136 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3137 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003138
3139 Xexpr "File1:10:Line1"
3140 Xexpr "File2:20:Line2"
3141 Xexpr "File3:30:Line3"
3142 Xolder | Xolder
3143 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3144 call g:Xsetlist([], 'f')
3145
3146 Xexpr "File1:10:Line1"
3147 Xexpr "File2:20:Line2"
3148 Xexpr "File3:30:Line3"
3149 Xolder | Xolder
3150 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3151 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3152endfunc
3153
3154func Test_Qf_Size()
3155 call XsizeTests('c')
3156 call XsizeTests('l')
3157endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003158
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003159func Test_cclose_from_copen()
3160 augroup QF_Test
3161 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003162 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003163 augroup END
3164 copen
3165 augroup QF_Test
3166 au!
3167 augroup END
3168 augroup! QF_Test
3169endfunc
3170
Bram Moolenaar18141832017-06-25 21:17:25 +02003171func Test_cclose_in_autocmd()
3172 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3173 " event will be triggered.
3174 call test_override('starting', 1)
3175 augroup QF_Test
3176 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003177 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003178 augroup END
3179 copen
3180 augroup QF_Test
3181 au!
3182 augroup END
3183 augroup! QF_Test
3184 call test_override('starting', 0)
3185endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003186
Bram Moolenaar379fb762018-08-30 15:58:28 +02003187" Check that ":file" without an argument is possible even when "curbuf_lock"
3188" is set.
3189func Test_file_from_copen()
3190 " Works without argument.
3191 augroup QF_Test
3192 au!
3193 au FileType qf file
3194 augroup END
3195 copen
3196
3197 augroup QF_Test
3198 au!
3199 augroup END
3200 cclose
3201
3202 " Fails with argument.
3203 augroup QF_Test
3204 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003205 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003206 augroup END
3207 copen
3208 augroup QF_Test
3209 au!
3210 augroup END
3211 cclose
3212
3213 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003214endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003215
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003216func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003217 augroup QF_Test
3218 au!
3219 au FileType qf resize 5
3220 augroup END
3221 try
3222 " This should succeed without any exception. No other buffers are
3223 " involved in the autocmd.
3224 copen
3225 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003226 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003227 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003228 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003229 augroup! QF_Test
3230 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003231endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003232
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003233func Test_vimgrep_with_textlock()
3234 new
3235
3236 " Simple way to execute something with "textwinlock" set.
3237 " Check that vimgrep without jumping can be executed.
3238 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3239 normal ax
3240 let qflist = getqflist()
3241 call assert_true(len(qflist) > 0)
3242 call assert_match('RunTheTest', qflist[0].text)
3243 call setqflist([], 'r')
3244 au! InsertCharPre
3245
3246 " Check that vimgrepadd without jumping can be executed.
3247 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3248 normal ax
3249 let qflist = getqflist()
3250 call assert_true(len(qflist) > 0)
3251 call assert_match('RunTheTest', qflist[0].text)
3252 call setqflist([], 'r')
3253 au! InsertCharPre
3254
3255 " Check that lvimgrep without jumping can be executed.
3256 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3257 normal ax
3258 let qflist = getloclist(0)
3259 call assert_true(len(qflist) > 0)
3260 call assert_match('RunTheTest', qflist[0].text)
3261 call setloclist(0, [], 'r')
3262 au! InsertCharPre
3263
3264 " Check that lvimgrepadd without jumping can be executed.
3265 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3266 normal ax
3267 let qflist = getloclist(0)
3268 call assert_true(len(qflist) > 0)
3269 call assert_match('RunTheTest', qflist[0].text)
3270 call setloclist(0, [], 'r')
3271 au! InsertCharPre
3272
3273 " trying to jump will give an error
3274 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3275 call assert_fails('normal ax', 'E565:')
3276 au! InsertCharPre
3277
3278 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3279 call assert_fails('normal ax', 'E565:')
3280 au! InsertCharPre
3281
3282 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3283 call assert_fails('normal ax', 'E565:')
3284 au! InsertCharPre
3285
3286 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3287 call assert_fails('normal ax', 'E565:')
3288 au! InsertCharPre
3289
3290 bwipe!
3291endfunc
3292
Bram Moolenaara8788f42017-07-19 17:06:20 +02003293" Tests for the quickfix buffer b:changedtick variable
3294func Xchangedtick_tests(cchar)
3295 call s:setup_commands(a:cchar)
3296
3297 new | only
3298
3299 Xexpr "" | Xexpr "" | Xexpr ""
3300
3301 Xopen
3302 Xolder
3303 Xolder
3304 Xaddexpr "F1:10:Line10"
3305 Xaddexpr "F2:20:Line20"
3306 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3307 call g:Xsetlist([], 'f')
3308 call assert_equal(8, getbufvar('%', 'changedtick'))
3309 Xclose
3310endfunc
3311
3312func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003313 call Xchangedtick_tests('c')
3314 call Xchangedtick_tests('l')
3315endfunc
3316
3317" Tests for parsing an expression using setqflist()
3318func Xsetexpr_tests(cchar)
3319 call s:setup_commands(a:cchar)
3320
3321 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003322 call g:Xsetlist([], ' ', {'lines' : t})
3323 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003324
3325 let l = g:Xgetlist()
3326 call assert_equal(3, len(l))
3327 call assert_equal(20, l[1].lnum)
3328 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003329 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003330 let l = g:Xgetlist()
3331 call assert_equal(1, len(l))
3332 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003333 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3334 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003335
3336 call g:Xsetlist([], 'f')
3337 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003338 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3339 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3340 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3341 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003342 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3343 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003344
3345 " Adding entries using a custom efm
3346 set efm&
3347 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3348 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3349 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3350 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3351 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3352 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3353 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3354 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003355endfunc
3356
3357func Test_setexpr()
3358 call Xsetexpr_tests('c')
3359 call Xsetexpr_tests('l')
3360endfunc
3361
3362" Tests for per quickfix/location list directory stack
3363func Xmultidirstack_tests(cchar)
3364 call s:setup_commands(a:cchar)
3365
3366 call g:Xsetlist([], 'f')
3367 Xexpr "" | Xexpr ""
3368
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003369 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3370 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3371 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3372 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003373
3374 let l1 = g:Xgetlist({'nr':1, 'items':1})
3375 let l2 = g:Xgetlist({'nr':2, 'items':1})
3376 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3377 call assert_equal(3, l1.items[1].lnum)
3378 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3379 call assert_equal(5, l2.items[1].lnum)
3380endfunc
3381
3382func Test_multidirstack()
3383 call mkdir('Xone/a', 'p')
3384 call mkdir('Xtwo/a', 'p')
3385 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3386 call writefile(lines, 'Xone/a/one.txt')
3387 call writefile(lines, 'Xtwo/a/two.txt')
3388 let save_efm = &efm
3389 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3390
3391 call Xmultidirstack_tests('c')
3392 call Xmultidirstack_tests('l')
3393
3394 let &efm = save_efm
3395 call delete('Xone', 'rf')
3396 call delete('Xtwo', 'rf')
3397endfunc
3398
3399" Tests for per quickfix/location list file stack
3400func Xmultifilestack_tests(cchar)
3401 call s:setup_commands(a:cchar)
3402
3403 call g:Xsetlist([], 'f')
3404 Xexpr "" | Xexpr ""
3405
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003406 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3407 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3408 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3409 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003410
3411 let l1 = g:Xgetlist({'nr':1, 'items':1})
3412 let l2 = g:Xgetlist({'nr':2, 'items':1})
3413 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3414 call assert_equal(3, l1.items[1].lnum)
3415 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3416 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003417
3418 " Test for start of a new error line in the same line where a previous
3419 " error line ends with a file stack.
3420 let efm_val = 'Error\ l%l\ in\ %f,'
3421 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3422 let l = g:Xgetlist({'lines' : [
3423 \ '(one.txt',
3424 \ 'Error l4 in one.txt',
3425 \ ') (two.txt',
3426 \ 'Error l6 in two.txt',
3427 \ ')',
3428 \ 'Error l8 in one.txt'
3429 \ ], 'efm' : efm_val})
3430 call assert_equal(3, len(l.items))
3431 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3432 call assert_equal(4, l.items[0].lnum)
3433 call assert_equal('one.txt', l.items[0].text)
3434 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3435 call assert_equal(6, l.items[1].lnum)
3436 call assert_equal('two.txt', l.items[1].text)
3437 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3438 call assert_equal(8, l.items[2].lnum)
3439 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003440endfunc
3441
3442func Test_multifilestack()
3443 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3444 call writefile(lines, 'one.txt')
3445 call writefile(lines, 'two.txt')
3446 let save_efm = &efm
3447 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3448
3449 call Xmultifilestack_tests('c')
3450 call Xmultifilestack_tests('l')
3451
3452 let &efm = save_efm
3453 call delete('one.txt')
3454 call delete('two.txt')
3455endfunc
3456
3457" Tests for per buffer 'efm' setting
3458func Test_perbuf_efm()
3459 call writefile(["File1-10-Line10"], 'one.txt')
3460 call writefile(["File2#20#Line20"], 'two.txt')
3461 set efm=%f#%l#%m
3462 new | only
3463 new
3464 setlocal efm=%f-%l-%m
3465 cfile one.txt
3466 wincmd w
3467 caddfile two.txt
3468
3469 let l = getqflist()
3470 call assert_equal(10, l[0].lnum)
3471 call assert_equal('Line20', l[1].text)
3472
3473 set efm&
3474 new | only
3475 call delete('one.txt')
3476 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003477endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003478
3479" Open multiple help windows using ":lhelpgrep
3480" This test used to crash Vim
3481func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003482 new | only
3483 lhelpgrep window
3484 lopen
3485 e#
3486 lhelpgrep buffer
3487 call assert_equal(3, winnr('$'))
3488 call assert_true(len(getloclist(1)) != 0)
3489 call assert_true(len(getloclist(2)) != 0)
3490 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003491endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003492
3493" Tests for adding new quickfix lists using setqflist()
3494func XaddQf_tests(cchar)
3495 call s:setup_commands(a:cchar)
3496
3497 " Create a new list using ' ' for action
3498 call g:Xsetlist([], 'f')
3499 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3500 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3501 call assert_equal(1, l.nr)
3502 call assert_equal('Test1', l.title)
3503
3504 " Create a new list using ' ' for action and '$' for 'nr'
3505 call g:Xsetlist([], 'f')
3506 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3507 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3508 call assert_equal(1, l.nr)
3509 call assert_equal('Test2', l.title)
3510
3511 " Create a new list using 'a' for action
3512 call g:Xsetlist([], 'f')
3513 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3514 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3515 call assert_equal(1, l.nr)
3516 call assert_equal('Test3', l.title)
3517
3518 " Create a new list using 'a' for action and '$' for 'nr'
3519 call g:Xsetlist([], 'f')
3520 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3521 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3522 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3523 call assert_equal(1, l.nr)
3524 call assert_equal('Test4', l.title)
3525
3526 " Adding a quickfix list should remove all the lists following the current
3527 " list.
3528 Xexpr "" | Xexpr "" | Xexpr ""
3529 silent! 10Xolder
3530 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3531 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3532 call assert_equal(2, l.nr)
3533 call assert_equal('Test5', l.title)
3534
3535 " Add a quickfix list using '$' as the list number.
3536 let lastqf = g:Xgetlist({'nr':'$'}).nr
3537 silent! 99Xolder
3538 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3539 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3540 call assert_equal(lastqf + 1, l.nr)
3541 call assert_equal('Test6', l.title)
3542
3543 " Add a quickfix list using 'nr' set to one more than the quickfix
3544 " list size.
3545 let lastqf = g:Xgetlist({'nr':'$'}).nr
3546 silent! 99Xolder
3547 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3548 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3549 call assert_equal(lastqf + 1, l.nr)
3550 call assert_equal('Test7', l.title)
3551
3552 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3553 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3554 silent! 99Xolder
3555 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3556 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3557 call assert_equal(10, l.nr)
3558 call assert_equal('Test8', l.title)
3559
3560 " Add a quickfix list using 'nr' set to a value greater than 10
3561 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3562
3563 " Try adding a quickfix list with 'nr' set to a value greater than the
3564 " quickfix list size but less than 10.
3565 call g:Xsetlist([], 'f')
3566 Xexpr "" | Xexpr "" | Xexpr ""
3567 silent! 99Xolder
3568 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3569
3570 " Add a quickfix list using 'nr' set to a some string or list
3571 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3572endfunc
3573
3574func Test_add_qf()
3575 call XaddQf_tests('c')
3576 call XaddQf_tests('l')
3577endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003578
3579" Test for getting the quickfix list items from some text without modifying
3580" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003581func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003582 call s:setup_commands(a:cchar)
3583 call g:Xsetlist([], 'f')
3584
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003585 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003586 call assert_equal(2, len(l))
3587 call assert_equal(30, l[1].lnum)
3588
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003589 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3590 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3591 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3592 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003593
Bram Moolenaar36538222017-09-02 19:51:44 +02003594 " Parse text using a custom efm
3595 set efm&
3596 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3597 call assert_equal('Line30', l[0].text)
3598 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3599 call assert_equal('File3:30:Line30', l[0].text)
3600 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3601 call assert_equal({}, l)
3602 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3603 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3604
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003605 " Make sure that the quickfix stack is not modified
3606 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3607endfunc
3608
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003609func Test_get_list_from_lines()
3610 call XgetListFromLines('c')
3611 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003612endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003613
3614" Tests for the quickfix list id
3615func Xqfid_tests(cchar)
3616 call s:setup_commands(a:cchar)
3617
3618 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003619 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003620 Xexpr ''
3621 let start_id = g:Xgetlist({'id' : 0}).id
3622 Xexpr '' | Xexpr ''
3623 Xolder
3624 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3625 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3626 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003627 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003628 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003629 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3630 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003631
3632 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3633 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003634 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003635 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3636 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3637 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3638
3639 let qfid = g:Xgetlist({'id':0, 'nr':0})
3640 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003641 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003642endfunc
3643
3644func Test_qf_id()
3645 call Xqfid_tests('c')
3646 call Xqfid_tests('l')
3647endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003648
3649func Xqfjump_tests(cchar)
3650 call s:setup_commands(a:cchar)
3651
3652 call writefile(["Line1\tFoo", "Line2"], 'F1')
3653 call writefile(["Line1\tBar", "Line2"], 'F2')
3654 call writefile(["Line1\tBaz", "Line2"], 'F3')
3655
3656 call g:Xsetlist([], 'f')
3657
3658 " Tests for
3659 " Jumping to a line using a pattern
3660 " Jumping to a column greater than the last column in a line
3661 " Jumping to a line greater than the last line in the file
3662 let l = []
3663 for i in range(1, 7)
3664 call add(l, {})
3665 endfor
3666 let l[0].filename='F1'
3667 let l[0].pattern='Line1'
3668 let l[1].filename='F2'
3669 let l[1].pattern='Line1'
3670 let l[2].filename='F3'
3671 let l[2].pattern='Line1'
3672 let l[3].filename='F3'
3673 let l[3].lnum=1
3674 let l[3].col=9
3675 let l[3].vcol=1
3676 let l[4].filename='F3'
3677 let l[4].lnum=99
3678 let l[5].filename='F3'
3679 let l[5].lnum=1
3680 let l[5].col=99
3681 let l[5].vcol=1
3682 let l[6].filename='F3'
3683 let l[6].pattern='abcxyz'
3684
3685 call g:Xsetlist([], ' ', {'items' : l})
3686 Xopen | only
3687 2Xnext
3688 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003689 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003690 Xnext
3691 call assert_equal(7, col('.'))
3692 Xnext
3693 call assert_equal(2, line('.'))
3694 Xnext
3695 call assert_equal(9, col('.'))
3696 2
3697 Xnext
3698 call assert_equal(2, line('.'))
3699
3700 if a:cchar == 'l'
3701 " When jumping to a location list entry in the location list window and
3702 " no usable windows are available, then a new window should be opened.
3703 enew! | new | only
3704 call g:Xsetlist([], 'f')
3705 setlocal buftype=nofile
3706 new
3707 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']})
3708 Xopen
3709 let winid = win_getid()
3710 wincmd p
3711 close
3712 call win_gotoid(winid)
3713 Xnext
3714 call assert_equal(3, winnr('$'))
3715 call assert_equal(1, winnr())
3716 call assert_equal(2, line('.'))
3717
3718 " When jumping to an entry in the location list window and the window
3719 " associated with the location list is not present and a window containing
3720 " the file is already present, then that window should be used.
3721 close
3722 belowright new
3723 call g:Xsetlist([], 'f')
3724 edit F3
3725 call win_gotoid(winid)
3726 Xlast
3727 call assert_equal(3, winnr())
3728 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3729 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3730 endif
3731
3732 " Cleanup
3733 enew!
3734 new | only
3735
3736 call delete('F1')
3737 call delete('F2')
3738 call delete('F3')
3739endfunc
3740
3741func Test_qfjump()
3742 call Xqfjump_tests('c')
3743 call Xqfjump_tests('l')
3744endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003745
3746" Tests for the getqflist() and getloclist() functions when the list is not
3747" present or is empty
3748func Xgetlist_empty_tests(cchar)
3749 call s:setup_commands(a:cchar)
3750
3751 " Empty quickfix stack
3752 call g:Xsetlist([], 'f')
3753 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3754 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3755 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3756 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3757 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3758 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3759 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3760 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003761 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003762 if a:cchar == 'c'
3763 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003764 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003765 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3766 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003767 else
3768 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3769 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003770 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003771 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003772 \ g:Xgetlist({'all' : 0}))
3773 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003774
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003775 " Quickfix window with empty stack
3776 silent! Xopen
3777 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003778 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003779 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3780 Xclose
3781
Bram Moolenaara6d48492017-12-12 22:45:31 +01003782 " Empty quickfix list
3783 Xexpr ""
3784 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3785 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3786 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3787 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3788 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3789 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3790 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3791 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003792 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003793
3794 let qfid = g:Xgetlist({'id' : 0}).id
3795 call g:Xsetlist([], 'f')
3796
3797 " Non-existing quickfix identifier
3798 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3799 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3800 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3801 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3802 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3803 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3804 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3805 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003806 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003807 if a:cchar == 'c'
3808 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3809 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003810 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003811 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3812 else
3813 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3814 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003815 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3816 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003817 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3818 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003819
3820 " Non-existing quickfix list number
3821 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3822 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3823 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3824 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3825 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3826 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3827 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3828 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003829 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003830 if a:cchar == 'c'
3831 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3832 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003833 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3834 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003835 else
3836 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3837 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003838 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3839 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003840 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003841endfunc
3842
3843func Test_getqflist()
3844 call Xgetlist_empty_tests('c')
3845 call Xgetlist_empty_tests('l')
3846endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003847
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003848func Test_getqflist_invalid_nr()
3849 " The following commands used to crash Vim
3850 cexpr ""
3851 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3852
3853 " Cleanup
3854 call setqflist([], 'r')
3855endfunc
3856
Bram Moolenaarb254af32017-12-18 19:48:58 +01003857" Tests for the quickfix/location list changedtick
3858func Xqftick_tests(cchar)
3859 call s:setup_commands(a:cchar)
3860
3861 call g:Xsetlist([], 'f')
3862
3863 Xexpr "F1:10:Line10"
3864 let qfid = g:Xgetlist({'id' : 0}).id
3865 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3866 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3867 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3868 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3869 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3870 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3871 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3872 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3873 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3874
3875 enew!
3876 call append(0, ["F5:50:L50", "F6:60:L60"])
3877 Xaddbuffer
3878 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3879 enew!
3880
3881 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3882 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3883 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3884 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3885 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3886 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3887 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3888 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3889 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3890 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3891 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3892
3893 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3894 Xfile Xone
3895 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3896 Xaddfile Xone
3897 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3898
3899 " Test case for updating a non-current quickfix list
3900 call g:Xsetlist([], 'f')
3901 Xexpr "F1:1:L1"
3902 Xexpr "F2:2:L2"
3903 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3904 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3905 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3906
3907 call delete("Xone")
3908endfunc
3909
3910func Test_qf_tick()
3911 call Xqftick_tests('c')
3912 call Xqftick_tests('l')
3913endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003914
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003915" Test helpgrep with lang specifier
3916func Xtest_helpgrep_with_lang_specifier(cchar)
3917 call s:setup_commands(a:cchar)
3918 Xhelpgrep Vim@en
3919 call assert_equal('help', &filetype)
3920 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3921 new | only
3922endfunc
3923
3924func Test_helpgrep_with_lang_specifier()
3925 call Xtest_helpgrep_with_lang_specifier('c')
3926 call Xtest_helpgrep_with_lang_specifier('l')
3927endfunc
3928
Bram Moolenaar12237442017-12-19 12:38:52 +01003929" The following test used to crash Vim.
3930" Open the location list window and close the regular window associated with
3931" the location list. When the garbage collection runs now, it incorrectly
3932" marks the location list context as not in use and frees the context.
3933func Test_ll_window_ctx()
3934 call setloclist(0, [], 'f')
3935 call setloclist(0, [], 'a', {'context' : []})
3936 lopen | only
3937 call test_garbagecollect_now()
3938 echo getloclist(0, {'context' : 1}).context
3939 enew | only
3940endfunc
3941
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003942" The following test used to crash vim
3943func Test_lfile_crash()
3944 sp Xtest
3945 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003946 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003947 au! QuickFixCmdPre
3948endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003949
3950" The following test used to crash vim
3951func Test_lbuffer_crash()
3952 sv Xtest
3953 augroup QF_Test
3954 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003955 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003956 augroup END
3957 lbuffer
3958 augroup QF_Test
3959 au!
3960 augroup END
3961endfunc
3962
3963" The following test used to crash vim
3964func Test_lexpr_crash()
3965 augroup QF_Test
3966 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003967 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003968 augroup END
3969 lexpr ""
3970 augroup QF_Test
3971 au!
3972 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003973
Bram Moolenaar3c097222017-12-21 20:54:49 +01003974 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003975 augroup QF_Test
3976 au!
3977 au BufNew * call setloclist(0, [], 'f')
3978 augroup END
3979 lexpr 'x:1:x'
3980 augroup QF_Test
3981 au!
3982 augroup END
3983
3984 enew | only
3985 lexpr ''
3986 lopen
3987 augroup QF_Test
3988 au!
3989 au FileType * call setloclist(0, [], 'f')
3990 augroup END
3991 lexpr ''
3992 augroup QF_Test
3993 au!
3994 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003995endfunc
3996
3997" The following test used to crash Vim
3998func Test_lvimgrep_crash()
3999 sv Xtest
4000 augroup QF_Test
4001 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004002 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01004003 augroup END
4004 lvimgrep quickfix test_quickfix.vim
4005 augroup QF_Test
4006 au!
4007 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004008
4009 new | only
4010 augroup QF_Test
4011 au!
4012 au BufEnter * call setloclist(0, [], 'r')
4013 augroup END
4014 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
4015 augroup QF_Test
4016 au!
4017 augroup END
4018
Bram Moolenaar3c097222017-12-21 20:54:49 +01004019 enew | only
4020endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01004021
Bram Moolenaar2573af32020-03-14 17:21:34 +01004022func Test_lvimgrep_crash2()
4023 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02004024 call assert_fails('lvimgrep x x', 'E471:')
4025 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01004026
4027 au! BufNewFile
4028endfunc
4029
Bram Moolenaarde046542017-12-26 13:53:11 +01004030" Test for the position of the quickfix and location list window
4031func Test_qfwin_pos()
4032 " Open two windows
4033 new | only
4034 new
4035 cexpr ['F1:10:L10']
4036 copen
4037 " Quickfix window should be the bottom most window
4038 call assert_equal(3, winnr())
4039 close
4040 " Open at the very top
4041 wincmd t
4042 topleft copen
4043 call assert_equal(1, winnr())
4044 close
4045 " open left of the current window
4046 wincmd t
4047 below new
4048 leftabove copen
4049 call assert_equal(2, winnr())
4050 close
4051 " open right of the current window
4052 rightbelow copen
4053 call assert_equal(3, winnr())
4054 close
4055endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004056
4057" Tests for quickfix/location lists changed by autocommands when
4058" :vimgrep/:lvimgrep commands are running.
4059func Test_vimgrep_autocmd()
4060 call setqflist([], 'f')
4061 call writefile(['stars'], 'Xtest1.txt')
4062 call writefile(['stars'], 'Xtest2.txt')
4063
4064 " Test 1:
4065 " When searching for a pattern using :vimgrep, if the quickfix list is
4066 " changed by an autocmd, the results should be added to the correct quickfix
4067 " list.
4068 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4069 silent vimgrep stars Xtest*.txt
4070 call assert_equal(1, getqflist({'nr' : 0}).nr)
4071 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4072 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4073 au! BufRead Xtest2.txt
4074
4075 " Test 2:
4076 " When searching for a pattern using :vimgrep, if the quickfix list is
4077 " freed, then a error should be given.
4078 silent! %bwipe!
4079 call setqflist([], 'f')
4080 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4081 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4082 au! BufRead Xtest2.txt
4083
4084 " Test 3:
4085 " When searching for a pattern using :lvimgrep, if the location list is
4086 " freed, then the command should error out.
4087 silent! %bwipe!
4088 let g:save_winid = win_getid()
4089 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4090 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4091 au! BufRead Xtest2.txt
4092
4093 call delete('Xtest1.txt')
4094 call delete('Xtest2.txt')
4095 call setqflist([], 'f')
4096endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004097
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004098" Test for an autocmd changing the current directory when running vimgrep
4099func Xvimgrep_autocmd_cd(cchar)
4100 call s:setup_commands(a:cchar)
4101
4102 %bwipe
4103 let save_cwd = getcwd()
4104
4105 augroup QF_Test
4106 au!
4107 autocmd BufRead * silent cd %:p:h
4108 augroup END
4109
4110 10Xvimgrep /vim/ Xdir/**
4111 let l = g:Xgetlist()
4112 call assert_equal('f1.txt', bufname(l[0].bufnr))
4113 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4114
4115 augroup QF_Test
4116 au!
4117 augroup END
4118
4119 exe 'cd ' . save_cwd
4120endfunc
4121
4122func Test_vimgrep_autocmd_cd()
4123 call mkdir('Xdir/a', 'p')
4124 call mkdir('Xdir/b', 'p')
4125 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4126 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4127 call Xvimgrep_autocmd_cd('c')
4128 call Xvimgrep_autocmd_cd('l')
4129 %bwipe
4130 call delete('Xdir', 'rf')
4131endfunc
4132
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004133" The following test used to crash Vim
4134func Test_lhelpgrep_autocmd()
4135 lhelpgrep quickfix
4136 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4137 lhelpgrep buffer
4138 call assert_equal('help', &filetype)
4139 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4140 lhelpgrep tabpage
4141 call assert_equal('help', &filetype)
4142 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4143 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004144
4145 new | only
4146 augroup QF_Test
4147 au!
4148 au BufEnter * call setqflist([], 'f')
4149 augroup END
4150 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004151 " run the test with a help window already open
4152 help
4153 wincmd w
4154 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004155 augroup QF_Test
4156 au! BufEnter
4157 augroup END
4158
4159 new | only
4160 augroup QF_Test
4161 au!
4162 au BufEnter * call setqflist([], 'r')
4163 augroup END
4164 call assert_fails('helpgrep quickfix', 'E925:')
4165 augroup QF_Test
4166 au! BufEnter
4167 augroup END
4168
4169 new | only
4170 augroup QF_Test
4171 au!
4172 au BufEnter * call setloclist(0, [], 'r')
4173 augroup END
4174 call assert_fails('lhelpgrep quickfix', 'E926:')
4175 augroup QF_Test
4176 au! BufEnter
4177 augroup END
4178
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004179 new | only
4180endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004181
4182" Test for shortening/simplifying the file name when opening the
4183" quickfix window or when displaying the quickfix list
4184func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004185 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004186 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004187 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004188 let fname = getcwd() . '/test_quickfix.vim'
4189 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4190 call assert_equal(fname, bufname('test_quickfix.vim'))
4191 " Opening the quickfix window should simplify the file path
4192 cwindow
4193 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4194 cclose
4195 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004196 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004197 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4198 call assert_equal(fname, bufname('test_quickfix.vim'))
4199 " Displaying the quickfix list should simplify the file path
4200 silent! clist
4201 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004202 " Add a few entries for the same file with different paths and check whether
4203 " the buffer name is shortened
4204 %bwipe
4205 call setqflist([], 'f')
4206 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4207 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4208 \ {'filename' : fname, 'lnum' : 30}], ' ')
4209 copen
4210 call assert_equal(['test_quickfix.vim|10| ',
4211 \ 'test_quickfix.vim|20| ',
4212 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4213 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004214endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004215
4216" Quickfix title tests
4217" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4218" Otherwise due to indentation, the title is set with spaces at the beginning
4219" of the command.
4220func Test_qftitle()
4221 call writefile(["F1:1:Line1"], 'Xerr')
4222
4223 " :cexpr
4224 exe "cexpr readfile('Xerr')"
4225 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4226
4227 " :cgetexpr
4228 exe "cgetexpr readfile('Xerr')"
4229 call assert_equal(":cgetexpr readfile('Xerr')",
4230 \ getqflist({'title' : 1}).title)
4231
4232 " :caddexpr
4233 call setqflist([], 'f')
4234 exe "caddexpr readfile('Xerr')"
4235 call assert_equal(":caddexpr readfile('Xerr')",
4236 \ getqflist({'title' : 1}).title)
4237
4238 " :cbuffer
4239 new Xerr
4240 exe "cbuffer"
4241 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4242
4243 " :cgetbuffer
4244 edit Xerr
4245 exe "cgetbuffer"
4246 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4247
4248 " :caddbuffer
4249 call setqflist([], 'f')
4250 edit Xerr
4251 exe "caddbuffer"
4252 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4253
4254 " :cfile
4255 exe "cfile Xerr"
4256 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4257
4258 " :cgetfile
4259 exe "cgetfile Xerr"
4260 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4261
4262 " :caddfile
4263 call setqflist([], 'f')
4264 exe "caddfile Xerr"
4265 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4266
4267 " :grep
4268 set grepprg=internal
4269 exe "grep F1 Xerr"
4270 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4271
4272 " :grepadd
4273 call setqflist([], 'f')
4274 exe "grepadd F1 Xerr"
4275 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4276 set grepprg&vim
4277
4278 " :vimgrep
4279 exe "vimgrep F1 Xerr"
4280 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4281
4282 " :vimgrepadd
4283 call setqflist([], 'f')
4284 exe "vimgrepadd F1 Xerr"
4285 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4286
4287 call setqflist(['F1:10:L10'], ' ')
4288 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4289
4290 call setqflist([], 'f')
4291 call setqflist(['F1:10:L10'], 'a')
4292 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4293
4294 call setqflist([], 'f')
4295 call setqflist(['F1:10:L10'], 'r')
4296 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4297
4298 close
4299 call delete('Xerr')
4300
4301 call setqflist([], ' ', {'title' : 'Errors'})
4302 copen
4303 call assert_equal('Errors', w:quickfix_title)
4304 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4305 call assert_equal('Errors', w:quickfix_title)
4306 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004307
4308 " Switching to another quickfix list in one tab page should update the
4309 " quickfix window title and statusline in all the other tab pages also
4310 call setqflist([], 'f')
4311 %bw!
4312 cgetexpr ['file_one:1:1: error in the first quickfix list']
4313 call setqflist([], 'a', {'title': 'first quickfix list'})
4314 cgetexpr ['file_two:2:1: error in the second quickfix list']
4315 call setqflist([], 'a', {'title': 'second quickfix list'})
4316 copen
4317 wincmd t
4318 tabnew two
4319 copen
4320 wincmd t
4321 colder
4322 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4323 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4324 call assert_equal(1, tabpagewinnr(1))
4325 call assert_equal(1, tabpagewinnr(2))
4326 tabnew
4327 call setqflist([], 'a', {'title': 'new quickfix title'})
4328 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4329 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4330 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004331endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004332
4333func Test_lbuffer_with_bwipe()
4334 new
4335 new
4336 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004337 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004338 augroup END
4339 lbuffer
4340 augroup nasty
4341 au!
4342 augroup END
4343endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004344
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004345" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4346" running
4347func Xexpr_acmd_freelist(cchar)
4348 call s:setup_commands(a:cchar)
4349
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004350 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004351 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004352 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004353 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004354 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004355 augroup nasty
4356 au!
4357 augroup END
4358endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004359
4360func Test_cexpr_acmd_freelist()
4361 call Xexpr_acmd_freelist('c')
4362 call Xexpr_acmd_freelist('l')
4363endfunc
4364
4365" Test for commands that create a new quickfix/location list and jump to the
4366" first error automatically.
4367func Xjumpto_first_error_test(cchar)
4368 call s:setup_commands(a:cchar)
4369
4370 call s:create_test_file('Xtestfile1')
4371 call s:create_test_file('Xtestfile2')
4372 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4373
4374 " Test for cexpr/lexpr
4375 enew
4376 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004377 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004378 call assert_equal(2, line('.'))
4379
4380 " Test for cfile/lfile
4381 enew
4382 call writefile(l, 'Xerr')
4383 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004384 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004385 call assert_equal(2, line('.'))
4386
4387 " Test for cbuffer/lbuffer
4388 edit Xerr
4389 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004390 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004391 call assert_equal(2, line('.'))
4392
4393 call delete('Xerr')
4394 call delete('Xtestfile1')
4395 call delete('Xtestfile2')
4396endfunc
4397
4398func Test_jumpto_first_error()
4399 call Xjumpto_first_error_test('c')
4400 call Xjumpto_first_error_test('l')
4401endfunc
4402
4403" Test for a quickfix autocmd changing the quickfix/location list before
4404" jumping to the first error in the new list.
4405func Xautocmd_changelist(cchar)
4406 call s:setup_commands(a:cchar)
4407
4408 " Test for cfile/lfile
4409 call s:create_test_file('Xtestfile1')
4410 call s:create_test_file('Xtestfile2')
4411 Xexpr 'Xtestfile1:2:Line2'
4412 autocmd QuickFixCmdPost * Xolder
4413 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4414 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004415 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004416 call assert_equal(4, line('.'))
4417 autocmd! QuickFixCmdPost
4418
4419 " Test for cbuffer/lbuffer
4420 call g:Xsetlist([], 'f')
4421 Xexpr 'Xtestfile1:2:Line2'
4422 autocmd QuickFixCmdPost * Xolder
4423 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4424 edit Xerr
4425 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004426 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004427 call assert_equal(4, line('.'))
4428 autocmd! QuickFixCmdPost
4429
4430 " Test for cexpr/lexpr
4431 call g:Xsetlist([], 'f')
4432 Xexpr 'Xtestfile1:2:Line2'
4433 autocmd QuickFixCmdPost * Xolder
4434 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004435 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004436 call assert_equal(4, line('.'))
4437 autocmd! QuickFixCmdPost
4438
Bram Moolenaar851332e2018-07-03 19:16:00 +02004439 " The grepprg may not be set on non-Unix systems
4440 if has('unix')
4441 " Test for grep/lgrep
4442 call g:Xsetlist([], 'f')
4443 Xexpr 'Xtestfile1:2:Line2'
4444 autocmd QuickFixCmdPost * Xolder
4445 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004446 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004447 call assert_equal(5, line('.'))
4448 autocmd! QuickFixCmdPost
4449 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004450
4451 " Test for vimgrep/lvimgrep
4452 call g:Xsetlist([], 'f')
4453 Xexpr 'Xtestfile1:2:Line2'
4454 autocmd QuickFixCmdPost * Xolder
4455 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004456 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004457 call assert_equal(5, line('.'))
4458 autocmd! QuickFixCmdPost
4459
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004460 " Test for autocommands clearing the quickfix list before jumping to the
4461 " first error. This should not result in an error
4462 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4463 let v:errmsg = ''
4464 " Test for cfile/lfile
4465 Xfile Xerr
4466 call assert_true(v:errmsg !~# 'E42:')
4467 " Test for cbuffer/lbuffer
4468 edit Xerr
4469 Xbuffer
4470 call assert_true(v:errmsg !~# 'E42:')
4471 " Test for cexpr/lexpr
4472 Xexpr 'Xtestfile2:4:Line4'
4473 call assert_true(v:errmsg !~# 'E42:')
4474 " Test for grep/lgrep
4475 " The grepprg may not be set on non-Unix systems
4476 if has('unix')
4477 silent Xgrep Line5 Xtestfile2
4478 call assert_true(v:errmsg !~# 'E42:')
4479 endif
4480 " Test for vimgrep/lvimgrep
4481 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4482 autocmd! QuickFixCmdPost
4483
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004484 call delete('Xerr')
4485 call delete('Xtestfile1')
4486 call delete('Xtestfile2')
4487endfunc
4488
4489func Test_autocmd_changelist()
4490 call Xautocmd_changelist('c')
4491 call Xautocmd_changelist('l')
4492endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004493
4494" Tests for the ':filter /pat/ clist' command
4495func Test_filter_clist()
4496 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4497 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4498 \ split(execute('filter /Line 15/ clist'), "\n"))
4499 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4500 \ split(execute('filter /Xfile1/ clist'), "\n"))
4501 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4502
4503 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4504 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4505 call assert_equal([' 2 pqr:pat2: '],
4506 \ split(execute('filter /pqr/ clist'), "\n"))
4507 call assert_equal([' 1 abc:pat1: '],
4508 \ split(execute('filter /pat1/ clist'), "\n"))
4509endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004510
4511" Tests for the "CTRL-W <CR>" command.
4512func Xview_result_split_tests(cchar)
4513 call s:setup_commands(a:cchar)
4514
4515 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4516 call g:Xsetlist([])
4517 Xopen
4518 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004519 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004520 call assert_equal(l:win_count, winnr('$'))
4521 Xclose
4522endfunc
4523
4524func Test_view_result_split()
4525 call Xview_result_split_tests('c')
4526 call Xview_result_split_tests('l')
4527endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004528
4529" Test that :cc sets curswant
4530func Test_curswant()
4531 helpgrep quickfix
4532 normal! llll
4533 1cc
4534 call assert_equal(getcurpos()[4], virtcol('.'))
4535 cclose | helpclose
4536endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004537
4538" Test for opening a file from the quickfix window using CTRL-W <Enter>
4539" doesn't leave an empty buffer around.
4540func Test_splitview()
4541 call s:create_test_file('Xtestfile1')
4542 call s:create_test_file('Xtestfile2')
4543 new | only
4544 let last_bufnr = bufnr('Test_sv_1', 1)
4545 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4546 cgetexpr l
4547 copen
4548 let numbufs = len(getbufinfo())
4549 exe "normal \<C-W>\<CR>"
4550 copen
4551 exe "normal j\<C-W>\<CR>"
4552 " Make sure new empty buffers are not created
4553 call assert_equal(numbufs, len(getbufinfo()))
4554 " Creating a new buffer should use the next available buffer number
4555 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4556 bwipe Test_sv_1
4557 bwipe Test_sv_2
4558 new | only
4559
4560 " When split opening files from location list window, make sure that two
4561 " windows doesn't refer to the same location list
4562 lgetexpr l
4563 let locid = getloclist(0, {'id' : 0}).id
4564 lopen
4565 exe "normal \<C-W>\<CR>"
4566 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4567 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4568 new | only
4569
4570 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004571 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004572 lhelpgrep window
4573 let locid = getloclist(0, {'id' : 0}).id
4574 lwindow
4575 exe "normal j\<C-W>\<CR>"
4576 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4577 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4578 new | only
4579
Bram Moolenaar406cd902020-02-18 21:54:41 +01004580 " Using :split or :vsplit from a quickfix window should behave like a :new
4581 " or a :vnew command
4582 copen
4583 split
4584 call assert_equal(3, winnr('$'))
4585 let l = getwininfo()
4586 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4587 close
4588 copen
4589 vsplit
4590 let l = getwininfo()
4591 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4592 new | only
4593
Bram Moolenaarb2443732018-11-11 22:50:27 +01004594 call delete('Xtestfile1')
4595 call delete('Xtestfile2')
4596endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004597
4598" Test for parsing entries using visual screen column
4599func Test_viscol()
4600 enew
4601 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4602 edit Xfile1
4603
4604 " Use byte offset for column number
4605 set efm&
4606 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4607 call assert_equal([5, 8], [col('.'), virtcol('.')])
4608 cnext
4609 call assert_equal([9, 12], [col('.'), virtcol('.')])
4610 cnext
4611 call assert_equal([14, 20], [col('.'), virtcol('.')])
4612
4613 " Use screen column offset for column number
4614 set efm=%f:%l:%v:%m
4615 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4616 call assert_equal([5, 8], [col('.'), virtcol('.')])
4617 cnext
4618 call assert_equal([9, 12], [col('.'), virtcol('.')])
4619 cnext
4620 call assert_equal([14, 20], [col('.'), virtcol('.')])
4621 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4622 call assert_equal([5, 8], [col('.'), virtcol('.')])
4623 cnext
4624 call assert_equal([10, 16], [col('.'), virtcol('.')])
4625 cnext
4626 call assert_equal([14, 20], [col('.'), virtcol('.')])
4627
4628 enew
4629 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4630
4631 " Use byte offset for column number
4632 set efm&
4633 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4634 call assert_equal([8, 10], [col('.'), virtcol('.')])
4635 cnext
4636 call assert_equal([11, 17], [col('.'), virtcol('.')])
4637 cnext
4638 call assert_equal([16, 25], [col('.'), virtcol('.')])
4639
4640 " Use screen column offset for column number
4641 set efm=%f:%l:%v:%m
4642 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4643 call assert_equal([8, 10], [col('.'), virtcol('.')])
4644 cnext
4645 call assert_equal([11, 17], [col('.'), virtcol('.')])
4646 cnext
4647 call assert_equal([16, 25], [col('.'), virtcol('.')])
4648
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004649 " Use screen column number with a multi-line error message
4650 enew
4651 call writefile(["à test"], 'Xfile1')
4652 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4653 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4654 call assert_equal('Xfile1', @%)
4655 call assert_equal([0, 1, 4, 0], getpos('.'))
4656
4657 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4658 " does not break this
4659 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4660 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4661 call assert_equal('Xfile1', @%)
4662 call assert_equal([0, 1, 3, 0], getpos('.'))
4663
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004664 enew | only
4665 set efm&
4666 call delete('Xfile1')
4667endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004668
4669" Test for the quickfix window buffer
4670func Xqfbuf_test(cchar)
4671 call s:setup_commands(a:cchar)
4672
4673 " Quickfix buffer should be reused across closing and opening a quickfix
4674 " window
4675 Xexpr "F1:10:Line10"
4676 Xopen
4677 let qfbnum = bufnr('')
4678 Xclose
4679 " Even after the quickfix window is closed, the buffer should be loaded
4680 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004681 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004682 Xopen
4683 " Buffer should be reused when opening the window again
4684 call assert_equal(qfbnum, bufnr(''))
4685 Xclose
4686
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004687 " When quickfix buffer is wiped out, getqflist() should return 0
4688 %bw!
4689 Xexpr ""
4690 Xopen
4691 bw!
4692 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4693
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004694 if a:cchar == 'l'
4695 %bwipe
4696 " For a location list, when both the file window and the location list
4697 " window for the list are closed, then the buffer should be freed.
4698 new | only
4699 lexpr "F1:10:Line10"
4700 let wid = win_getid()
4701 lopen
4702 let qfbnum = bufnr('')
4703 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4704 close
4705 " When the location list window is closed, the buffer name should not
4706 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004707 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004708 call assert_true(bufloaded(qfbnum))
4709
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004710 " After deleting a location list buffer using ":bdelete", opening the
4711 " location list window should mark the buffer as a location list buffer.
4712 exe "bdelete " . qfbnum
4713 lopen
4714 call assert_equal("quickfix", &buftype)
4715 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4716 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4717 call assert_false(&swapfile)
4718 lclose
4719
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004720 " When the location list is cleared for the window, the buffer should be
4721 " removed
4722 call setloclist(0, [], 'f')
4723 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004724 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004725
4726 " When the location list is freed with the location list window open, the
4727 " location list buffer should not be lost. It should be reused when the
4728 " location list is again populated.
4729 lexpr "F1:10:Line10"
4730 lopen
4731 let wid = win_getid()
4732 let qfbnum = bufnr('')
4733 wincmd p
4734 call setloclist(0, [], 'f')
4735 lexpr "F1:10:Line10"
4736 lopen
4737 call assert_equal(wid, win_getid())
4738 call assert_equal(qfbnum, bufnr(''))
4739 lclose
4740
4741 " When the window with the location list is closed, the buffer should be
4742 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004743 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004744 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004745 endif
4746endfunc
4747
4748func Test_qfbuf()
4749 call Xqfbuf_test('c')
4750 call Xqfbuf_test('l')
4751endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004752
4753" If there is an autocmd to use only one window, then opening the location
4754" list window used to crash Vim.
4755func Test_winonly_autocmd()
4756 call s:create_test_file('Xtest1')
4757 " Autocmd to show only one Vim window at a time
4758 autocmd WinEnter * only
4759 new
4760 " Load the location list
4761 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4762 let loclistid = getloclist(0, {'id' : 0}).id
4763 " Open the location list window. Only this window will be shown and the file
4764 " window is closed.
4765 lopen
4766 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4767 " Jump to an entry in the location list and make sure that the cursor is
4768 " positioned correctly.
4769 ll 3
4770 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004771 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004772 call assert_equal(15, line('.'))
4773 " Cleanup
4774 autocmd! WinEnter
4775 new | only
4776 call delete('Xtest1')
4777endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004778
4779" Test to make sure that an empty quickfix buffer is not reused for loading
4780" a normal buffer.
4781func Test_empty_qfbuf()
4782 enew | only
4783 call writefile(["Test"], 'Xfile1')
4784 call setqflist([], 'f')
4785 copen | only
4786 let qfbuf = bufnr('')
4787 edit Xfile1
4788 call assert_notequal(qfbuf, bufnr(''))
4789 enew
4790 call delete('Xfile1')
4791endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004792
4793" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004794" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004795func Xtest_below(cchar)
4796 call s:setup_commands(a:cchar)
4797
4798 " No quickfix/location list
4799 call assert_fails('Xbelow', 'E42:')
4800 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004801 call assert_fails('Xbefore', 'E42:')
4802 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004803
4804 " Empty quickfix/location list
4805 call g:Xsetlist([])
4806 call assert_fails('Xbelow', 'E42:')
4807 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004808 call assert_fails('Xbefore', 'E42:')
4809 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004810
4811 call s:create_test_file('X1')
4812 call s:create_test_file('X2')
4813 call s:create_test_file('X3')
4814 call s:create_test_file('X4')
4815
4816 " Invalid entries
4817 edit X1
4818 call g:Xsetlist(["E1", "E2"])
4819 call assert_fails('Xbelow', 'E42:')
4820 call assert_fails('Xabove', 'E42:')
4821 call assert_fails('3Xbelow', 'E42:')
4822 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004823 call assert_fails('Xbefore', 'E42:')
4824 call assert_fails('Xafter', 'E42:')
4825 call assert_fails('3Xbefore', 'E42:')
4826 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004827
4828 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004829 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 +02004830 edit +7 X2
4831 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004832 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004833 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004834 normal 7G
4835 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004836 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004837 call assert_fails('Xbefore', 'E553:')
4838
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004839 normal 2j
4840 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004841 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004842 normal 7G
4843 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004844 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004845
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004846 " Last error in this file
4847 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004848 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004849 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004850 normal gg
4851 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004852 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004853 call assert_fails('Xafter', 'E553:')
4854
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004855 " First error in this file
4856 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004857 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004858 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004859 normal G
4860 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004861 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004862 call assert_fails('Xbefore', 'E553:')
4863
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004864 normal gg
4865 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004866 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004867 normal gg
4868 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004869 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004870
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004871 normal G
4872 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004873 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004874 normal G
4875 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004876 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004877
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004878 edit X4
4879 call assert_fails('Xabove', 'E42:')
4880 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004881 call assert_fails('Xbefore', 'E42:')
4882 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004883 if a:cchar == 'l'
4884 " If a buffer has location list entries from some other window but not
4885 " from the current window, then the commands should fail.
4886 edit X1 | split | call setloclist(0, [], 'f')
4887 call assert_fails('Xabove', 'E776:')
4888 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004889 call assert_fails('Xbefore', 'E776:')
4890 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004891 close
4892 endif
4893
4894 " Test for lines with multiple quickfix entries
4895 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4896 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4897 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4898 edit +1 X2
4899 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004900 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004901 normal 1G
4902 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004903 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004904
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004905 normal gg
4906 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004907 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004908 normal gg
4909 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004910 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004911
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004912 normal G
4913 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004914 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004915 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004916 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004917 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004918
4919 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004920 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004921 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004922 normal G
4923 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004924 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004925
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004926 normal 10G
4927 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004928 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004929 normal 10G$
4930 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004931 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004932
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004933 normal 10G
4934 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004935 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004936 normal 9G
4937 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004938 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004939
4940 " Invalid range
4941 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004942 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004943 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004944 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004945 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004946 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004947 endif
4948
4949 call delete('X1')
4950 call delete('X2')
4951 call delete('X3')
4952 call delete('X4')
4953endfunc
4954
4955func Test_cbelow()
4956 call Xtest_below('c')
4957 call Xtest_below('l')
4958endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004959
4960func Test_quickfix_count()
4961 let commands = [
4962 \ 'cNext',
4963 \ 'cNfile',
4964 \ 'cabove',
4965 \ 'cbelow',
4966 \ 'cfirst',
4967 \ 'clast',
4968 \ 'cnewer',
4969 \ 'cnext',
4970 \ 'cnfile',
4971 \ 'colder',
4972 \ 'cprevious',
4973 \ 'crewind',
4974 \
4975 \ 'lNext',
4976 \ 'lNfile',
4977 \ 'labove',
4978 \ 'lbelow',
4979 \ 'lfirst',
4980 \ 'llast',
4981 \ 'lnewer',
4982 \ 'lnext',
4983 \ 'lnfile',
4984 \ 'lolder',
4985 \ 'lprevious',
4986 \ 'lrewind',
4987 \ ]
4988 for cmd in commands
4989 call assert_fails('-1' .. cmd, 'E16:')
4990 call assert_fails('.' .. cmd, 'E16:')
4991 call assert_fails('%' .. cmd, 'E16:')
4992 call assert_fails('$' .. cmd, 'E16:')
4993 endfor
4994endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004995
4996" Test for aborting quickfix commands using QuickFixCmdPre
4997func Xtest_qfcmd_abort(cchar)
4998 call s:setup_commands(a:cchar)
4999
5000 call g:Xsetlist([], 'f')
5001
5002 " cexpr/lexpr
5003 let e = ''
5004 try
5005 Xexpr ["F1:10:Line10", "F2:20:Line20"]
5006 catch /.*/
5007 let e = v:exception
5008 endtry
5009 call assert_equal('AbortCmd', e)
5010 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5011
5012 " cfile/lfile
5013 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
5014 let e = ''
5015 try
5016 Xfile Xfile1
5017 catch /.*/
5018 let e = v:exception
5019 endtry
5020 call assert_equal('AbortCmd', e)
5021 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5022 call delete('Xfile1')
5023
5024 " cgetbuffer/lgetbuffer
5025 enew!
5026 call append(0, ["F1:10:Line10", "F2:20:Line20"])
5027 let e = ''
5028 try
5029 Xgetbuffer
5030 catch /.*/
5031 let e = v:exception
5032 endtry
5033 call assert_equal('AbortCmd', e)
5034 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5035 enew!
5036
5037 " vimgrep/lvimgrep
5038 let e = ''
5039 try
5040 Xvimgrep /func/ test_quickfix.vim
5041 catch /.*/
5042 let e = v:exception
5043 endtry
5044 call assert_equal('AbortCmd', e)
5045 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5046
5047 " helpgrep/lhelpgrep
5048 let e = ''
5049 try
5050 Xhelpgrep quickfix
5051 catch /.*/
5052 let e = v:exception
5053 endtry
5054 call assert_equal('AbortCmd', e)
5055 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5056
5057 " grep/lgrep
5058 if has('unix')
5059 let e = ''
5060 try
5061 silent Xgrep func test_quickfix.vim
5062 catch /.*/
5063 let e = v:exception
5064 endtry
5065 call assert_equal('AbortCmd', e)
5066 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5067 endif
5068endfunc
5069
5070func Test_qfcmd_abort()
5071 augroup QF_Test
5072 au!
5073 autocmd QuickFixCmdPre * throw "AbortCmd"
5074 augroup END
5075
5076 call Xtest_qfcmd_abort('c')
5077 call Xtest_qfcmd_abort('l')
5078
5079 augroup QF_Test
5080 au!
5081 augroup END
5082endfunc
5083
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005084" Test for using a file in one of the parent directories.
5085func Test_search_in_dirstack()
5086 call mkdir('Xtestdir/a/b/c', 'p')
5087 let save_cwd = getcwd()
5088 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5089 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5090 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5091 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5092
5093 let lines = "Entering dir Xtestdir\n" .
5094 \ "Entering dir a\n" .
5095 \ "Entering dir b\n" .
5096 \ "Xfile2:2:X2_L2\n" .
5097 \ "Leaving dir a\n" .
5098 \ "Xfile1:2:X1_L2\n" .
5099 \ "Xfile3:1:X3_L1\n" .
5100 \ "Entering dir c\n" .
5101 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005102 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005103 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005104 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005105 call assert_equal(11, getqflist({'size' : 0}).size)
5106 call assert_equal(4, getqflist({'idx' : 0}).idx)
5107 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005108 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005109 cnext
5110 call assert_equal(6, getqflist({'idx' : 0}).idx)
5111 call assert_equal('X1_L2', getline('.'))
5112 cnext
5113 call assert_equal(7, getqflist({'idx' : 0}).idx)
5114 call assert_equal(1, line('$'))
5115 call assert_equal('', getline(1))
5116 cnext
5117 call assert_equal(9, getqflist({'idx' : 0}).idx)
5118 call assert_equal(1, line('$'))
5119 call assert_equal('', getline(1))
5120
5121 set efm&
5122 exe 'cd ' . save_cwd
5123 call delete('Xtestdir', 'rf')
5124endfunc
5125
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005126" Test for :cquit
5127func Test_cquit()
5128 " Exit Vim with a non-zero value
5129 if RunVim([], ["cquit 7"], '')
5130 call assert_equal(7, v:shell_error)
5131 endif
5132
5133 if RunVim([], ["50cquit"], '')
5134 call assert_equal(50, v:shell_error)
5135 endif
5136
5137 " Exit Vim with default value
5138 if RunVim([], ["cquit"], '')
5139 call assert_equal(1, v:shell_error)
5140 endif
5141
5142 " Exit Vim with zero value
5143 if RunVim([], ["cquit 0"], '')
5144 call assert_equal(0, v:shell_error)
5145 endif
5146
5147 " Exit Vim with negative value
5148 call assert_fails('-3cquit', 'E16:')
5149endfunc
5150
Bram Moolenaar858ba062020-05-31 23:11:59 +02005151" Test for getting a specific item from a quickfix list
5152func Xtest_getqflist_by_idx(cchar)
5153 call s:setup_commands(a:cchar)
5154 " Empty list
5155 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5156 Xexpr ['F1:10:L10', 'F1:20:L20']
5157 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5158 call assert_equal(bufnr('F1'), l[0].bufnr)
5159 call assert_equal(20, l[0].lnum)
5160 call assert_equal('L20', l[0].text)
5161 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5162 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5163 %bwipe!
5164endfunc
5165
5166func Test_getqflist_by_idx()
5167 call Xtest_getqflist_by_idx('c')
5168 call Xtest_getqflist_by_idx('l')
5169endfunc
5170
5171" Test for the 'quickfixtextfunc' setting
5172func Tqfexpr(info)
5173 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005174 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005175 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005176 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005177 endif
5178
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005179 let l = []
5180 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5181 let e = qfl[idx]
5182 let s = ''
5183 if e.bufnr != 0
5184 let bname = bufname(e.bufnr)
5185 let s ..= fnamemodify(bname, ':.')
5186 endif
5187 let s ..= '-'
5188 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5189 let s ..= e.text
5190 call add(l, s)
5191 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005192
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005193 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005194endfunc
5195
5196func Xtest_qftextfunc(cchar)
5197 call s:setup_commands(a:cchar)
5198
5199 set efm=%f:%l:%c:%m
5200 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005201 call assert_equal('Tqfexpr', &quickfixtextfunc)
5202 call assert_equal('',
5203 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005204 call g:Xsetlist([
5205 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5206 \ 'end_col': 7, 'text': 'green'},
5207 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5208 \ 'end_col': 8, 'text': 'blue'},
5209 \ ])
5210
Bram Moolenaar858ba062020-05-31 23:11:59 +02005211 Xwindow
5212 call assert_equal('F1-L10C2-green', getline(1))
5213 call assert_equal('F1-L20C4-blue', getline(2))
5214 Xclose
5215 set quickfixtextfunc&vim
5216 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005217 call assert_equal('F1|10 col 2-7| green', getline(1))
5218 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005219 Xclose
5220 set efm&
5221 set quickfixtextfunc&
5222
5223 " Test for per list 'quickfixtextfunc' setting
5224 func PerQfText(info)
5225 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005226 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005227 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005228 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005229 endif
5230 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005231 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005232 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005233 let l = []
5234 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5235 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5236 endfor
5237 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005238 endfunc
5239 set quickfixtextfunc=Tqfexpr
5240 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5241 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5242 Xwindow
5243 call assert_equal('Line 10, Col 2', getline(1))
5244 call assert_equal('Line 20, Col 4', getline(2))
5245 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005246 call assert_equal(function('PerQfText'),
5247 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005248 " Add entries to the list when the quickfix buffer is hidden
5249 Xaddexpr ['F1:30:6:red']
5250 Xwindow
5251 call assert_equal('Line 30, Col 6', getline(3))
5252 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005253 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005254 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005255 set quickfixtextfunc&
5256 delfunc PerQfText
5257
5258 " Non-existing function
5259 set quickfixtextfunc=Tabc
5260 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5261 call assert_fails("Xwindow", 'E117:')
5262 Xclose
5263 set quickfixtextfunc&
5264
5265 " set option to a non-function
5266 set quickfixtextfunc=[10,\ 20]
5267 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5268 call assert_fails("Xwindow", 'E117:')
5269 Xclose
5270 set quickfixtextfunc&
5271
5272 " set option to a function with different set of arguments
5273 func Xqftext(a, b, c)
5274 return a:a .. a:b .. a:c
5275 endfunc
5276 set quickfixtextfunc=Xqftext
5277 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5278 call assert_fails("Xwindow", 'E119:')
5279 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005280
5281 " set option to a function that returns a list with non-strings
5282 func Xqftext2(d)
5283 return ['one', [], 'two']
5284 endfunc
5285 set quickfixtextfunc=Xqftext2
5286 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5287 \ 'E730:')
5288 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005289 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5290 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005291 Xclose
5292
Bram Moolenaar858ba062020-05-31 23:11:59 +02005293 set quickfixtextfunc&
5294 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005295 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005296
5297 " set the global option to a lambda function
5298 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5299 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5300 Xwindow
5301 call assert_equal(['green', 'blue'], getline(1, '$'))
5302 Xclose
5303 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)
5304 set quickfixtextfunc&
5305
5306 " use a lambda function that returns an empty list
5307 set quickfixtextfunc={d\ ->\ []}
5308 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5309 Xwindow
5310 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5311 \ getline(1, '$'))
5312 Xclose
5313 set quickfixtextfunc&
5314
5315 " use a lambda function that returns a list with empty strings
5316 set quickfixtextfunc={d\ ->\ ['',\ '']}
5317 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5318 Xwindow
5319 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5320 \ getline(1, '$'))
5321 Xclose
5322 set quickfixtextfunc&
5323
5324 " set the per-quickfix list text function to a lambda function
5325 call g:Xsetlist([], ' ',
5326 \ {'quickfixtextfunc' :
5327 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5328 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5329 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5330 Xwindow
5331 call assert_equal('Line 10, Col 2', getline(1))
5332 call assert_equal('Line 20, Col 4', getline(2))
5333 Xclose
5334 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5335 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005336endfunc
5337
5338func Test_qftextfunc()
5339 call Xtest_qftextfunc('c')
5340 call Xtest_qftextfunc('l')
5341endfunc
5342
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005343func Test_qftextfunc_callback()
5344 let lines =<< trim END
5345 set efm=%f:%l:%c:%m
5346
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005347 #" Test for using a function name
5348 LET &qftf = 'g:Tqfexpr'
5349 cexpr "F0:0:0:L0"
5350 copen
5351 call assert_equal('F0-L0C0-L0', getline(1))
5352 cclose
5353
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005354 #" Test for using a function()
5355 set qftf=function('g:Tqfexpr')
5356 cexpr "F1:1:1:L1"
5357 copen
5358 call assert_equal('F1-L1C1-L1', getline(1))
5359 cclose
5360
5361 #" Using a funcref variable to set 'quickfixtextfunc'
5362 VAR Fn = function('g:Tqfexpr')
5363 LET &qftf = Fn
5364 cexpr "F2:2:2:L2"
5365 copen
5366 call assert_equal('F2-L2C2-L2', getline(1))
5367 cclose
5368
5369 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5370 LET Fn = function('g:Tqfexpr')
5371 LET &qftf = string(Fn)
5372 cexpr "F3:3:3:L3"
5373 copen
5374 call assert_equal('F3-L3C3-L3', getline(1))
5375 cclose
5376
5377 #" Test for using a funcref()
5378 set qftf=funcref('g:Tqfexpr')
5379 cexpr "F4:4:4:L4"
5380 copen
5381 call assert_equal('F4-L4C4-L4', getline(1))
5382 cclose
5383
5384 #" Using a funcref variable to set 'quickfixtextfunc'
5385 LET Fn = funcref('g:Tqfexpr')
5386 LET &qftf = Fn
5387 cexpr "F5:5:5:L5"
5388 copen
5389 call assert_equal('F5-L5C5-L5', getline(1))
5390 cclose
5391
5392 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5393 LET Fn = funcref('g:Tqfexpr')
5394 LET &qftf = string(Fn)
5395 cexpr "F5:5:5:L5"
5396 copen
5397 call assert_equal('F5-L5C5-L5', getline(1))
5398 cclose
5399
5400 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00005401 VAR optval = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005402 LET optval = substitute(optval, ' ', '\\ ', 'g')
5403 exe "set qftf=" .. optval
5404 cexpr "F6:6:6:L6"
5405 copen
5406 call assert_equal('F6-L6C6-L6', getline(1))
5407 cclose
5408
5409 #" Set 'quickfixtextfunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005410 LET &qftf = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005411 cexpr "F7:7:7:L7"
5412 copen
5413 call assert_equal('F7-L7C7-L7', getline(1))
5414 cclose
5415
5416 #" Set 'quickfixtextfunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005417 LET &qftf = "LSTART a LMIDDLE g:Tqfexpr(a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005418 cexpr "F8:8:8:L8"
5419 copen
5420 call assert_equal('F8-L8C8-L8', getline(1))
5421 cclose
5422
5423 #" Set 'quickfixtextfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00005424 VAR Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005425 LET &qftf = Lambda
5426 cexpr "F9:9:9:L9"
5427 copen
5428 call assert_equal('F9-L9C9-L9', getline(1))
5429 cclose
5430
5431 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00005432 LET Lambda = LSTART a LMIDDLE g:Tqfexpr(a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005433 LET &qftf = string(Lambda)
5434 cexpr "F9:9:9:L9"
5435 copen
5436 call assert_equal('F9-L9C9-L9', getline(1))
5437 cclose
5438 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00005439 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005440
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005441 " Test for using a script-local function name
5442 func s:TqfFunc2(info)
5443 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5444 return ''
5445 endfunc
5446 let g:TqfFunc2Args = []
5447 set quickfixtextfunc=s:TqfFunc2
5448 cexpr "F10:10:10:L10"
5449 cclose
5450 call assert_equal([1, 1], g:TqfFunc2Args)
5451
5452 let &quickfixtextfunc = 's:TqfFunc2'
5453 cexpr "F11:11:11:L11"
5454 cclose
5455 call assert_equal([1, 1], g:TqfFunc2Args)
5456 delfunc s:TqfFunc2
5457
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005458 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5459 func SetQftfFunc()
5460 let params = {'qftf': function('g:DictQftfFunc')}
5461 let &quickfixtextfunc = params.qftf
5462 endfunc
5463 func g:DictQftfFunc(_) dict
5464 endfunc
5465 call SetQftfFunc()
5466 new
5467 call SetQftfFunc()
5468 bw
5469 call test_garbagecollect_now()
5470 new
5471 set qftf=
5472 wincmd w
5473 set qftf=
5474 :%bw!
5475
5476 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5477 " to cause a crash.
5478 let &qftf = ''
5479 func SetLocalQftfFunc()
5480 let params = {'qftf': function('g:DictQftfFunc')}
5481 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5482 endfunc
5483 call SetLocalQftfFunc()
5484 call test_garbagecollect_now()
5485 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5486 delfunc g:DictQftfFunc
5487 delfunc SetQftfFunc
5488 delfunc SetLocalQftfFunc
5489 set efm&
5490endfunc
5491
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005492" Test for updating a location list for some other window and check that
5493" 'qftextfunc' uses the correct location list.
5494func Test_qftextfunc_other_loclist()
5495 %bw!
5496 call setloclist(0, [], 'f')
5497
5498 " create a window and a location list for it and open the location list
5499 " window
5500 lexpr ['F1:10:12:one', 'F1:20:14:two']
5501 let w1_id = win_getid()
5502 call setloclist(0, [], ' ',
5503 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5504 \ 'quickfixtextfunc':
5505 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5506 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5507 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5508 lwindow
5509 let w2_id = win_getid()
5510
5511 " create another window and a location list for it and open the location
5512 " list window
5513 topleft new
5514 let w3_id = win_getid()
5515 call setloclist(0, [], ' ',
5516 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5517 \ 'quickfixtextfunc':
5518 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5519 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5520 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5521 lwindow
5522 let w4_id = win_getid()
5523
5524 topleft new
5525 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5526 let w5_id = win_getid()
5527
5528 " change the location list for some other window
5529 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5530 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5531 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5532 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5533 \ getbufline(winbufnr(w2_id), 1, '$'))
5534 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5535 \ getbufline(winbufnr(w4_id), 1, '$'))
5536 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5537 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5538 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5539 \ getbufline(winbufnr(w2_id), 1, '$'))
5540 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5541 \ getbufline(winbufnr(w4_id), 1, '$'))
5542
5543 call win_gotoid(w5_id)
5544 lwindow
5545 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5546 \ getline(1, '$'))
5547 %bw!
5548endfunc
5549
Bram Moolenaarec98e932020-06-08 19:35:59 +02005550" Running :lhelpgrep command more than once in a help window, doesn't jump to
5551" the help topic
5552func Test_lhelpgrep_from_help_window()
5553 call mkdir('Xtestdir/doc', 'p')
5554 call writefile(['window'], 'Xtestdir/doc/a.txt')
5555 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5556 let save_rtp = &rtp
5557 let &rtp = 'Xtestdir'
5558 lhelpgrep window
5559 lhelpgrep buffer
5560 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5561 lhelpgrep window
5562 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5563 let &rtp = save_rtp
5564 call delete('Xtestdir', 'rf')
5565 new | only!
5566endfunc
5567
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005568" Test for the crash fixed by 7.3.715
5569func Test_setloclist_crash()
5570 %bw!
5571 let g:BufNum = bufnr()
5572 augroup QF_Test
5573 au!
5574 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5575 augroup END
5576
5577 try
5578 lvimgrep /.*/ *.mak
5579 catch /E926:/
5580 endtry
5581 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5582 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5583
5584 augroup QF_Test
5585 au!
5586 augroup END
5587 unlet g:BufNum
5588 %bw!
5589endfunc
5590
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005591" Test for adding an invalid entry with the quickfix window open and making
5592" sure that the window contents are not changed
5593func Test_add_invalid_entry_with_qf_window()
5594 call setqflist([], 'f')
5595 cexpr "Xfile1:10:aa"
5596 copen
5597 call setqflist(['bb'], 'a')
5598 call assert_equal(1, line('$'))
5599 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005600 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())
5601
5602 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5603 call assert_equal(1 , line('$'))
5604 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5605 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())
5606
5607 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')
5608 call assert_equal(1 , line('$'))
5609 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5610 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())
5611
5612 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')
5613 call assert_equal(1 , line('$'))
5614 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5615 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())
5616
5617 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')
5618 call assert_equal(1 , line('$'))
5619 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5620 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())
5621
5622 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')
5623 call assert_equal(1 , line('$'))
5624 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5625 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())
5626
5627 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')
5628 call assert_equal(1 , line('$'))
5629 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5630 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())
5631
5632 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')
5633 call assert_equal(1 , line('$'))
5634 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5635 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 +01005636 cclose
5637endfunc
5638
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005639" Test for very weird problem: autocommand causes a failure, resulting opening
5640" the quickfix window to fail. This still splits the window, but otherwise
5641" should not mess up buffers.
5642func Test_quickfix_window_fails_to_open()
5643 CheckScreendump
5644
5645 let lines =<< trim END
5646 anything
5647 try
5648 anything
5649 endtry
5650 END
5651 call writefile(lines, 'XquickfixFails')
5652
5653 let lines =<< trim END
5654 split XquickfixFails
5655 silent vimgrep anything %
5656 normal o
5657 au BufLeave * ++once source XquickfixFails
5658 " This will trigger the autocommand, which causes an error, what follows
5659 " is aborted but the window was already split.
5660 silent! cwindow
5661 END
5662 call writefile(lines, 'XtestWinFails')
5663 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5664 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5665
5666 " clean up
5667 call term_sendkeys(buf, ":bwipe!\<CR>")
5668 call term_wait(buf)
5669 call StopVimInTerminal(buf)
5670 call delete('XtestWinFails')
5671 call delete('XquickfixFails')
5672endfunc
5673
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005674" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005675" is changed.
5676func Xqfbuf_update(cchar)
5677 call s:setup_commands(a:cchar)
5678
5679 Xexpr "F1:1:line1"
5680 Xopen
5681 call assert_equal(['F1|1| line1'], getline(1, '$'))
5682 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5683
5684 " Test setqflist() using the 'lines' key in 'what'
5685 " add a new entry
5686 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5687 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5688 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5689 " replace all the entries with a single entry
5690 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5691 call assert_equal(['F3|3| line3'], getline(1, '$'))
5692 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5693 " remove all the entries
5694 call g:Xsetlist([], 'r', {'lines' : []})
5695 call assert_equal([''], getline(1, '$'))
5696 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5697 " add a new list
5698 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5699 call assert_equal(['F4|4| line4'], getline(1, '$'))
5700 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5701
5702 " Test setqflist() using the 'items' key in 'what'
5703 " add a new entry
5704 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5705 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5706 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5707 " replace all the entries with a single entry
5708 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5709 call assert_equal(['F6|6| line6'], getline(1, '$'))
5710 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5711 " remove all the entries
5712 call g:Xsetlist([], 'r', {'items' : []})
5713 call assert_equal([''], getline(1, '$'))
5714 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5715 " add a new list
5716 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5717 call assert_equal(['F7|7| line7'], getline(1, '$'))
5718 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5719
5720 call g:Xsetlist([], ' ', {})
5721 call assert_equal([''], getline(1, '$'))
5722 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5723
5724 Xclose
5725endfunc
5726
5727func Test_qfbuf_update()
5728 call Xqfbuf_update('c')
5729 call Xqfbuf_update('l')
5730endfunc
5731
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005732func Test_vimgrep_noswapfile()
5733 set noswapfile
5734 call writefile(['one', 'two', 'three'], 'Xgreppie')
5735 vimgrep two Xgreppie
5736 call assert_equal('two', getline('.'))
5737
5738 call delete('Xgreppie')
5739 set swapfile
5740endfunc
5741
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005742" Test for the :vimgrep 'f' flag (fuzzy match)
5743func Xvimgrep_fuzzy_match(cchar)
5744 call s:setup_commands(a:cchar)
5745
5746 Xvimgrep /three one/f Xfile*
5747 let l = g:Xgetlist()
5748 call assert_equal(2, len(l))
5749 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5750 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5751 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5752 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5753
5754 Xvimgrep /the/f Xfile*
5755 let l = g:Xgetlist()
5756 call assert_equal(3, len(l))
5757 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5758 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5759 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5760 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5761 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5762 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5763
5764 Xvimgrep /aaa/fg Xfile*
5765 let l = g:Xgetlist()
5766 call assert_equal(4, len(l))
5767 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5768 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5769 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5770 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5771 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5772 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5773 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5774 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5775
5776 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5777endfunc
5778
5779func Test_vimgrep_fuzzy_match()
5780 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5781 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5782 call Xvimgrep_fuzzy_match('c')
5783 call Xvimgrep_fuzzy_match('l')
5784 call delete('Xfile1')
5785 call delete('Xfile2')
5786endfunc
5787
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005788func Test_locationlist_open_in_newtab()
5789 call s:create_test_file('Xqftestfile1')
5790 call s:create_test_file('Xqftestfile2')
5791 call s:create_test_file('Xqftestfile3')
5792
5793 %bwipe!
5794
5795 lgetexpr ['Xqftestfile1:5:Line5',
5796 \ 'Xqftestfile2:10:Line10',
5797 \ 'Xqftestfile3:16:Line16']
5798
5799 silent! llast
5800 call assert_equal(1, tabpagenr('$'))
5801 call assert_equal('Xqftestfile3', bufname())
5802
5803 set switchbuf=newtab
5804
5805 silent! lfirst
5806 call assert_equal(2, tabpagenr('$'))
5807 call assert_equal('Xqftestfile1', bufname())
5808
5809 silent! lnext
5810 call assert_equal(3, tabpagenr('$'))
5811 call assert_equal('Xqftestfile2', bufname())
5812
5813 call delete('Xqftestfile1')
5814 call delete('Xqftestfile2')
5815 call delete('Xqftestfile3')
5816 set switchbuf&vim
5817
5818 %bwipe!
5819endfunc
5820
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005821" Test for win_gettype() in quickfix and location list windows
5822func Test_win_gettype()
5823 copen
5824 call assert_equal("quickfix", win_gettype())
5825 let wid = win_getid()
5826 wincmd p
5827 call assert_equal("quickfix", win_gettype(wid))
5828 cclose
5829 lexpr ''
5830 lopen
5831 call assert_equal("loclist", win_gettype())
5832 let wid = win_getid()
5833 wincmd p
5834 call assert_equal("loclist", win_gettype(wid))
5835 lclose
5836endfunc
5837
Christian Brabandt0b226f62021-12-01 10:54:24 +00005838fun Test_vimgrep_nomatch()
5839 call XexprTests('c')
5840 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5841 copen
5842 if has("win32")
5843 call assert_fails('vimgrep foo *.zzz', 'E479:')
5844 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'}]
5845 else
5846 call assert_fails('vimgrep foo *.zzz', 'E480:')
5847 let expected = []
5848 endif
5849 call assert_equal(expected, getqflist())
5850 cclose
5851endfunc
5852
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005853" Test for opening the quickfix window in two tab pages and then closing one
5854" of the quickfix windows. This should not make the quickfix buffer unlisted.
5855" (github issue #9300).
5856func Test_two_qf_windows()
5857 cexpr "F1:1:line1"
5858 copen
5859 tabnew
5860 copen
5861 call assert_true(&buflisted)
5862 cclose
5863 tabfirst
5864 call assert_true(&buflisted)
5865 let bnum = bufnr()
5866 cclose
5867 " if all the quickfix windows are closed, then buffer should be unlisted.
5868 call assert_false(buflisted(bnum))
5869 %bw!
5870
5871 " Repeat the test for a location list
5872 lexpr "F2:2:line2"
5873 lopen
5874 let bnum = bufnr()
5875 tabnew
5876 exe "buffer" bnum
5877 tabfirst
5878 lclose
5879 tablast
5880 call assert_true(buflisted(bnum))
5881 tabclose
5882 lopen
5883 call assert_true(buflisted(bnum))
5884 lclose
5885 call assert_false(buflisted(bnum))
5886 %bw!
5887endfunc
5888
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005889" Weird sequence of commands that caused entering a wiped-out buffer
5890func Test_lopen_bwipe()
5891 func R()
5892 silent! tab lopen
5893 e x
5894 silent! lfile
5895 endfunc
5896
5897 cal R()
5898 cal R()
5899 cal R()
5900 bw!
5901 delfunc R
5902endfunc
5903
Bram Moolenaare3537ae2022-02-08 15:05:20 +00005904" Another sequence of commands that caused all buffers to be wiped out
5905func Test_lopen_bwipe_all()
5906 let lines =<< trim END
5907 func R()
5908 silent! tab lopen
5909 e foo
5910 silent! lfile
5911 endfunc
5912 cal R()
5913 exe "norm \<C-W>\<C-V>0"
5914 cal R()
5915 bwipe
5916
5917 call writefile(['done'], 'Xresult')
5918 qall!
5919 END
5920 call writefile(lines, 'Xscript')
5921 if RunVim([], [], '-u NONE -n -X -Z -e -m -s -S Xscript')
5922 call assert_equal(['done'], readfile('Xresult'))
5923 endif
5924
5925 call delete('Xscript')
5926 call delete('Xresult')
5927endfunc
5928
Bram Moolenaar9b4a80a2022-02-01 13:54:17 +00005929
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005930" vim: shiftwidth=2 sts=2 expandtab