blob: e82ce683eceb156d38e4524fc92d568b520626df [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
4CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01005
Bram Moolenaare00fdf32019-09-15 19:09:42 +02006source screendump.vim
7
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01008set encoding=utf-8
9
Bram Moolenaar2b946c92016-11-12 18:14:44 +010010func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020011 if a:cchar == 'c'
12 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
13 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020014 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020015 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020016 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010017 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020018 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020019 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020020 command! -nargs=* Xclose <mods>cclose <args>
21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
22 command! -nargs=* Xgetfile <mods>cgetfile <args>
23 command! -nargs=* Xaddfile <mods>caddfile <args>
24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
27 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020028 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020030 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
31 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020032 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020033 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020034 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020035 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010036 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020037 command! -nargs=* Xgrep <mods> grep <args>
38 command! -nargs=* Xgrepadd <mods> grepadd <args>
39 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010040 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020041 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
42 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020043 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
44 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020045 let g:Xgetlist = function('getqflist')
46 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020047 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020048 else
49 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
50 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020051 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020052 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020053 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010054 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020055 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020056 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020057 command! -nargs=* Xclose <mods>lclose <args>
58 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
59 command! -nargs=* Xgetfile <mods>lgetfile <args>
60 command! -nargs=* Xaddfile <mods>laddfile <args>
61 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
62 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
63 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
64 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020065 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
66 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020067 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
68 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020069 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020070 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020071 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020072 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010073 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020074 command! -nargs=* Xgrep <mods> lgrep <args>
75 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
76 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010077 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020078 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
79 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020080 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
81 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020082 let g:Xgetlist = function('getloclist', [0])
83 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020084 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020085 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010086endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020087
Bram Moolenaarda59dd52016-01-05 21:59:58 +010088" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010089func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020090 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010091
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020092 if a:cchar == 'l'
93 call assert_fails('llist', 'E776:')
94 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020096 Xgetexpr []
97 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098 call assert_true(v:errmsg ==# 'E42: No Errors')
99
100 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200101 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100103 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100104
105 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100106 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100107 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
108 \ ' 4 Xtestfile2:2 col 2: Line2',
109 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
110
111 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100112 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100113 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
114 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100115 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100116
117 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100118 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100119 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
120 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
121
Bram Moolenaaree85df32017-03-19 14:19:50 +0100122 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
124
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
127
Bram Moolenaaree85df32017-03-19 14:19:50 +0100128 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100129 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
130 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100131
132 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100133 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100134 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
135 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100136
thinca6864efa2021-06-19 20:45:20 +0200137 " Ranged entries
138 call g:Xsetlist([{'lnum':10,'text':'Line1'},
139 \ {'lnum':20,'col':10,'text':'Line2'},
140 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
141 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
142 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
143 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
144 let l = split(execute('Xlist', ""), "\n")
145 call assert_equal([' 1:10: Line1',
146 \ ' 2:20 col 10: Line2',
147 \ ' 3:30 col 15-20: Line3',
148 \ ' 4:40-45: Line4',
149 \ ' 5:50-55 col 15: Line5',
150 \ ' 6:60-65 col 25-35: Line6'], l)
151
Bram Moolenaaree85df32017-03-19 14:19:50 +0100152 " Different types of errors
153 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
154 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
155 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
156 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
157 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
158 let l = split(execute('Xlist', ""), "\n")
159 call assert_equal([' 1:10 col 5 warning 11: Warning',
160 \ ' 2:20 col 10 error 22: Error',
161 \ ' 3:30 col 15 info 33: Info',
162 \ ' 4:40 col 20 x 44: Other',
163 \ ' 5:50 col 25 55: one'], l)
164
Bram Moolenaard76ce852018-05-01 15:02:04 +0200165 " Test for module names, one needs to explicitly set `'valid':v:true` so
166 call g:Xsetlist([
167 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
168 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
169 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
170 let l = split(execute('Xlist', ""), "\n")
171 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
172 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
173 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
174
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100175 " For help entries in the quickfix list, only the filename without directory
176 " should be displayed
177 Xhelpgrep setqflist()
178 let l = split(execute('Xlist 1', ''), "\n")
179 call assert_match('^ 1 [^\\/]\{-}:', l[0])
180
Bram Moolenaaree85df32017-03-19 14:19:50 +0100181 " Error cases
182 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100183endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100184
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100185func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100186 call XlistTests('c')
187 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100188endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100189
190" Tests for the :colder, :cnewer, :lolder and :lnewer commands
191" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100192" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100193func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200194 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100195
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200196 if a:cchar == 'l'
197 " No location list for the current window
198 call assert_fails('lolder', 'E776:')
199 call assert_fails('lnewer', 'E776:')
200 endif
201
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200202 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200203 call g:Xsetlist(list)
204
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100205 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200206 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100207 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
208
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200209 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100210 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
211
212 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 Xgetexpr ['Xtestfile1:1:3:Line1']
214 Xgetexpr ['Xtestfile2:2:2:Line2']
215 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100216
217 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200218 Xolder
219 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100220 call assert_equal('Line2', l[0].text)
221
222 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200223 Xnewer
224 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100225 call assert_equal('Line3', l[0].text)
226
227 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200228 Xolder 2
229 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100230 call assert_equal('Line1', l[0].text)
231
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200232 Xnewer 2
233 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100234 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100235endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100236
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100237func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100238 call XageTests('c')
239 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100240endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100241
242" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
243" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100244func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200245 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100246
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200247 " Opening the location list window without any errors should fail
248 if a:cchar == 'l'
249 call assert_fails('lopen', 'E776:')
250 endif
251
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100252 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200253 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100254
255 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200256 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100257 call assert_true(winnr('$') == 1)
258
259 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200260 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
261 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100262
263 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200264 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100265 call assert_true(winnr('$') == 2 && winnr() == 2 &&
266 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200267 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100268
269 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200270 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100271 call assert_true(winnr('$') == 1)
272
273 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200274 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100275
276 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200277 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100278 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200279 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100280
281 " Opening the window again, should move the cursor to that window
282 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200283 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100284 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200285 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100286 \ getline('.') ==# '|| non-error 1')
287
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100288 " :cnext in quickfix window should move to the next entry
289 Xnext
290 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100291
292 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200293 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100294 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200295
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100296 " Specifying the width should adjust the width for a vertically split
297 " quickfix window.
298 vert Xopen
299 call assert_equal(10, winwidth(0))
300 vert Xopen 12
301 call assert_equal(12, winwidth(0))
302 Xclose
303
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200304 " Horizontally or vertically splitting the quickfix window should create a
305 " normal window/buffer
306 Xopen
307 wincmd s
308 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
309 call assert_equal(0, getwininfo(win_getid())[0].loclist)
310 call assert_notequal('quickfix', &buftype)
311 close
312 Xopen
313 wincmd v
314 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
315 call assert_equal(0, getwininfo(win_getid())[0].loclist)
316 call assert_notequal('quickfix', &buftype)
317 close
318 Xopen
319 Xclose
320
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200321 if a:cchar == 'c'
322 " Opening the quickfix window in multiple tab pages should reuse the
323 " quickfix buffer
324 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
325 \ 'Xtestfile3:3:1:Line3']
326 Xopen
327 let qfbufnum = bufnr('%')
328 tabnew
329 Xopen
330 call assert_equal(qfbufnum, bufnr('%'))
331 new | only | tabonly
332 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100333endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100334
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100335func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100336 call XwindowTests('c')
337 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100338endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100339
Bram Moolenaar36d50222019-05-02 20:17:40 +0200340func Test_copenHeight()
341 copen
342 wincmd H
343 let height = winheight(0)
344 copen 10
345 call assert_equal(height, winheight(0))
346 quit
347endfunc
348
Bram Moolenaar1142a312019-10-16 14:51:39 +0200349func Test_copenHeight_tabline()
350 set tabline=foo showtabline=2
351 copen
352 wincmd H
353 let height = winheight(0)
354 copen 10
355 call assert_equal(height, winheight(0))
356 quit
357 set tabline& showtabline&
358endfunc
359
360
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100361" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
362" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100363func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200364 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100365
366 call writefile(['Xtestfile1:700:10:Line 700',
367 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
368
369 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200370 Xfile Xqftestfile1
371 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100372 call assert_true(len(l) == 2 &&
373 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
374 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
375
Bram Moolenaar049cba92016-06-26 14:38:04 +0200376 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200377 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200378
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100379 " Run cfile/lfile from a modified buffer
380 enew!
381 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200382 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100383 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
384
385 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200386 Xaddfile Xqftestfile1
387 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100388 call assert_true(len(l) == 3 &&
389 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
390
391 call writefile(['Xtestfile1:222:77:Line 222',
392 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
393
394 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200395 Xgetfile Xqftestfile1
396 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100397 call assert_true(len(l) == 2 &&
398 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
399 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
400
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100401 " Test for a file with a long line and without a newline at the end
402 let text = repeat('x', 1024)
403 let t = 'a.txt:18:' . text
404 call writefile([t], 'Xqftestfile1', 'b')
405 silent! Xfile Xqftestfile1
406 call assert_equal(text, g:Xgetlist()[0].text)
407
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100408 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100409endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100410
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100411func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100412 call XfileTests('c')
413 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100414endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100415
416" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
417" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100418func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200419 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420
421 enew!
422 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
423 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200424 Xbuffer!
425 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100426 call assert_true(len(l) == 2 &&
427 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
428 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
429
430 enew!
431 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
432 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200433 Xgetbuffer
434 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100435 call assert_true(len(l) == 2 &&
436 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
437 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
438
439 enew!
440 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
441 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200442 Xaddbuffer
443 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100444 call assert_true(len(l) == 4 &&
445 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
446 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
447 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200448 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100449
Bram Moolenaaree85df32017-03-19 14:19:50 +0100450 " Check for invalid buffer
451 call assert_fails('Xbuffer 199', 'E474:')
452
453 " Check for unloaded buffer
454 edit Xtestfile1
455 let bnr = bufnr('%')
456 enew!
457 call assert_fails('Xbuffer ' . bnr, 'E681:')
458
459 " Check for invalid range
460 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
461 " commands. So directly call the commands.
462 if (a:cchar == 'c')
463 call assert_fails('900,999cbuffer', 'E16:')
464 else
465 call assert_fails('900,999lbuffer', 'E16:')
466 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100467endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100468
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100469func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100470 call XbufferTests('c')
471 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100472endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100473
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100474func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200475 call s:setup_commands(a:cchar)
476
477 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100478endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200479
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100480func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200481 call XexprTests('c')
482 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100483endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200484
485" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100486func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200487 call s:setup_commands(a:cchar)
488
Bram Moolenaar74240d32017-12-10 15:26:15 +0100489 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200490 " Jumping to first or next location list entry without any error should
491 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100492 if a:cchar == 'c'
493 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100494 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100495 else
496 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100497 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200498 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100499 call assert_fails('Xnext', err)
500 call assert_fails('Xprev', err)
501 call assert_fails('Xnfile', err)
502 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100503 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200504
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100505 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100506 call assert_fails(cmd, 'E42:')
507
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200508 call s:create_test_file('Xqftestfile1')
509 call s:create_test_file('Xqftestfile2')
510
511 Xgetexpr ['Xqftestfile1:5:Line5',
512 \ 'Xqftestfile1:6:Line6',
513 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200514 \ 'Xqftestfile2:11:Line11',
515 \ 'RegularLine1',
516 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200517
518 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100519 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200520 call assert_fails('Xprev', 'E553:')
521 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200522 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200523 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200524 call assert_equal(10, line('.'))
525 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200526 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200527 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100528 5Xcc
529 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
530 2Xcc
531 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100532 if a:cchar == 'c'
533 cc
534 else
535 ll
536 endif
537 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100538 10Xcc
539 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200540 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200541 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200542 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200543 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200544 call assert_fails('Xnext', 'E553:')
545 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100546 " To process the range using quickfix list entries, directly use the
547 " quickfix commands (don't use the user defined commands)
548 if a:cchar == 'c'
549 $cc
550 else
551 $ll
552 endif
553 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200554 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200555 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200556 call assert_equal(5, line('.'))
557
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200558 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200559 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200560 call assert_equal(11, line('.'))
561 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200562 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200563 call assert_equal(5, line('.'))
564
Bram Moolenaar74240d32017-12-10 15:26:15 +0100565 " Jumping to an error from the error window using cc command
566 Xgetexpr ['Xqftestfile1:5:Line5',
567 \ 'Xqftestfile1:6:Line6',
568 \ 'Xqftestfile2:10:Line10',
569 \ 'Xqftestfile2:11:Line11']
570 Xopen
571 10Xcc
572 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200573 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100574 Xopen
575 call cursor(2, 1)
576 if a:cchar == 'c'
577 .cc
578 else
579 .ll
580 endif
581 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200582 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100583
584 " Jumping to an error from the error window (when only the error window is
585 " present)
586 Xopen | only
587 Xlast 1
588 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200589 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100590
Bram Moolenaaree85df32017-03-19 14:19:50 +0100591 Xexpr ""
592 call assert_fails('Xnext', 'E42:')
593
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200594 call delete('Xqftestfile1')
595 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200596
597 " Should be able to use next/prev with invalid entries
598 Xexpr ""
599 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
600 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100601 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200602 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
603 Xlast
604 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
605 Xfirst
606 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
607 2Xnext
608 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100609endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200610
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100611func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200612 call Xtest_browse('c')
613 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100614endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200615
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100616func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200617 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100618 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100619
Bram Moolenaarce90e362019-09-08 18:58:44 +0200620 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100621 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100622
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200623 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100624 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100625
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200626 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100627 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100628
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200629 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100630 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100631
632endfunc
633
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100634func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200635 call s:setup_commands(a:cchar)
636 Xhelpgrep quickfix
637 Xopen
638 if a:cchar == 'c'
639 let title_text = ':helpgrep quickfix'
640 else
641 let title_text = ':lhelpgrep quickfix'
642 endif
643 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200644
645 " Jumping to a help topic should open the help window
646 only
647 Xnext
648 call assert_true(&buftype == 'help')
649 call assert_true(winnr('$') == 2)
650 " Jumping to the next match should reuse the help window
651 Xnext
652 call assert_true(&buftype == 'help')
653 call assert_true(winnr() == 1)
654 call assert_true(winnr('$') == 2)
655 " Jumping to the next match from the quickfix window should reuse the help
656 " window
657 Xopen
658 Xnext
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
661 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200662 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200663
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100664 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200665 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100666
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100667 " When the current window is vertically split, jumping to a help match
668 " should open the help window at the top.
669 only | enew
670 let w1 = win_getid()
671 vert new
672 let w2 = win_getid()
673 Xnext
674 let w3 = win_getid()
675 call assert_true(&buftype == 'help')
676 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100677 " See jump_to_help_window() for details
678 let w2_width = winwidth(w2)
679 if w2_width != &columns && w2_width < 80
680 call assert_equal(['col', [['leaf', w3],
681 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
682 else
683 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
684 \ ['leaf', w1]]] , winlayout())
685 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100686
687 new | only
688 set buftype=help
689 set modified
690 call assert_fails('Xnext', 'E37:')
691 set nomodified
692 new | only
693
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200694 if a:cchar == 'l'
695 " When a help window is present, running :lhelpgrep should reuse the
696 " help window and not the current window
697 new | only
698 call g:Xsetlist([], 'f')
699 help index.txt
700 wincmd w
701 lhelpgrep quickfix
702 call assert_equal(1, winnr())
703 call assert_notequal([], getloclist(1))
704 call assert_equal([], getloclist(2))
705 endif
706
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200707 new | only
708
Bram Moolenaaree85df32017-03-19 14:19:50 +0100709 " Search for non existing help string
710 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200711 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200712 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100713endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200714
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100715func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200716 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200717 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200718 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100719endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100720
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100721def Test_helpgrep_vim9_restore_cpo()
722 assert_equal('aABceFs', &cpo)
723
724 var rtp_save = &rtp
725 var dir = 'Xruntime/after'
726 &rtp ..= ',' .. dir
727 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100728 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100729 filetype plugin on
730 silent helpgrep grail
731 cwindow
732 silent helpgrep grail
733
734 assert_equal('aABceFs', &cpo)
735 delete(dir, 'rf')
736 &rtp = rtp_save
737 cclose
738 helpclose
739enddef
740
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200741def Test_vim9_cexpr()
742 var text = 'somefile:95:error'
743 cexpr text
744 var l = getqflist()
745 assert_equal(1, l->len())
746 assert_equal(95, l[0].lnum)
747 assert_equal('error', l[0].text)
748
749 text = 'somefile:77:warning'
750 caddexpr text
751 l = getqflist()
752 assert_equal(2, l->len())
753 assert_equal(77, l[1].lnum)
754 assert_equal('warning', l[1].text)
755enddef
756
Bram Moolenaar6920c722016-01-22 22:44:10 +0100757func Test_errortitle()
758 augroup QfBufWinEnter
759 au!
760 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
761 augroup END
762 copen
763 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'')'}]
764 call setqflist(a)
765 call assert_equal(':setqflist()', g:a)
766 augroup QfBufWinEnter
767 au!
768 augroup END
769 augroup! QfBufWinEnter
770endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100771
Bram Moolenaar5584df62016-03-18 21:00:51 +0100772func Test_vimgreptitle()
773 augroup QfBufWinEnter
774 au!
775 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
776 augroup END
777 try
778 vimgrep /pattern/j file
779 catch /E480/
780 endtry
781 copen
782 call assert_equal(': vimgrep /pattern/j file', g:a)
783 augroup QfBufWinEnter
784 au!
785 augroup END
786 augroup! QfBufWinEnter
787endfunc
788
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100789func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200790 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100791
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200792 Xgetexpr ['file:1:1:message']
793 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100794 if a:cchar == 'c'
795 call setqflist(l, 'r')
796 else
797 call setloclist(0, l, 'r')
798 endif
799
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200800 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100801 if a:cchar == 'c'
802 let title = ':setqflist()'
803 else
804 let title = ':setloclist()'
805 endif
806 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200807 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100808endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100809
810" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100811func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200812 call XqfTitleTests('c')
813 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100814endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100815
816" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100817func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100818 let save_efm = &efm
819 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
820 cgetexpr ['WWWW', 'EEEE', 'CCCC']
821 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
822 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
823 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
824 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
825 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
826 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
827 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
828 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
829 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100830endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100831
832" This will test for problems in quickfix:
833" A. incorrectly copying location lists which caused the location list to show
834" a different name than the file that was actually being displayed.
835" B. not reusing the window for which the location list window is opened but
836" instead creating new windows.
837" C. make sure that the location list window is not reused instead of the
838" window it belongs to.
839"
840" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100841func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100842 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
843 let word = substitute(base, '\v(.*)\..*', '\1', '')
844
845 setl modifiable
846 setl noreadonly
847 setl noswapfile
848 setl bufhidden=delete
849 %del _
850 " For problem 2:
851 " 'buftype' has to be set to reproduce the constant opening of new windows
852 setl buftype=nofile
853
854 call setline(1, word)
855
856 setl nomodified
857 setl nomodifiable
858 setl readonly
859 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100860endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100861
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100862func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200863 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100864
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200865 augroup testgroup
866 au!
867 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
868 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100869
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200870 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100871
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200872 let qflist = []
873 for word in words
874 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
875 " NOTE: problem 1:
876 " intentionally not setting 'lnum' so that the quickfix entries are not
877 " valid
878 eval qflist->setloclist(0, ' ')
879 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100880
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200881 " Test A
882 lrewind
883 enew
884 lopen
885 4lnext
886 vert split
887 wincmd L
888 lopen
889 wincmd p
890 lnext
891 let fileName = expand("%")
892 wincmd p
893 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
894 let fileName = substitute(fileName, '\\', '/', 'g')
895 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
896 call assert_equal("test://bar.txt", fileName)
897 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100898
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200899 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100900
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200901 " Test B:
902 lrewind
903 lopen
904 2
905 exe "normal \<CR>"
906 wincmd p
907 3
908 exe "normal \<CR>"
909 wincmd p
910 4
911 exe "normal \<CR>"
912 call assert_equal(2, winnr('$'))
913 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100914
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200915 " Test C:
916 lrewind
917 lopen
918 " Let's move the location list window to the top to check whether it (the
919 " first window found) will be reused when we try to open new windows:
920 wincmd K
921 2
922 exe "normal \<CR>"
923 wincmd p
924 3
925 exe "normal \<CR>"
926 wincmd p
927 4
928 exe "normal \<CR>"
929 1wincmd w
930 call assert_equal('quickfix', &buftype)
931 2wincmd w
932 let bufferName = expand("%")
933 let bufferName = substitute(bufferName, '\\', '/', 'g')
934 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100935
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200936 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100937
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200938 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100939endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100940
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100941func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200942 augroup testgroup
943 au!
944 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
945 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100946
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200947 func! R(n)
948 quit
949 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100950
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200951 new
952 let q = []
953 call add(q, {'filename': 'test_curwin.txt' })
954 call setloclist(0, q)
955 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100956
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200957 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100958endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100959
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100960func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200961 call writefile(['loclistfoo'], 'loclistfoo')
962 call writefile(['loclistbar'], 'loclistbar')
963 set switchbuf=usetab
964
965 edit loclistfoo
966 tabedit loclistbar
967 silent lgrep loclistfoo loclist*
968 call assert_equal(1, tabpagenr())
969
970 enew | only | tabonly
971 set switchbuf&vim
972 call delete('loclistfoo')
973 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100974endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200975
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100976" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100977func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200978 " The 'errorformat' setting is different on non-Unix systems.
979 " This test works only on Unix-like systems.
980 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100981
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200982 let l =<< trim [DATA]
983 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
984 "Xtestfile", line 6 col 19; this is an error
985 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
986 Xtestfile:9: parse error before `asd'
987 make: *** [vim] Error 1
988 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100989
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200990 2 returned
991 "Xtestfile", line 11 col 1; this is an error
992 "Xtestfile", line 12 col 2; this is another error
993 "Xtestfile", line 14:10; this is an error in column 10
994 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
995 "Xtestfile", linenr 16: yet another problem
996 Error in "Xtestfile" at line 17:
997 x should be a dot
998 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
999 ^
1000 Error in "Xtestfile" at line 18:
1001 x should be a dot
1002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1003 .............^
1004 Error in "Xtestfile" at line 19:
1005 x should be a dot
1006 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1007 --------------^
1008 Error in "Xtestfile" at line 20:
1009 x should be a dot
1010 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1011 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001012
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001013 Does anyone know what is the problem and how to correction it?
1014 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1015 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1016 [DATA]
1017
1018 call writefile(l, 'Xerrorfile1')
1019 call writefile(l[:-2], 'Xerrorfile2')
1020
1021 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001022 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1023 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1024 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1025 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1026 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1027 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1028 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1029 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1030 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1031 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1032 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1033 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1034 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1035 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1036 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1037 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1038 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1039 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1040 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1041 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1042 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1043[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001044 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001045
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001046 let save_efm = &efm
1047 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1048 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001049
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001050 exe 'cf Xerrorfile2'
1051 clast
1052 copen
1053 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1054 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001055
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001056 exe 'cf Xerrorfile1'
1057 call assert_equal([4, 12], [line('.'), col('.')])
1058 cn
1059 call assert_equal([6, 19], [line('.'), col('.')])
1060 cn
1061 call assert_equal([9, 2], [line('.'), col('.')])
1062 cn
1063 call assert_equal([10, 2], [line('.'), col('.')])
1064 cn
1065 call assert_equal([11, 1], [line('.'), col('.')])
1066 cn
1067 call assert_equal([12, 2], [line('.'), col('.')])
1068 cn
1069 call assert_equal([14, 10], [line('.'), col('.')])
1070 cn
1071 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1072 cn
1073 call assert_equal([16, 2], [line('.'), col('.')])
1074 cn
1075 call assert_equal([17, 6], [line('.'), col('.')])
1076 cn
1077 call assert_equal([18, 7], [line('.'), col('.')])
1078 cn
1079 call assert_equal([19, 8], [line('.'), col('.')])
1080 cn
1081 call assert_equal([20, 9], [line('.'), col('.')])
1082 clast
1083 cprev
1084 cprev
1085 wincmd w
1086 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1087 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001088
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001089 let &efm = save_efm
1090 call delete('Xerrorfile1')
1091 call delete('Xerrorfile2')
1092 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001093endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001094
Bram Moolenaarab47c612016-06-14 22:02:26 +02001095" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001096func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001097 call s:setup_commands(a:cchar)
1098
Bram Moolenaarab47c612016-06-14 22:02:26 +02001099 let save_efm=&efm
1100 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1101
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001102 let lines = ["Entering dir 'dir1/a'",
1103 \ 'habits2.txt:1:Nine Healthy Habits',
1104 \ "Entering dir 'b'",
1105 \ 'habits3.txt:2:0 Hours of television',
1106 \ 'habits2.txt:7:5 Small meals',
1107 \ "Entering dir 'dir1/c'",
1108 \ 'habits4.txt:3:1 Hour of exercise',
1109 \ "Leaving dir 'dir1/c'",
1110 \ "Leaving dir 'dir1/a'",
1111 \ 'habits1.txt:4:2 Liters of water',
1112 \ "Entering dir 'dir2'",
1113 \ 'habits5.txt:5:3 Cups of hot green tea',
1114 \ "Leaving dir 'dir2'"
1115 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001116
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001117 Xexpr ""
1118 for l in lines
1119 Xaddexpr l
1120 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001121
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001122 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001123
1124 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1125 call assert_equal(1, qf[1].lnum)
1126 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1127 call assert_equal(2, qf[3].lnum)
1128 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1129 call assert_equal(7, qf[4].lnum)
1130 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1131 call assert_equal(3, qf[6].lnum)
1132 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1133 call assert_equal(4, qf[9].lnum)
1134 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1135 call assert_equal(5, qf[11].lnum)
1136
1137 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001138endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001139
1140" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001141func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001142 " Create the directory stack and files
1143 call mkdir('dir1')
1144 call mkdir('dir1/a')
1145 call mkdir('dir1/a/b')
1146 call mkdir('dir1/c')
1147 call mkdir('dir2')
1148
1149 let lines = ["Nine Healthy Habits",
1150 \ "0 Hours of television",
1151 \ "1 Hour of exercise",
1152 \ "2 Liters of water",
1153 \ "3 Cups of hot green tea",
1154 \ "4 Short mental breaks",
1155 \ "5 Small meals",
1156 \ "6 AM wake up time",
1157 \ "7 Minutes of laughter",
1158 \ "8 Hours of sleep (at least)",
1159 \ "9 PM end of the day and off to bed"
1160 \ ]
1161 call writefile(lines, 'habits1.txt')
1162 call writefile(lines, 'dir1/a/habits2.txt')
1163 call writefile(lines, 'dir1/a/b/habits3.txt')
1164 call writefile(lines, 'dir1/c/habits4.txt')
1165 call writefile(lines, 'dir2/habits5.txt')
1166
1167 call s:dir_stack_tests('c')
1168 call s:dir_stack_tests('l')
1169
1170 call delete('dir1', 'rf')
1171 call delete('dir2', 'rf')
1172 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001173endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001174
Bram Moolenaar9b457942016-10-09 16:10:05 +02001175" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001176func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001177 call s:setup_commands(a:cchar)
1178
1179 let save_efm = &efm
1180
1181 let &efm =
1182 \ '%Eerror %m %l,' .
1183 \ '%-Wignored %m %l,' .
1184 \ '%+Cmore ignored %m %l,' .
1185 \ '%Zignored end'
1186 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1187 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1188 call assert_equal([['resync', 1, 4, 'E']], l)
1189
1190 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001191endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001192
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001193func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001194 call Xefm_ignore_continuations('c')
1195 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001196endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001197
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001198" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001199func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001200 call s:setup_commands(a:cchar)
1201
Bram Moolenaar049cba92016-06-26 14:38:04 +02001202 let save_efm = &efm
1203
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001204 set efm=%f:%l:%m,%f:%f:%l:%m
1205 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1206
1207 set efm=%f:%l:%m,%f:%l:%r:%m
1208 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1209
1210 set efm=%f:%l:%m,%O:%f:%l:%m
1211 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1212
1213 set efm=%f:%l:%m,%f:%l:%*[^a-z
1214 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1215
1216 set efm=%f:%l:%m,%f:%l:%*c
1217 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1218
1219 set efm=%f:%l:%m,%L%M%N
1220 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1221
1222 set efm=%f:%l:%m,%f:%l:%m:%R
1223 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1224
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001225 " Invalid regular expression
1226 set efm=%\\%%k
1227 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1228
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001229 set efm=
1230 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1231
1232 set efm=%DEntering\ dir\ abc,%f:%l:%m
1233 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1234
1235 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001236endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001237
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001238func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001239 call Xinvalid_efm_Tests('c')
1240 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001241endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001242
1243" TODO:
1244" Add tests for the following formats in 'errorformat'
1245" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001246func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001247 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001248
1249 " Test for %s format in efm
1250 set efm=%f:%s
1251 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001252 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001253 call assert_equal('^\VLine search text\$', l[0].pattern)
1254 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001255
Bram Moolenaaree85df32017-03-19 14:19:50 +01001256 let l = split(execute('clist', ''), "\n")
1257 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1258
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001259 " Test for a long line
1260 cexpr 'Xtestfile:' . repeat('a', 1026)
1261 let l = getqflist()
1262 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1263
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001264 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001265 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001266 [Xtestfile1]
1267 (1,17) error: ';' missing
1268 (21,2) warning: variable 'z' not defined
1269 (67,3) error: end of file found before string ended
1270 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001271
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001272 [Xtestfile2]
1273 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001274
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001275 [Xtestfile3]
1276 NEW compiler v1.1
1277 (2,2) warning: variable 'x' not defined
1278 (67,3) warning: 's' already defined
1279 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001280 [DATA]
1281
Bram Moolenaaree85df32017-03-19 14:19:50 +01001282 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001283 " To exercise the push/pop file functionality in quickfix, the test files
1284 " need to be created.
1285 call writefile(['Line1'], 'Xtestfile1')
1286 call writefile(['Line2'], 'Xtestfile2')
1287 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001288 cexpr ""
1289 for l in lines
1290 caddexpr l
1291 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001292 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001293 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001294 call assert_equal(21, l[2].lnum)
1295 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001296 call assert_equal('w', l[2].type)
1297 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001298 call delete('Xtestfile1')
1299 call delete('Xtestfile2')
1300 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001301
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001302 " Test for %P, %Q with non-existing files
1303 cexpr lines
1304 let l = getqflist()
1305 call assert_equal(14, len(l))
1306 call assert_equal('[Xtestfile1]', l[0].text)
1307 call assert_equal('[Xtestfile2]', l[6].text)
1308 call assert_equal('[Xtestfile3]', l[9].text)
1309
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001310 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001311 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001312 Error 275
1313 line 42
1314 column 3
1315 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001316 [DATA]
1317
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001318 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1319 cgetexpr lines
1320 let l = getqflist()
1321 call assert_equal(275, l[0].nr)
1322 call assert_equal(42, l[0].lnum)
1323 call assert_equal(3, l[0].col)
1324 call assert_equal('E', l[0].type)
1325 call assert_equal("\n' ' expected after '--'", l[0].text)
1326
1327 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001328 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001329 Error in line 147 of foo.c:
1330 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001331 [DATA]
1332
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001333 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1334 cgetexpr lines
1335 let l = getqflist()
1336 call assert_equal(147, l[0].lnum)
1337 call assert_equal('E', l[0].type)
1338 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001339
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001340 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001341 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001342 ==============================================================
1343 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1344 --------------------------------------------------------------
1345 Traceback (most recent call last):
1346 File "unittests/dbfacadeTest.py", line 89, in testFoo
1347 self.assertEquals(34, dtid)
1348 File "/usr/lib/python2.2/unittest.py", line 286, in
1349 failUnlessEqual
1350 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001351 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001352
1353 --------------------------------------------------------------
1354 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001355 [DATA]
1356
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001357 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001358 cgetexpr lines
1359 let l = getqflist()
1360 call assert_equal(8, len(l))
1361 call assert_equal(89, l[4].lnum)
1362 call assert_equal(1, l[4].valid)
1363 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001364 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001365
Bram Moolenaard76ce852018-05-01 15:02:04 +02001366 " Test for %o
1367 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001368 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1369 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001370 let l = getqflist()
1371 call assert_equal(1, len(l), string(l))
1372 call assert_equal('Language.PureScript.Types', l[0].module)
1373 copen
1374 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1375 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001376 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001377 cclose
1378 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001379 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001380
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001381 " Test for a long module name
1382 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1383 let l = getqflist()
1384 call assert_equal(repeat('m', 1024), l[0].module)
1385 call assert_equal(15, l[0].lnum)
1386 call assert_equal('message', l[0].text)
1387
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001388 " The following sequence of commands used to crash Vim
1389 set efm=%W%m
1390 cgetexpr ['msg1']
1391 let l = getqflist()
1392 call assert_equal(1, len(l), string(l))
1393 call assert_equal('msg1', l[0].text)
1394 set efm=%C%m
1395 lexpr 'msg2'
1396 let l = getloclist(0)
1397 call assert_equal(1, len(l), string(l))
1398 call assert_equal('msg2', l[0].text)
1399 lopen
1400 call setqflist([], 'r')
1401 caddbuf
1402 let l = getqflist()
1403 call assert_equal(1, len(l), string(l))
1404 call assert_equal('|| msg2', l[0].text)
1405
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001406 " When matching error lines, case should be ignored. Test for this.
1407 set noignorecase
1408 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1409 call assert_equal(10, l.items[0].lnum)
1410 call assert_equal('Line 20', l.items[0].text)
1411 set ignorecase&
1412
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001413 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001414 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001415endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001416
Bram Moolenaare9283662020-06-07 14:10:47 +02001417" Test for '%t' (error type) field in 'efm'
1418func Test_efm_error_type()
1419 let save_efm = &efm
1420
1421 " error type
1422 set efm=%f:%l:%t:%m
1423 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1424 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1425 let output = split(execute('clist'), "\n")
1426 call assert_equal([
1427 \ ' 1 Xfile1:10 error: msg1',
1428 \ ' 2 Xfile1:20 warning: msg2',
1429 \ ' 3 Xfile1:30 info: msg3',
1430 \ ' 4 Xfile1:40 note: msg4',
1431 \ ' 5 Xfile1:50 R: msg5'], output)
1432
1433 " error type and a error number
1434 set efm=%f:%l:%t:%n:%m
1435 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1436 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1437 let output = split(execute('clist'), "\n")
1438 call assert_equal([
1439 \ ' 1 Xfile1:10 error 2: msg1',
1440 \ ' 2 Xfile1:20 warning 4: msg2',
1441 \ ' 3 Xfile1:30 info 6: msg3',
1442 \ ' 4 Xfile1:40 note 8: msg4',
1443 \ ' 5 Xfile1:50 R 3: msg5'], output)
1444 let &efm = save_efm
1445endfunc
1446
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001447func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001448 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001449 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001450 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001451 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001452 colder
1453 cgetexpr []
1454 endfunc
1455 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001456 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001457 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001458 lolder
1459 lgetexpr []
1460 endfunc
1461 endif
1462
1463 augroup testgroup
1464 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001465 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001466 augroup END
1467
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001468 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001469 let words = [ "a", "b" ]
1470 let qflist = []
1471 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001472 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001473 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001474 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001475 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001476
1477 augroup! testgroup
1478endfunc
1479
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001480func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001481 call XquickfixChangedByAutocmd('c')
1482 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001483endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001484
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001485func Test_setloclist_in_autocommand()
1486 call writefile(['test1', 'test2'], 'Xfile')
1487 edit Xfile
1488 let s:bufnr = bufnr()
1489 call setloclist(1,
1490 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1491 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1492
1493 augroup Test_LocList
1494 au!
1495 autocmd BufEnter * call setloclist(1,
1496 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1497 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1498 augroup END
1499
1500 lopen
1501 call assert_fails('exe "normal j\<CR>"', 'E926:')
1502
1503 augroup Test_LocList
1504 au!
1505 augroup END
1506 call delete('Xfile')
1507endfunc
1508
Bram Moolenaar8b201792016-03-25 15:01:10 +01001509func Test_caddbuffer_to_empty()
1510 helpgr quickfix
1511 call setqflist([], 'r')
1512 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001513 try
1514 cn
1515 catch
1516 " number of matches is unknown
1517 call assert_true(v:exception =~ 'E553:')
1518 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001519 quit!
1520endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001521
1522func Test_cgetexpr_works()
1523 " this must not crash Vim
1524 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001525 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001526endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001527
1528" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001529func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001530 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001531
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001532 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001533 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001534 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001535 call assert_equal(2, len(l))
1536 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001537 call assert_equal(3, l[1].end_lnum)
1538 call assert_equal(4, l[1].col)
1539 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001540
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001541 Xnext
1542 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1543 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001544 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001545 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001546 call assert_equal(3, line('.'))
1547
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001548 " Appending entries to the list should not change the cursor position
1549 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001550 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001551 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001552 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001553 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1554 call assert_equal(1, line('.'))
1555 close
1556
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001557 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001558 \ {'bufnr': a:bnum, 'lnum': 4},
1559 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001560 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001561 call assert_equal(3, len(l))
1562 call assert_equal(5, l[2].lnum)
1563
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001564 call g:Xsetlist([])
1565 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001566 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001567
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001568 " Tests for setting the 'valid' flag
1569 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1570 Xwindow
1571 call assert_equal(1, winnr('$'))
1572 let l = g:Xgetlist()
1573 call g:Xsetlist(l)
1574 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001575 " Adding a non-valid entry should not mark the list as having valid entries
1576 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1577 Xwindow
1578 call assert_equal(1, winnr('$'))
1579
1580 " :cnext/:cprev should still work even with invalid entries in the list
1581 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1582 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1583 call g:Xsetlist(l)
1584 Xnext
1585 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1586 Xprev
1587 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1588 " :cnext/:cprev should still work after appending invalid entries to an
1589 " empty list
1590 call g:Xsetlist([])
1591 call g:Xsetlist(l, 'a')
1592 Xnext
1593 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1594 Xprev
1595 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1596
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001597 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1598 Xwindow
1599 call assert_equal(2, winnr('$'))
1600 Xclose
1601 let save_efm = &efm
1602 set efm=%m
1603 Xgetexpr 'TestMessage'
1604 let l = g:Xgetlist()
1605 call g:Xsetlist(l)
1606 call assert_equal(1, g:Xgetlist()[0].valid)
1607 let &efm = save_efm
1608
Bram Moolenaaree85df32017-03-19 14:19:50 +01001609 " Error cases:
1610 " Refer to a non-existing buffer and pass a non-dictionary type
1611 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1612 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1613 call g:Xsetlist([[1, 2,3]])
1614 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001615 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001616endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001617
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001618func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001619 new Xtestfile | only
1620 let bnum = bufnr('%')
1621 call setline(1, range(1,5))
1622
1623 call SetXlistTests('c', bnum)
1624 call SetXlistTests('l', bnum)
1625
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001626 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001627 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001628endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001629
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001630func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001631 call s:setup_commands(a:cchar)
1632
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001633 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001634 let @/ = 'Test_'
1635 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001636 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001637 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001638 Xvimgrep empty test_quickfix.vim
1639 call assert_true(len(g:Xgetlist()) > 0)
1640 Xvimgrep matches test_quickfix.vim
1641 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001642 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001643 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001644 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001645 call g:Xsetlist([], 'r')
1646 call assert_true(len(g:Xgetlist()) == 0)
1647 Xolder
1648 call assert_equal(testlen, len(g:Xgetlist()))
1649 Xnewer
1650 Xnewer
1651 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001652endfunc
1653
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001654func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001655 call Xlist_empty_middle('c')
1656 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001657endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001658
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001659func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001660 call s:setup_commands(a:cchar)
1661
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001662 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001663 Xvimgrep one test_quickfix.vim
1664 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001665 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001666 Xvimgrep two test_quickfix.vim
1667 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001668 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001669 Xvimgrep three test_quickfix.vim
1670 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001671 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001672 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001673 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001674 call g:Xsetlist([], 'r')
1675 call assert_true(len(g:Xgetlist()) == 0)
1676 Xnewer
1677 call assert_equal(twolen, len(g:Xgetlist()))
1678 Xnewer
1679 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001680endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001681
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001682func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001683 call Xlist_empty_older('c')
1684 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001685endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001686
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001687func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001688 call s:setup_commands(a:cchar)
1689
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001690 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1691 \ {'filename': 'fnameB', 'text': 'B'}]
1692 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1693 \ {'filename': 'fnameD', 'text': 'D'},
1694 \ {'filename': 'fnameE', 'text': 'E'}]
1695
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001696 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001697 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001698 silent! Xnewer 99
1699 call g:Xsetlist(list1)
1700 call g:Xsetlist(list2)
1701 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001702 call assert_equal(3, len(li))
1703 call assert_equal('C', li[0]['text'])
1704 call assert_equal('D', li[1]['text'])
1705 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001706 silent! Xolder
1707 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001708 call assert_equal(2, len(li))
1709 call assert_equal('A', li[0]['text'])
1710 call assert_equal('B', li[1]['text'])
1711
1712 " {action} is specified ' '.
1713 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001714 silent! Xnewer 99
1715 call g:Xsetlist(list1)
1716 call g:Xsetlist(list2, ' ')
1717 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001718 call assert_equal(3, len(li))
1719 call assert_equal('C', li[0]['text'])
1720 call assert_equal('D', li[1]['text'])
1721 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001722 silent! Xolder
1723 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001724 call assert_equal(2, len(li))
1725 call assert_equal('A', li[0]['text'])
1726 call assert_equal('B', li[1]['text'])
1727
1728 " {action} is specified 'a'.
1729 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001730 silent! Xnewer 99
1731 call g:Xsetlist(list1)
1732 call g:Xsetlist(list2, 'a')
1733 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001734 call assert_equal(5, len(li))
1735 call assert_equal('A', li[0]['text'])
1736 call assert_equal('B', li[1]['text'])
1737 call assert_equal('C', li[2]['text'])
1738 call assert_equal('D', li[3]['text'])
1739 call assert_equal('E', li[4]['text'])
1740
1741 " {action} is specified 'r'.
1742 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001743 silent! Xnewer 99
1744 call g:Xsetlist(list1)
1745 call g:Xsetlist(list2, 'r')
1746 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001747 call assert_equal(3, len(li))
1748 call assert_equal('C', li[0]['text'])
1749 call assert_equal('D', li[1]['text'])
1750 call assert_equal('E', li[2]['text'])
1751
1752 " Test for wrong value.
1753 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001754 call assert_fails("call g:Xsetlist(0)", 'E714:')
1755 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1756 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1757 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1758 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001759endfunc
1760
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001761func Test_setqflist_invalid_nr()
1762 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001763 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001764endfunc
1765
Bram Moolenaar99234f22020-02-10 22:56:54 +01001766func Test_setqflist_user_sets_buftype()
1767 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1768 set buftype=quickfix
1769 call setqflist([], 'a')
1770 enew
1771endfunc
1772
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001773func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001774 call XquickfixSetListWithAct('c')
1775 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001776endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001777
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001778func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001779 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001780
Bram Moolenaar049cba92016-06-26 14:38:04 +02001781 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001782 call assert_equal(1, l[0].lnum)
1783 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001784 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001785 call assert_equal(2, l[1].lnum)
1786 call assert_equal(1, l[1].col)
1787 call assert_equal(4070, len(l[1].text))
1788 call assert_equal(3, l[2].lnum)
1789 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001790 call assert_equal(4070, len(l[2].text))
1791 call assert_equal(4, l[3].lnum)
1792 call assert_equal(1, l[3].col)
1793 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001794
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001795 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001796endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001797
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001798func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001799 call s:setup_commands(a:cchar)
1800
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001801 let testfile = 'samples/quickfix.txt'
1802
1803 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001804 exe 'Xgetfile' testfile
1805 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001806
1807 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001808 Xexpr readfile(testfile)
1809 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001810
1811 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001812 Xexpr join(readfile(testfile), "\n")
1813 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001814
1815 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001816 exe 'edit' testfile
1817 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001818 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001819endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001820
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001821func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001822 call s:long_lines_tests('c')
1823 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001824endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001825
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001826func Test_cgetfile_on_long_lines()
1827 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1828 " are read at a time.
1829 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1830 let lines = [
1831 \ '/tmp/file1:1:1:aaa',
1832 \ '/tmp/file2:1:1:%s',
1833 \ '/tmp/file3:1:1:bbb',
1834 \ '/tmp/file4:1:1:ccc',
1835 \ ]
1836 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1837 call writefile(lines, 'Xcqetfile.txt')
1838 cgetfile Xcqetfile.txt
1839 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1840 endfor
1841 call delete('Xcqetfile.txt')
1842endfunc
1843
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001844func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001845 let l = []
1846 for i in range(1, 20)
1847 call add(l, 'Line' . i)
1848 endfor
1849 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001850endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001851
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001852func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001853 call s:create_test_file('Xqftestfile1')
1854 call s:create_test_file('Xqftestfile2')
1855 call s:create_test_file('Xqftestfile3')
1856
1857 new | only
1858 edit Xqftestfile1
1859 let file1_winid = win_getid()
1860 new Xqftestfile2
1861 let file2_winid = win_getid()
1862 cgetexpr ['Xqftestfile1:5:Line5',
1863 \ 'Xqftestfile1:6:Line6',
1864 \ 'Xqftestfile2:10:Line10',
1865 \ 'Xqftestfile2:11:Line11',
1866 \ 'Xqftestfile3:15:Line15',
1867 \ 'Xqftestfile3:16:Line16']
1868
1869 new
1870 let winid = win_getid()
1871 cfirst | cnext
1872 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001873 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001874 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001875 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001876 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001877
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001878 " Test for 'switchbuf' set to search for files in windows in the current
1879 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001880 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001881 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001882 cfirst | cnext
1883 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001884 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001885 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001886 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001887 call assert_equal(file2_winid, win_getid())
1888
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001889 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1890 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001891 enew | only
1892 set switchbuf=usetab
1893 tabedit Xqftestfile1
1894 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001895 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001896 tabfirst
1897 cfirst | cnext
1898 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001899 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001901 6cnext
1902 call assert_equal(4, tabpagenr())
1903 2cpfile
1904 call assert_equal(2, tabpagenr())
1905 2cnfile
1906 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001907 tabfirst | tabonly | enew
1908
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001909 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001910 set switchbuf=split
1911 cfirst | cnext
1912 call assert_equal(1, winnr('$'))
1913 cnext | cnext
1914 call assert_equal(2, winnr('$'))
1915 cnext | cnext
1916 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001917
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001918 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001919 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001920 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001921 cfirst | cnext
1922 call assert_equal(1, tabpagenr('$'))
1923 cnext | cnext
1924 call assert_equal(2, tabpagenr('$'))
1925 cnext | cnext
1926 call assert_equal(3, tabpagenr('$'))
1927 tabfirst | enew | tabonly | only
1928
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001929 set switchbuf=uselast
1930 split
1931 let last_winid = win_getid()
1932 copen
1933 exe "normal 1G\<CR>"
1934 call assert_equal(last_winid, win_getid())
1935 enew | only
1936
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001937 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1938 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001939 set switchbuf=
1940 edit Xqftestfile1
1941 let file1_winid = win_getid()
1942 new Xqftestfile2
1943 let file2_winid = win_getid()
1944 copen
1945 exe "normal 1G\<CR>"
1946 call assert_equal(file1_winid, win_getid())
1947 copen
1948 exe "normal 3G\<CR>"
1949 call assert_equal(file2_winid, win_getid())
1950 copen | only
1951 exe "normal 5G\<CR>"
1952 call assert_equal(2, winnr('$'))
1953 call assert_equal(1, bufwinnr('Xqftestfile3'))
1954
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001955 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001956 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001957 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001958 set switchbuf=usetab
1959 tabedit Xqftestfile1
1960 tabedit Xqftestfile2
1961 tabedit Xqftestfile3
1962 tabfirst
1963 copen | only
1964 clast
1965 call assert_equal(4, tabpagenr())
1966 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001967
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001968 " Jumping to a file that is not present in any of the tabpages and the
1969 " current tabpage doesn't have any usable windows, should open it in a new
1970 " window in the current tabpage.
1971 copen | only
1972 cfirst
1973 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001974 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001975
1976 " If opening a file changes 'switchbuf', then the new value should be
1977 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001978 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001979 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1980 enew | only
1981 set switchbuf&vim
1982 cexpr "Xqftestfile1:1:10"
1983 call assert_equal('split', &switchbuf)
1984 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1985 enew | only
1986 set switchbuf=useopen
1987 cexpr "Xqftestfile1:1:10"
1988 call assert_equal('usetab', &switchbuf)
1989 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1990 enew | only
1991 set switchbuf=useopen
1992 cexpr "Xqftestfile1:1:10"
1993 call assert_equal('', &switchbuf)
1994
Bram Moolenaar049cba92016-06-26 14:38:04 +02001995 call delete('Xqftestfile1')
1996 call delete('Xqftestfile2')
1997 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001998 set switchbuf&vim
1999
2000 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002001endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002002
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002003func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002004 call s:setup_commands(a:cchar)
2005
2006 enew | only
2007
Bram Moolenaarc1542742016-07-20 21:44:37 +02002008 let fname = 'Xqftestfile' . a:cchar
2009 call s:create_test_file(fname)
2010 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002011
Bram Moolenaarc1542742016-07-20 21:44:37 +02002012 Xgetexpr [fname . ':5:Line5',
2013 \ fname . ':10:Line10',
2014 \ fname . ':15:Line15',
2015 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002016
2017 6,14delete
2018 call append(6, ['Buffer', 'Window'])
2019
2020 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002021 call assert_equal(5, l[0].lnum)
2022 call assert_equal(6, l[2].lnum)
2023 call assert_equal(13, l[3].lnum)
2024
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002025 " If a file doesn't have any quickfix entries, then deleting lines in the
2026 " file should not update the quickfix list
2027 call g:Xsetlist([], 'f')
2028 1,2delete
2029 call assert_equal([], g:Xgetlist())
2030
Bram Moolenaar049cba92016-06-26 14:38:04 +02002031 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002032 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002033endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002034
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002035func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002036 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002037 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002038 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002039 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002040endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002041
2042" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002043func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002044 call s:setup_commands(a:cchar)
2045
2046 " The following lines are used for the grep test. Don't remove.
2047 " Grep_Test_Text: Match 1
2048 " Grep_Test_Text: Match 2
2049 " GrepAdd_Test_Text: Match 1
2050 " GrepAdd_Test_Text: Match 2
2051 enew! | only
2052 set makeef&vim
2053 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002054 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002055 Xopen
2056 call assert_true(w:quickfix_title =~ '^:grep')
2057 Xclose
2058 enew
2059 set makeef=Temp_File_##
2060 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002061 call assert_true(len(g:Xgetlist()) == 9)
2062
2063 " Try with 'grepprg' set to 'internal'
2064 set grepprg=internal
2065 silent Xgrep Grep_Test_Text: test_quickfix.vim
2066 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2067 call assert_true(len(g:Xgetlist()) == 9)
2068 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002069
2070 call writefile(['Vim'], 'XtestTempFile')
2071 set makeef=XtestTempFile
2072 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002073 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002074 call assert_false(filereadable('XtestTempFile'))
2075 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002076endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002077
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002078func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002079 " The grepprg may not be set on non-Unix systems
2080 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002081
2082 call s:test_xgrep('c')
2083 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002084endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002085
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002086func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002087 " Use one 'errorformat' for two windows. Add an expression to each of them,
2088 " make sure they each keep their own state.
2089 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2090 call mkdir('Xone/a', 'p')
2091 call mkdir('Xtwo/a', 'p')
2092 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2093 call writefile(lines, 'Xone/a/one.txt')
2094 call writefile(lines, 'Xtwo/a/two.txt')
2095
2096 new one
2097 let one_id = win_getid()
2098 lexpr ""
2099 new two
2100 let two_id = win_getid()
2101 lexpr ""
2102
2103 laddexpr "Entering dir 'Xtwo/a'"
2104 call win_gotoid(one_id)
2105 laddexpr "Entering dir 'Xone/a'"
2106 call win_gotoid(two_id)
2107 laddexpr 'two.txt:5:two two two'
2108 call win_gotoid(one_id)
2109 laddexpr 'one.txt:3:one one one'
2110
2111 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002112 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2113 call assert_equal(3, loc_one[1].lnum)
2114
2115 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002116 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2117 call assert_equal(5, loc_two[1].lnum)
2118
2119 call win_gotoid(one_id)
2120 bwipe!
2121 call win_gotoid(two_id)
2122 bwipe!
2123 call delete('Xone', 'rf')
2124 call delete('Xtwo', 'rf')
2125endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002126
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002127func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002128 call s:setup_commands(a:cchar)
2129
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002130 " Calling lbottom without any errors should fail
2131 if a:cchar == 'l'
2132 call assert_fails('lbottom', 'E776:')
2133 endif
2134
Bram Moolenaar875feea2017-06-11 16:07:51 +02002135 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002136 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002137 let wid = win_getid()
2138 call assert_equal(1, line('.'))
2139 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002140 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002141 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002142 call win_gotoid(wid)
2143 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002144 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002145endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002146
2147" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002148func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002149 call XbottomTests('c')
2150 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002151endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002152
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002153func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002154 call s:setup_commands(a:cchar)
2155
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002156 " clear all lists after the first one, then replace the first one.
2157 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002158 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002159 let entry = {'filename': 'foo', 'lnum': 42}
2160 call g:Xsetlist([entry], 'r')
2161 call g:Xsetlist([entry, entry])
2162 call g:Xsetlist([entry, entry, entry])
2163 let res = split(execute(a:cchar . 'hist'), "\n")
2164 call assert_equal(3, len(res))
2165 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2166 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2167 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2168 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002169
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002170 " Test for changing the quickfix lists
2171 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2172 exe '1' . a:cchar . 'hist'
2173 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2174 exe '3' . a:cchar . 'hist'
2175 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2176 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2177 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2178
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002179 call g:Xsetlist([], 'f')
2180 let l = split(execute(a:cchar . 'hist'), "\n")
2181 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002182 if a:cchar == 'c'
2183 call assert_fails('4chist', 'E16:')
2184 else
2185 call assert_fails('4lhist', 'E776:')
2186 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002187
2188 " An empty list should still show the stack history
2189 call g:Xsetlist([])
2190 let res = split(execute(a:cchar . 'hist'), "\n")
2191 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2192
2193 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002194endfunc
2195
2196func Test_history()
2197 call HistoryTest('c')
2198 call HistoryTest('l')
2199endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002200
2201func Test_duplicate_buf()
2202 " make sure we can get the highest buffer number
2203 edit DoesNotExist
2204 edit DoesNotExist2
2205 let last_buffer = bufnr("$")
2206
2207 " make sure only one buffer is created
2208 call writefile(['this one', 'that one'], 'Xgrepthis')
2209 vimgrep one Xgrepthis
2210 vimgrep one Xgrepthis
2211 call assert_equal(last_buffer + 1, bufnr("$"))
2212
2213 call delete('Xgrepthis')
2214endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002215
2216" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002217func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002218 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002219
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002220 " Error cases
2221 call assert_fails('call g:Xgetlist(99)', 'E715:')
2222 call assert_fails('call g:Xsetlist(99)', 'E714:')
2223 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002224
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002225 " Set and get the title
2226 call g:Xsetlist([])
2227 Xopen
2228 wincmd p
2229 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2230 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2231 call assert_equal(0, s)
2232 let d = g:Xgetlist({"title":1})
2233 call assert_equal('Sample', d.title)
2234 " Try setting title to a non-string value
2235 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2236 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2237
2238 Xopen
2239 call assert_equal('Sample', w:quickfix_title)
2240 Xclose
2241
2242 " Tests for action argument
2243 silent! Xolder 999
2244 let qfnr = g:Xgetlist({'all':1}).nr
2245 call g:Xsetlist([], 'r', {'title' : 'N1'})
2246 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2247 call g:Xsetlist([], ' ', {'title' : 'N2'})
2248 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2249
2250 let res = g:Xgetlist({'nr': 0})
2251 call assert_equal(qfnr + 1, res.nr)
2252 call assert_equal(['nr'], keys(res))
2253
2254 call g:Xsetlist([], ' ', {'title' : 'N3'})
2255 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2256
2257 " Changing the title of an earlier quickfix list
2258 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2259 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2260
2261 " Changing the title of an invalid quickfix list
2262 call assert_equal(-1, g:Xsetlist([], ' ',
2263 \ {'title' : 'SomeTitle', 'nr' : 99}))
2264 call assert_equal(-1, g:Xsetlist([], ' ',
2265 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2266
2267 if a:cchar == 'c'
2268 copen
2269 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2270 cclose
2271 endif
2272
2273 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002274 call assert_fails('call g:Xgetlist([])', 'E715:')
2275 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002276 let s = g:Xsetlist([], 'a', {'abc':1})
2277 call assert_equal(-1, s)
2278
2279 call assert_equal({}, g:Xgetlist({'abc':1}))
2280 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2281 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2282
2283 if a:cchar == 'l'
2284 call assert_equal({}, getloclist(99, {'title': 1}))
2285 endif
2286
2287 " Context related tests
2288 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2289 call assert_equal(0, s)
2290 call test_garbagecollect_now()
2291 let d = g:Xgetlist({'context':1})
2292 call assert_equal([1,2,3], d.context)
2293 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2294 let d = g:Xgetlist({'context':1})
2295 call assert_equal({'color':'green'}, d.context)
2296 call g:Xsetlist([], 'a', {'context':"Context info"})
2297 let d = g:Xgetlist({'context':1})
2298 call assert_equal("Context info", d.context)
2299 call g:Xsetlist([], 'a', {'context':246})
2300 let d = g:Xgetlist({'context':1})
2301 call assert_equal(246, d.context)
2302 " set other Vim data types as context
2303 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2304 if has('channel')
2305 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2306 endif
2307 if has('job')
2308 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2309 endif
2310 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2311 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2312 call g:Xsetlist([], 'a', {'context' : ''})
2313 call test_garbagecollect_now()
2314 if a:cchar == 'l'
2315 " Test for copying context across two different location lists
2316 new | only
2317 let w1_id = win_getid()
2318 let l = [1]
2319 call setloclist(0, [], 'a', {'context':l})
2320 new
2321 let w2_id = win_getid()
2322 call add(l, 2)
2323 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2324 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2325 unlet! l
2326 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2327 only
2328 call setloclist(0, [], 'f')
2329 call assert_equal('', getloclist(0, {'context':1}).context)
2330 endif
2331
2332 " Test for changing the context of previous quickfix lists
2333 call g:Xsetlist([], 'f')
2334 Xexpr "One"
2335 Xexpr "Two"
2336 Xexpr "Three"
2337 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2338 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2339 " Also, check for setting the context using quickfix list number zero.
2340 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2341 call test_garbagecollect_now()
2342 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2343 call assert_equal([1], l.context)
2344 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2345 call assert_equal([2], l.context)
2346 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2347 call assert_equal([3], l.context)
2348
2349 " Test for changing the context through reference and for garbage
2350 " collection of quickfix context
2351 let l = ["red"]
2352 call g:Xsetlist([], ' ', {'context' : l})
2353 call add(l, "blue")
2354 let x = g:Xgetlist({'context' : 1})
2355 call add(x.context, "green")
2356 call assert_equal(["red", "blue", "green"], l)
2357 call assert_equal(["red", "blue", "green"], x.context)
2358 unlet l
2359 call test_garbagecollect_now()
2360 let m = g:Xgetlist({'context' : 1})
2361 call assert_equal(["red", "blue", "green"], m.context)
2362
2363 " Test for setting/getting items
2364 Xexpr ""
2365 let qfprev = g:Xgetlist({'nr':0})
2366 let s = g:Xsetlist([], ' ', {'title':'Green',
2367 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2368 call assert_equal(0, s)
2369 let qfcur = g:Xgetlist({'nr':0})
2370 call assert_true(qfcur.nr == qfprev.nr + 1)
2371 let l = g:Xgetlist({'items':1})
2372 call assert_equal('F1', bufname(l.items[0].bufnr))
2373 call assert_equal(10, l.items[0].lnum)
2374 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2375 \ {'filename':'F2', 'lnum':30}]})
2376 let l = g:Xgetlist({'items':1})
2377 call assert_equal('F2', bufname(l.items[2].bufnr))
2378 call assert_equal(30, l.items[2].lnum)
2379 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2380 let l = g:Xgetlist({'items':1})
2381 call assert_equal('F3', bufname(l.items[0].bufnr))
2382 call assert_equal(40, l.items[0].lnum)
2383 call g:Xsetlist([], 'r', {'items' : []})
2384 let l = g:Xgetlist({'items':1})
2385 call assert_equal(0, len(l.items))
2386
2387 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2388 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2389 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2390 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2391
2392 " Test for getting id of window associated with a location list window
2393 if a:cchar == 'l'
2394 only
2395 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2396 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002397 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002398 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2399 wincmd w
2400 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2401 only
2402 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002403
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002404 " The following used to crash Vim with address sanitizer
2405 call g:Xsetlist([], 'f')
2406 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2407 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002408
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002409 " Try setting the items using a string
2410 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002411
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002412 " Save and restore the quickfix stack
2413 call g:Xsetlist([], 'f')
2414 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2415 Xexpr "File1:10:Line1"
2416 Xexpr "File2:20:Line2"
2417 Xexpr "File3:30:Line3"
2418 let last_qf = g:Xgetlist({'nr':'$'}).nr
2419 call assert_equal(3, last_qf)
2420 let qstack = []
2421 for i in range(1, last_qf)
2422 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2423 endfor
2424 call g:Xsetlist([], 'f')
2425 for i in range(len(qstack))
2426 call g:Xsetlist([], ' ', qstack[i])
2427 endfor
2428 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2429 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2430 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2431 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2432 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002433
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002434 " Swap two quickfix lists
2435 Xexpr "File1:10:Line10"
2436 Xexpr "File2:20:Line20"
2437 Xexpr "File3:30:Line30"
2438 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2439 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2440 let l1=g:Xgetlist({'nr':1,'all':1})
2441 let l2=g:Xgetlist({'nr':2,'all':1})
2442 let save_id = l1.id
2443 let l1.id=l2.id
2444 let l2.id=save_id
2445 call g:Xsetlist([], 'r', l1)
2446 call g:Xsetlist([], 'r', l2)
2447 let newl1=g:Xgetlist({'nr':1,'all':1})
2448 let newl2=g:Xgetlist({'nr':2,'all':1})
2449 call assert_equal('Fruits', newl1.title)
2450 call assert_equal(['Fruits'], newl1.context)
2451 call assert_equal('Line20', newl1.items[0].text)
2452 call assert_equal('Colors', newl2.title)
2453 call assert_equal(['Colors'], newl2.context)
2454 call assert_equal('Line10', newl2.items[0].text)
2455 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002456
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002457 " Cannot specify both a non-empty list argument and a dict argument
2458 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002459endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002460
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002461func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002462 call Xproperty_tests('c')
2463 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002464endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002465
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002466" Test for setting the current index in the location/quickfix list
2467func Xtest_setqfidx(cchar)
2468 call s:setup_commands(a:cchar)
2469
2470 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2471 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2472 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2473
2474 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2475 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2476 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2477 Xolder 2
2478 Xopen
2479 call assert_equal(3, line('.'))
2480 Xnewer
2481 call assert_equal(2, line('.'))
2482 Xnewer
2483 call assert_equal(2, line('.'))
2484 " Update the current index with the quickfix window open
2485 wincmd w
2486 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2487 Xopen
2488 call assert_equal(3, line('.'))
2489 Xclose
2490
2491 " Set the current index to the last entry
2492 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2493 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2494 " A large value should set the index to the last index
2495 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2496 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2497 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2498 " Invalid index values
2499 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2500 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2501 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2502 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2503 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2504 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2505 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2506
2507 call g:Xsetlist([], 'f')
2508 new | only
2509endfunc
2510
2511func Test_setqfidx()
2512 call Xtest_setqfidx('c')
2513 call Xtest_setqfidx('l')
2514endfunc
2515
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002516" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002517func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002518 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002519endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002520
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002521func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002522 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2523 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2524
2525 let g:acmds = []
2526 cexpr "F1:10:Line 10"
2527 caddexpr "F1:20:Line 20"
2528 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002529 cexpr ""
2530 caddexpr ""
2531 cgetexpr ""
2532 silent! cexpr non_existing_func()
2533 silent! caddexpr non_existing_func()
2534 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002535 let l = ['precexpr',
2536 \ 'postcexpr',
2537 \ 'precaddexpr',
2538 \ 'postcaddexpr',
2539 \ 'precgetexpr',
2540 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002541 \ 'precexpr',
2542 \ 'postcexpr',
2543 \ 'precaddexpr',
2544 \ 'postcaddexpr',
2545 \ 'precgetexpr',
2546 \ 'postcgetexpr',
2547 \ 'precexpr',
2548 \ 'precaddexpr',
2549 \ 'precgetexpr']
2550 call assert_equal(l, g:acmds)
2551
2552 let g:acmds = []
2553 enew! | call append(0, "F2:10:Line 10")
2554 cbuffer!
2555 enew! | call append(0, "F2:20:Line 20")
2556 cgetbuffer
2557 enew! | call append(0, "F2:30:Line 30")
2558 caddbuffer
2559 new
2560 let bnum = bufnr('%')
2561 bunload
2562 exe 'silent! cbuffer! ' . bnum
2563 exe 'silent! cgetbuffer ' . bnum
2564 exe 'silent! caddbuffer ' . bnum
2565 enew!
2566 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002567 \ 'postcbuffer',
2568 \ 'precgetbuffer',
2569 \ 'postcgetbuffer',
2570 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002571 \ 'postcaddbuffer',
2572 \ 'precbuffer',
2573 \ 'precgetbuffer',
2574 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002575 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002576
2577 call writefile(['Xtest:1:Line1'], 'Xtest')
2578 call writefile([], 'Xempty')
2579 let g:acmds = []
2580 cfile Xtest
2581 caddfile Xtest
2582 cgetfile Xtest
2583 cfile Xempty
2584 caddfile Xempty
2585 cgetfile Xempty
2586 silent! cfile do_not_exist
2587 silent! caddfile do_not_exist
2588 silent! cgetfile do_not_exist
2589 let l = ['precfile',
2590 \ 'postcfile',
2591 \ 'precaddfile',
2592 \ 'postcaddfile',
2593 \ 'precgetfile',
2594 \ 'postcgetfile',
2595 \ 'precfile',
2596 \ 'postcfile',
2597 \ 'precaddfile',
2598 \ 'postcaddfile',
2599 \ 'precgetfile',
2600 \ 'postcgetfile',
2601 \ 'precfile',
2602 \ 'postcfile',
2603 \ 'precaddfile',
2604 \ 'postcaddfile',
2605 \ 'precgetfile',
2606 \ 'postcgetfile']
2607 call assert_equal(l, g:acmds)
2608
2609 let g:acmds = []
2610 helpgrep quickfix
2611 silent! helpgrep non_existing_help_topic
2612 vimgrep test Xtest
2613 vimgrepadd test Xtest
2614 silent! vimgrep non_existing_test Xtest
2615 silent! vimgrepadd non_existing_test Xtest
2616 set makeprg=
2617 silent! make
2618 set makeprg&
2619 let l = ['prehelpgrep',
2620 \ 'posthelpgrep',
2621 \ 'prehelpgrep',
2622 \ 'posthelpgrep',
2623 \ 'previmgrep',
2624 \ 'postvimgrep',
2625 \ 'previmgrepadd',
2626 \ 'postvimgrepadd',
2627 \ 'previmgrep',
2628 \ 'postvimgrep',
2629 \ 'previmgrepadd',
2630 \ 'postvimgrepadd',
2631 \ 'premake',
2632 \ 'postmake']
2633 call assert_equal(l, g:acmds)
2634
2635 if has('unix')
2636 " Run this test only on Unix-like systems. The grepprg may not be set on
2637 " non-Unix systems.
2638 " The following lines are used for the grep test. Don't remove.
2639 " Grep_Autocmd_Text: Match 1
2640 " GrepAdd_Autocmd_Text: Match 2
2641 let g:acmds = []
2642 silent grep Grep_Autocmd_Text test_quickfix.vim
2643 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2644 silent grep abc123def Xtest
2645 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002646 set grepprg=internal
2647 silent grep Grep_Autocmd_Text test_quickfix.vim
2648 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2649 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2650 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2651 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002652 let l = ['pregrep',
2653 \ 'postgrep',
2654 \ 'pregrepadd',
2655 \ 'postgrepadd',
2656 \ 'pregrep',
2657 \ 'postgrep',
2658 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002659 \ 'postgrepadd',
2660 \ 'pregrep',
2661 \ 'postgrep',
2662 \ 'pregrepadd',
2663 \ 'postgrepadd',
2664 \ 'prelgrep',
2665 \ 'postlgrep',
2666 \ 'prelgrepadd',
2667 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002668 call assert_equal(l, g:acmds)
2669 endif
2670
2671 call delete('Xtest')
2672 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002673 au! QuickFixCmdPre
2674 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002675endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002676
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002677func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002678 set efm=%m
2679 lgetexpr '?'
2680
2681 try
2682 call DoesNotExit()
2683 catch
2684 lgetexpr '1'
2685 finally
2686 lgetexpr '1'
2687 endtry
2688
2689 call assert_equal('1', getloclist(0)[0].text)
2690
2691 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002692endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002693
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002694func Test_caddbuffer_wrong()
2695 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002696 let save_efm = &efm
2697 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2698 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2699 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002700 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002701 bwipe!
2702endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002703
2704func Test_caddexpr_wrong()
2705 " This used to cause a memory access in freed memory.
2706 cbuffer
2707 cbuffer
2708 copen
2709 let save_efm = &efm
2710 set efm=%
2711 call assert_fails('caddexpr ""', 'E376:')
2712 let &efm = save_efm
2713endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002714
2715func Test_dirstack_cleanup()
2716 " This used to cause a memory access in freed memory.
2717 let save_efm = &efm
2718 lexpr '0'
2719 lopen
2720 fun X(c)
2721 let save_efm=&efm
2722 set efm=%D%f
2723 if a:c == 'c'
2724 caddexpr '::'
2725 else
2726 laddexpr ':0:0'
2727 endif
2728 let &efm=save_efm
2729 endfun
2730 call X('c')
2731 call X('l')
2732 call setqflist([], 'r')
2733 caddbuffer
2734 let &efm = save_efm
2735endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002736
2737" Tests for jumping to entries from the location list window and quickfix
2738" window
2739func Test_cwindow_jump()
2740 set efm=%f%%%l%%%m
2741 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2742 lopen | only
2743 lfirst
2744 call assert_true(winnr('$') == 2)
2745 call assert_true(winnr() == 1)
2746 " Location list for the new window should be set
2747 call assert_true(getloclist(0)[2].text == 'Line 30')
2748
2749 " Open a scratch buffer
2750 " Open a new window and create a location list
2751 " Open the location list window and close the other window
2752 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002753 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002754 " should not be used.
2755 enew | only
2756 set buftype=nofile
2757 below new
2758 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2759 lopen
2760 2wincmd c
2761 lnext
2762 call assert_true(winnr('$') == 3)
2763 call assert_true(winnr() == 2)
2764
2765 " Open two windows with two different location lists
2766 " Open the location list window and close the previous window
2767 " Jump to an entry in the location list window
2768 " Should open the file in the first window and not set the location list.
2769 enew | only
2770 lgetexpr ["F1%5%Line 5"]
2771 below new
2772 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2773 lopen
2774 2wincmd c
2775 lnext
2776 call assert_true(winnr() == 1)
2777 call assert_true(getloclist(0)[0].text == 'Line 5')
2778
2779 enew | only
2780 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2781 copen
2782 cnext
2783 call assert_true(winnr('$') == 2)
2784 call assert_true(winnr() == 1)
2785
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002786 " open the quickfix buffer in two windows and jump to an entry. Should open
2787 " the file in the first quickfix window.
2788 enew | only
2789 copen
2790 let bnum = bufnr('')
2791 exe 'sbuffer ' . bnum
2792 wincmd b
2793 cfirst
2794 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002795 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002796 enew | only
2797 exe 'sb' bnum
2798 exe 'botright sb' bnum
2799 wincmd t
2800 clast
2801 call assert_equal(2, winnr())
2802 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2803 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2804
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002805 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002806 " window by wrapping around the window list.
2807 enew | only
2808 call setloclist(0, [], 'f')
2809 new | new
2810 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2811 lopen
2812 1close
2813 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2814 lnext
2815 call assert_equal(3, winnr())
2816 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2817
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002818 enew | only
2819 set efm&vim
2820endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002821
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002822func Test_cwindow_highlight()
2823 CheckScreendump
2824
2825 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002826 call setline(1, ['some', 'text', 'with', 'matches'])
2827 write XCwindow
2828 vimgrep e XCwindow
2829 redraw
2830 cwindow 4
2831 END
2832 call writefile(lines, 'XtestCwindow')
2833 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2834 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2835
2836 call term_sendkeys(buf, ":cnext\<CR>")
2837 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2838
2839 " clean up
2840 call StopVimInTerminal(buf)
2841 call delete('XtestCwindow')
2842 call delete('XCwindow')
2843endfunc
2844
Bram Moolenaaree85df32017-03-19 14:19:50 +01002845func XvimgrepTests(cchar)
2846 call s:setup_commands(a:cchar)
2847
2848 call writefile(['Editor:VIM vim',
2849 \ 'Editor:Emacs EmAcS',
2850 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2851 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2852
2853 " Error cases
2854 call assert_fails('Xvimgrep /abc *', 'E682:')
2855
2856 let @/=''
2857 call assert_fails('Xvimgrep // *', 'E35:')
2858
2859 call assert_fails('Xvimgrep abc', 'E683:')
2860 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2861 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2862
2863 Xexpr ""
2864 Xvimgrepadd Notepad Xtestfile1
2865 Xvimgrepadd MacOS Xtestfile2
2866 let l = g:Xgetlist()
2867 call assert_equal(2, len(l))
2868 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2869
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002870 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002871 let l = g:Xgetlist()
2872 call assert_equal(2, len(l))
2873 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002874 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002875 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002876 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002877
2878 1Xvimgrep ?Editor? Xtestfile*
2879 let l = g:Xgetlist()
2880 call assert_equal(1, len(l))
2881 call assert_equal('Editor:VIM vim', l[0].text)
2882
2883 edit +3 Xtestfile2
2884 Xvimgrep +\cemacs+j Xtestfile1
2885 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002886 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002887 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2888
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002889 " Test for unloading a buffer after vimgrep searched the buffer
2890 %bwipe
2891 Xvimgrep /Editor/j Xtestfile*
2892 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2893 call assert_equal([], getbufinfo('Xtestfile2'))
2894
Bram Moolenaaree85df32017-03-19 14:19:50 +01002895 call delete('Xtestfile1')
2896 call delete('Xtestfile2')
2897endfunc
2898
2899" Tests for the :vimgrep command
2900func Test_vimgrep()
2901 call XvimgrepTests('c')
2902 call XvimgrepTests('l')
2903endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002904
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002905func Test_vimgrep_wildcards_expanded_once()
2906 new X[id-01] file.txt
2907 call setline(1, 'some text to search for')
2908 vimgrep text %
2909 bwipe!
2910endfunc
2911
Bram Moolenaar1c299432018-10-28 14:36:09 +01002912" Test for incsearch highlighting of the :vimgrep pattern
2913" This test used to cause "E315: ml_get: invalid lnum" errors.
2914func Test_vimgrep_incsearch()
2915 enew
2916 set incsearch
2917 call test_override("char_avail", 1)
2918
2919 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2920 let l = getqflist()
2921 call assert_equal(2, len(l))
2922
2923 call test_override("ALL", 0)
2924 set noincsearch
2925endfunc
2926
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002927" Test vimgrep with the last search pattern not set
2928func Test_vimgrep_with_no_last_search_pat()
2929 let lines =<< trim [SCRIPT]
2930 call assert_fails('vimgrep // *', 'E35:')
2931 call writefile(v:errors, 'Xresult')
2932 qall!
2933 [SCRIPT]
2934 call writefile(lines, 'Xscript')
2935 if RunVim([], [], '--clean -S Xscript')
2936 call assert_equal([], readfile('Xresult'))
2937 endif
2938 call delete('Xscript')
2939 call delete('Xresult')
2940endfunc
2941
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002942" Test vimgrep without swap file
2943func Test_vimgrep_without_swap_file()
2944 let lines =<< trim [SCRIPT]
2945 vimgrep grep test_c*
2946 call writefile(['done'], 'Xresult')
2947 qall!
2948 [SCRIPT]
2949 call writefile(lines, 'Xscript')
2950 if RunVim([], [], '--clean -n -S Xscript Xscript')
2951 call assert_equal(['done'], readfile('Xresult'))
2952 endif
2953 call delete('Xscript')
2954 call delete('Xresult')
2955endfunc
2956
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002957func Test_vimgrep_existing_swapfile()
2958 call writefile(['match apple with apple'], 'Xapple')
2959 call writefile(['swapfile'], '.Xapple.swp')
2960 let g:foundSwap = 0
2961 let g:ignoreSwapExists = 1
2962 augroup grep
2963 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2964 augroup END
2965 vimgrep apple Xapple
2966 call assert_equal(1, g:foundSwap)
2967 call assert_match('.Xapple.swo', swapname(''))
2968
2969 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002970 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002971 augroup grep
2972 au! SwapExists
2973 augroup END
2974 unlet g:ignoreSwapExists
2975endfunc
2976
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002977func XfreeTests(cchar)
2978 call s:setup_commands(a:cchar)
2979
2980 enew | only
2981
2982 " Deleting the quickfix stack should work even When the current list is
2983 " somewhere in the middle of the stack
2984 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2985 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2986 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2987 Xolder
2988 call g:Xsetlist([], 'f')
2989 call assert_equal(0, len(g:Xgetlist()))
2990
2991 " After deleting the stack, adding a new list should create a stack with a
2992 " single list.
2993 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2994 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2995
2996 " Deleting the stack from a quickfix window should update/clear the
2997 " quickfix/location list window.
2998 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2999 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3000 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3001 Xolder
3002 Xwindow
3003 call g:Xsetlist([], 'f')
3004 call assert_equal(2, winnr('$'))
3005 call assert_equal(1, line('$'))
3006 Xclose
3007
3008 " Deleting the stack from a non-quickfix window should update/clear the
3009 " quickfix/location list window.
3010 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3011 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3012 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3013 Xolder
3014 Xwindow
3015 wincmd p
3016 call g:Xsetlist([], 'f')
3017 call assert_equal(0, len(g:Xgetlist()))
3018 wincmd p
3019 call assert_equal(2, winnr('$'))
3020 call assert_equal(1, line('$'))
3021
3022 " After deleting the location list stack, if the location list window is
3023 " opened, then a new location list should be created. So opening the
3024 " location list window again should not create a new window.
3025 if a:cchar == 'l'
3026 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3027 wincmd p
3028 lopen
3029 call assert_equal(2, winnr('$'))
3030 endif
3031 Xclose
3032endfunc
3033
Bram Moolenaar74240d32017-12-10 15:26:15 +01003034" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003035func Test_qf_free()
3036 call XfreeTests('c')
3037 call XfreeTests('l')
3038endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003039
3040" Test for buffer overflow when parsing lines and adding new entries to
3041" the quickfix list.
3042func Test_bufoverflow()
3043 set efm=%f:%l:%m
3044 cgetexpr ['File1:100:' . repeat('x', 1025)]
3045
3046 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3047 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3048
3049 set efm=%DEntering\ directory\ %f,%f:%l:%m
3050 cgetexpr ['Entering directory ' . repeat('a', 1006),
3051 \ 'File1:10:Hello World']
3052 set efm&vim
3053endfunc
3054
Bram Moolenaar875feea2017-06-11 16:07:51 +02003055" Tests for getting the quickfix stack size
3056func XsizeTests(cchar)
3057 call s:setup_commands(a:cchar)
3058
3059 call g:Xsetlist([], 'f')
3060 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003061 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3062 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003063
3064 Xexpr "File1:10:Line1"
3065 Xexpr "File2:20:Line2"
3066 Xexpr "File3:30:Line3"
3067 Xolder | Xolder
3068 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3069 call g:Xsetlist([], 'f')
3070
3071 Xexpr "File1:10:Line1"
3072 Xexpr "File2:20:Line2"
3073 Xexpr "File3:30:Line3"
3074 Xolder | Xolder
3075 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3076 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3077endfunc
3078
3079func Test_Qf_Size()
3080 call XsizeTests('c')
3081 call XsizeTests('l')
3082endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003083
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003084func Test_cclose_from_copen()
3085 augroup QF_Test
3086 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003087 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003088 augroup END
3089 copen
3090 augroup QF_Test
3091 au!
3092 augroup END
3093 augroup! QF_Test
3094endfunc
3095
Bram Moolenaar18141832017-06-25 21:17:25 +02003096func Test_cclose_in_autocmd()
3097 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3098 " event will be triggered.
3099 call test_override('starting', 1)
3100 augroup QF_Test
3101 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003102 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003103 augroup END
3104 copen
3105 augroup QF_Test
3106 au!
3107 augroup END
3108 augroup! QF_Test
3109 call test_override('starting', 0)
3110endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003111
Bram Moolenaar379fb762018-08-30 15:58:28 +02003112" Check that ":file" without an argument is possible even when "curbuf_lock"
3113" is set.
3114func Test_file_from_copen()
3115 " Works without argument.
3116 augroup QF_Test
3117 au!
3118 au FileType qf file
3119 augroup END
3120 copen
3121
3122 augroup QF_Test
3123 au!
3124 augroup END
3125 cclose
3126
3127 " Fails with argument.
3128 augroup QF_Test
3129 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003130 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003131 augroup END
3132 copen
3133 augroup QF_Test
3134 au!
3135 augroup END
3136 cclose
3137
3138 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003139endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003140
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003141func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003142 augroup QF_Test
3143 au!
3144 au FileType qf resize 5
3145 augroup END
3146 try
3147 " This should succeed without any exception. No other buffers are
3148 " involved in the autocmd.
3149 copen
3150 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003151 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003152 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003153 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003154 augroup! QF_Test
3155 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003156endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003157
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003158func Test_vimgrep_with_textlock()
3159 new
3160
3161 " Simple way to execute something with "textwinlock" set.
3162 " Check that vimgrep without jumping can be executed.
3163 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3164 normal ax
3165 let qflist = getqflist()
3166 call assert_true(len(qflist) > 0)
3167 call assert_match('RunTheTest', qflist[0].text)
3168 call setqflist([], 'r')
3169 au! InsertCharPre
3170
3171 " Check that vimgrepadd without jumping can be executed.
3172 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3173 normal ax
3174 let qflist = getqflist()
3175 call assert_true(len(qflist) > 0)
3176 call assert_match('RunTheTest', qflist[0].text)
3177 call setqflist([], 'r')
3178 au! InsertCharPre
3179
3180 " Check that lvimgrep without jumping can be executed.
3181 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3182 normal ax
3183 let qflist = getloclist(0)
3184 call assert_true(len(qflist) > 0)
3185 call assert_match('RunTheTest', qflist[0].text)
3186 call setloclist(0, [], 'r')
3187 au! InsertCharPre
3188
3189 " Check that lvimgrepadd without jumping can be executed.
3190 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3191 normal ax
3192 let qflist = getloclist(0)
3193 call assert_true(len(qflist) > 0)
3194 call assert_match('RunTheTest', qflist[0].text)
3195 call setloclist(0, [], 'r')
3196 au! InsertCharPre
3197
3198 " trying to jump will give an error
3199 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3200 call assert_fails('normal ax', 'E565:')
3201 au! InsertCharPre
3202
3203 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3204 call assert_fails('normal ax', 'E565:')
3205 au! InsertCharPre
3206
3207 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3208 call assert_fails('normal ax', 'E565:')
3209 au! InsertCharPre
3210
3211 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3212 call assert_fails('normal ax', 'E565:')
3213 au! InsertCharPre
3214
3215 bwipe!
3216endfunc
3217
Bram Moolenaara8788f42017-07-19 17:06:20 +02003218" Tests for the quickfix buffer b:changedtick variable
3219func Xchangedtick_tests(cchar)
3220 call s:setup_commands(a:cchar)
3221
3222 new | only
3223
3224 Xexpr "" | Xexpr "" | Xexpr ""
3225
3226 Xopen
3227 Xolder
3228 Xolder
3229 Xaddexpr "F1:10:Line10"
3230 Xaddexpr "F2:20:Line20"
3231 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3232 call g:Xsetlist([], 'f')
3233 call assert_equal(8, getbufvar('%', 'changedtick'))
3234 Xclose
3235endfunc
3236
3237func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003238 call Xchangedtick_tests('c')
3239 call Xchangedtick_tests('l')
3240endfunc
3241
3242" Tests for parsing an expression using setqflist()
3243func Xsetexpr_tests(cchar)
3244 call s:setup_commands(a:cchar)
3245
3246 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003247 call g:Xsetlist([], ' ', {'lines' : t})
3248 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003249
3250 let l = g:Xgetlist()
3251 call assert_equal(3, len(l))
3252 call assert_equal(20, l[1].lnum)
3253 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003254 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003255 let l = g:Xgetlist()
3256 call assert_equal(1, len(l))
3257 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003258 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3259 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003260
3261 call g:Xsetlist([], 'f')
3262 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003263 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3264 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3265 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3266 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003267 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3268 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003269
3270 " Adding entries using a custom efm
3271 set efm&
3272 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3273 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3274 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3275 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3276 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3277 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3278 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3279 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003280endfunc
3281
3282func Test_setexpr()
3283 call Xsetexpr_tests('c')
3284 call Xsetexpr_tests('l')
3285endfunc
3286
3287" Tests for per quickfix/location list directory stack
3288func Xmultidirstack_tests(cchar)
3289 call s:setup_commands(a:cchar)
3290
3291 call g:Xsetlist([], 'f')
3292 Xexpr "" | Xexpr ""
3293
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003294 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3295 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3296 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3297 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003298
3299 let l1 = g:Xgetlist({'nr':1, 'items':1})
3300 let l2 = g:Xgetlist({'nr':2, 'items':1})
3301 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3302 call assert_equal(3, l1.items[1].lnum)
3303 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3304 call assert_equal(5, l2.items[1].lnum)
3305endfunc
3306
3307func Test_multidirstack()
3308 call mkdir('Xone/a', 'p')
3309 call mkdir('Xtwo/a', 'p')
3310 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3311 call writefile(lines, 'Xone/a/one.txt')
3312 call writefile(lines, 'Xtwo/a/two.txt')
3313 let save_efm = &efm
3314 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3315
3316 call Xmultidirstack_tests('c')
3317 call Xmultidirstack_tests('l')
3318
3319 let &efm = save_efm
3320 call delete('Xone', 'rf')
3321 call delete('Xtwo', 'rf')
3322endfunc
3323
3324" Tests for per quickfix/location list file stack
3325func Xmultifilestack_tests(cchar)
3326 call s:setup_commands(a:cchar)
3327
3328 call g:Xsetlist([], 'f')
3329 Xexpr "" | Xexpr ""
3330
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003331 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3332 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3333 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3334 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003335
3336 let l1 = g:Xgetlist({'nr':1, 'items':1})
3337 let l2 = g:Xgetlist({'nr':2, 'items':1})
3338 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3339 call assert_equal(3, l1.items[1].lnum)
3340 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3341 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003342
3343 " Test for start of a new error line in the same line where a previous
3344 " error line ends with a file stack.
3345 let efm_val = 'Error\ l%l\ in\ %f,'
3346 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3347 let l = g:Xgetlist({'lines' : [
3348 \ '(one.txt',
3349 \ 'Error l4 in one.txt',
3350 \ ') (two.txt',
3351 \ 'Error l6 in two.txt',
3352 \ ')',
3353 \ 'Error l8 in one.txt'
3354 \ ], 'efm' : efm_val})
3355 call assert_equal(3, len(l.items))
3356 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3357 call assert_equal(4, l.items[0].lnum)
3358 call assert_equal('one.txt', l.items[0].text)
3359 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3360 call assert_equal(6, l.items[1].lnum)
3361 call assert_equal('two.txt', l.items[1].text)
3362 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3363 call assert_equal(8, l.items[2].lnum)
3364 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003365endfunc
3366
3367func Test_multifilestack()
3368 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3369 call writefile(lines, 'one.txt')
3370 call writefile(lines, 'two.txt')
3371 let save_efm = &efm
3372 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3373
3374 call Xmultifilestack_tests('c')
3375 call Xmultifilestack_tests('l')
3376
3377 let &efm = save_efm
3378 call delete('one.txt')
3379 call delete('two.txt')
3380endfunc
3381
3382" Tests for per buffer 'efm' setting
3383func Test_perbuf_efm()
3384 call writefile(["File1-10-Line10"], 'one.txt')
3385 call writefile(["File2#20#Line20"], 'two.txt')
3386 set efm=%f#%l#%m
3387 new | only
3388 new
3389 setlocal efm=%f-%l-%m
3390 cfile one.txt
3391 wincmd w
3392 caddfile two.txt
3393
3394 let l = getqflist()
3395 call assert_equal(10, l[0].lnum)
3396 call assert_equal('Line20', l[1].text)
3397
3398 set efm&
3399 new | only
3400 call delete('one.txt')
3401 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003402endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003403
3404" Open multiple help windows using ":lhelpgrep
3405" This test used to crash Vim
3406func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003407 new | only
3408 lhelpgrep window
3409 lopen
3410 e#
3411 lhelpgrep buffer
3412 call assert_equal(3, winnr('$'))
3413 call assert_true(len(getloclist(1)) != 0)
3414 call assert_true(len(getloclist(2)) != 0)
3415 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003416endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003417
3418" Tests for adding new quickfix lists using setqflist()
3419func XaddQf_tests(cchar)
3420 call s:setup_commands(a:cchar)
3421
3422 " Create a new list using ' ' for action
3423 call g:Xsetlist([], 'f')
3424 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3425 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3426 call assert_equal(1, l.nr)
3427 call assert_equal('Test1', l.title)
3428
3429 " Create a new list using ' ' for action and '$' for 'nr'
3430 call g:Xsetlist([], 'f')
3431 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3432 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3433 call assert_equal(1, l.nr)
3434 call assert_equal('Test2', l.title)
3435
3436 " Create a new list using 'a' for action
3437 call g:Xsetlist([], 'f')
3438 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3439 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3440 call assert_equal(1, l.nr)
3441 call assert_equal('Test3', l.title)
3442
3443 " Create a new list using 'a' for action and '$' for 'nr'
3444 call g:Xsetlist([], 'f')
3445 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3446 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3447 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3448 call assert_equal(1, l.nr)
3449 call assert_equal('Test4', l.title)
3450
3451 " Adding a quickfix list should remove all the lists following the current
3452 " list.
3453 Xexpr "" | Xexpr "" | Xexpr ""
3454 silent! 10Xolder
3455 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3456 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3457 call assert_equal(2, l.nr)
3458 call assert_equal('Test5', l.title)
3459
3460 " Add a quickfix list using '$' as the list number.
3461 let lastqf = g:Xgetlist({'nr':'$'}).nr
3462 silent! 99Xolder
3463 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3464 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3465 call assert_equal(lastqf + 1, l.nr)
3466 call assert_equal('Test6', l.title)
3467
3468 " Add a quickfix list using 'nr' set to one more than the quickfix
3469 " list size.
3470 let lastqf = g:Xgetlist({'nr':'$'}).nr
3471 silent! 99Xolder
3472 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3473 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3474 call assert_equal(lastqf + 1, l.nr)
3475 call assert_equal('Test7', l.title)
3476
3477 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3478 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3479 silent! 99Xolder
3480 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3481 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3482 call assert_equal(10, l.nr)
3483 call assert_equal('Test8', l.title)
3484
3485 " Add a quickfix list using 'nr' set to a value greater than 10
3486 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3487
3488 " Try adding a quickfix list with 'nr' set to a value greater than the
3489 " quickfix list size but less than 10.
3490 call g:Xsetlist([], 'f')
3491 Xexpr "" | Xexpr "" | Xexpr ""
3492 silent! 99Xolder
3493 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3494
3495 " Add a quickfix list using 'nr' set to a some string or list
3496 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3497endfunc
3498
3499func Test_add_qf()
3500 call XaddQf_tests('c')
3501 call XaddQf_tests('l')
3502endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003503
3504" Test for getting the quickfix list items from some text without modifying
3505" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003506func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003507 call s:setup_commands(a:cchar)
3508 call g:Xsetlist([], 'f')
3509
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003510 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003511 call assert_equal(2, len(l))
3512 call assert_equal(30, l[1].lnum)
3513
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003514 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3515 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3516 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3517 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003518
Bram Moolenaar36538222017-09-02 19:51:44 +02003519 " Parse text using a custom efm
3520 set efm&
3521 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3522 call assert_equal('Line30', l[0].text)
3523 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3524 call assert_equal('File3:30:Line30', l[0].text)
3525 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3526 call assert_equal({}, l)
3527 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3528 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3529
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003530 " Make sure that the quickfix stack is not modified
3531 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3532endfunc
3533
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003534func Test_get_list_from_lines()
3535 call XgetListFromLines('c')
3536 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003537endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003538
3539" Tests for the quickfix list id
3540func Xqfid_tests(cchar)
3541 call s:setup_commands(a:cchar)
3542
3543 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003544 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003545 Xexpr ''
3546 let start_id = g:Xgetlist({'id' : 0}).id
3547 Xexpr '' | Xexpr ''
3548 Xolder
3549 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3550 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3551 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003552 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003553 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003554 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3555 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003556
3557 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3558 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003559 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003560 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3561 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3562 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3563
3564 let qfid = g:Xgetlist({'id':0, 'nr':0})
3565 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003566 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003567endfunc
3568
3569func Test_qf_id()
3570 call Xqfid_tests('c')
3571 call Xqfid_tests('l')
3572endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003573
3574func Xqfjump_tests(cchar)
3575 call s:setup_commands(a:cchar)
3576
3577 call writefile(["Line1\tFoo", "Line2"], 'F1')
3578 call writefile(["Line1\tBar", "Line2"], 'F2')
3579 call writefile(["Line1\tBaz", "Line2"], 'F3')
3580
3581 call g:Xsetlist([], 'f')
3582
3583 " Tests for
3584 " Jumping to a line using a pattern
3585 " Jumping to a column greater than the last column in a line
3586 " Jumping to a line greater than the last line in the file
3587 let l = []
3588 for i in range(1, 7)
3589 call add(l, {})
3590 endfor
3591 let l[0].filename='F1'
3592 let l[0].pattern='Line1'
3593 let l[1].filename='F2'
3594 let l[1].pattern='Line1'
3595 let l[2].filename='F3'
3596 let l[2].pattern='Line1'
3597 let l[3].filename='F3'
3598 let l[3].lnum=1
3599 let l[3].col=9
3600 let l[3].vcol=1
3601 let l[4].filename='F3'
3602 let l[4].lnum=99
3603 let l[5].filename='F3'
3604 let l[5].lnum=1
3605 let l[5].col=99
3606 let l[5].vcol=1
3607 let l[6].filename='F3'
3608 let l[6].pattern='abcxyz'
3609
3610 call g:Xsetlist([], ' ', {'items' : l})
3611 Xopen | only
3612 2Xnext
3613 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003614 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003615 Xnext
3616 call assert_equal(7, col('.'))
3617 Xnext
3618 call assert_equal(2, line('.'))
3619 Xnext
3620 call assert_equal(9, col('.'))
3621 2
3622 Xnext
3623 call assert_equal(2, line('.'))
3624
3625 if a:cchar == 'l'
3626 " When jumping to a location list entry in the location list window and
3627 " no usable windows are available, then a new window should be opened.
3628 enew! | new | only
3629 call g:Xsetlist([], 'f')
3630 setlocal buftype=nofile
3631 new
3632 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']})
3633 Xopen
3634 let winid = win_getid()
3635 wincmd p
3636 close
3637 call win_gotoid(winid)
3638 Xnext
3639 call assert_equal(3, winnr('$'))
3640 call assert_equal(1, winnr())
3641 call assert_equal(2, line('.'))
3642
3643 " When jumping to an entry in the location list window and the window
3644 " associated with the location list is not present and a window containing
3645 " the file is already present, then that window should be used.
3646 close
3647 belowright new
3648 call g:Xsetlist([], 'f')
3649 edit F3
3650 call win_gotoid(winid)
3651 Xlast
3652 call assert_equal(3, winnr())
3653 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3654 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3655 endif
3656
3657 " Cleanup
3658 enew!
3659 new | only
3660
3661 call delete('F1')
3662 call delete('F2')
3663 call delete('F3')
3664endfunc
3665
3666func Test_qfjump()
3667 call Xqfjump_tests('c')
3668 call Xqfjump_tests('l')
3669endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003670
3671" Tests for the getqflist() and getloclist() functions when the list is not
3672" present or is empty
3673func Xgetlist_empty_tests(cchar)
3674 call s:setup_commands(a:cchar)
3675
3676 " Empty quickfix stack
3677 call g:Xsetlist([], 'f')
3678 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3679 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3680 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3681 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3682 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3683 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3684 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3685 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003686 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003687 if a:cchar == 'c'
3688 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003689 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003690 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3691 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003692 else
3693 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3694 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003695 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003696 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003697 \ g:Xgetlist({'all' : 0}))
3698 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003699
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003700 " Quickfix window with empty stack
3701 silent! Xopen
3702 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003703 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003704 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3705 Xclose
3706
Bram Moolenaara6d48492017-12-12 22:45:31 +01003707 " Empty quickfix list
3708 Xexpr ""
3709 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3710 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3711 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3712 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3713 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3714 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3715 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3716 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003717 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003718
3719 let qfid = g:Xgetlist({'id' : 0}).id
3720 call g:Xsetlist([], 'f')
3721
3722 " Non-existing quickfix identifier
3723 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3724 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3725 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3726 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3727 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3728 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3729 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3730 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003731 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003732 if a:cchar == 'c'
3733 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3734 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003735 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003736 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3737 else
3738 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3739 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003740 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3741 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003742 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3743 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003744
3745 " Non-existing quickfix list number
3746 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3747 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3748 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3749 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3750 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3751 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3752 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3753 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003754 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003755 if a:cchar == 'c'
3756 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3757 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003758 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3759 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003760 else
3761 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3762 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003763 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3764 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003765 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003766endfunc
3767
3768func Test_getqflist()
3769 call Xgetlist_empty_tests('c')
3770 call Xgetlist_empty_tests('l')
3771endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003772
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003773func Test_getqflist_invalid_nr()
3774 " The following commands used to crash Vim
3775 cexpr ""
3776 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3777
3778 " Cleanup
3779 call setqflist([], 'r')
3780endfunc
3781
Bram Moolenaarb254af32017-12-18 19:48:58 +01003782" Tests for the quickfix/location list changedtick
3783func Xqftick_tests(cchar)
3784 call s:setup_commands(a:cchar)
3785
3786 call g:Xsetlist([], 'f')
3787
3788 Xexpr "F1:10:Line10"
3789 let qfid = g:Xgetlist({'id' : 0}).id
3790 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3791 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3792 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3793 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3794 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3795 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3796 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3797 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3798 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3799
3800 enew!
3801 call append(0, ["F5:50:L50", "F6:60:L60"])
3802 Xaddbuffer
3803 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3804 enew!
3805
3806 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3807 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3808 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3809 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3810 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3811 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3812 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3813 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3814 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3815 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3816 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3817
3818 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3819 Xfile Xone
3820 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3821 Xaddfile Xone
3822 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3823
3824 " Test case for updating a non-current quickfix list
3825 call g:Xsetlist([], 'f')
3826 Xexpr "F1:1:L1"
3827 Xexpr "F2:2:L2"
3828 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3829 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3830 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3831
3832 call delete("Xone")
3833endfunc
3834
3835func Test_qf_tick()
3836 call Xqftick_tests('c')
3837 call Xqftick_tests('l')
3838endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003839
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003840" Test helpgrep with lang specifier
3841func Xtest_helpgrep_with_lang_specifier(cchar)
3842 call s:setup_commands(a:cchar)
3843 Xhelpgrep Vim@en
3844 call assert_equal('help', &filetype)
3845 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3846 new | only
3847endfunc
3848
3849func Test_helpgrep_with_lang_specifier()
3850 call Xtest_helpgrep_with_lang_specifier('c')
3851 call Xtest_helpgrep_with_lang_specifier('l')
3852endfunc
3853
Bram Moolenaar12237442017-12-19 12:38:52 +01003854" The following test used to crash Vim.
3855" Open the location list window and close the regular window associated with
3856" the location list. When the garbage collection runs now, it incorrectly
3857" marks the location list context as not in use and frees the context.
3858func Test_ll_window_ctx()
3859 call setloclist(0, [], 'f')
3860 call setloclist(0, [], 'a', {'context' : []})
3861 lopen | only
3862 call test_garbagecollect_now()
3863 echo getloclist(0, {'context' : 1}).context
3864 enew | only
3865endfunc
3866
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003867" The following test used to crash vim
3868func Test_lfile_crash()
3869 sp Xtest
3870 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003871 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003872 au! QuickFixCmdPre
3873endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003874
3875" The following test used to crash vim
3876func Test_lbuffer_crash()
3877 sv Xtest
3878 augroup QF_Test
3879 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003880 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003881 augroup END
3882 lbuffer
3883 augroup QF_Test
3884 au!
3885 augroup END
3886endfunc
3887
3888" The following test used to crash vim
3889func Test_lexpr_crash()
3890 augroup QF_Test
3891 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003892 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003893 augroup END
3894 lexpr ""
3895 augroup QF_Test
3896 au!
3897 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003898
Bram Moolenaar3c097222017-12-21 20:54:49 +01003899 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003900 augroup QF_Test
3901 au!
3902 au BufNew * call setloclist(0, [], 'f')
3903 augroup END
3904 lexpr 'x:1:x'
3905 augroup QF_Test
3906 au!
3907 augroup END
3908
3909 enew | only
3910 lexpr ''
3911 lopen
3912 augroup QF_Test
3913 au!
3914 au FileType * call setloclist(0, [], 'f')
3915 augroup END
3916 lexpr ''
3917 augroup QF_Test
3918 au!
3919 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003920endfunc
3921
3922" The following test used to crash Vim
3923func Test_lvimgrep_crash()
3924 sv Xtest
3925 augroup QF_Test
3926 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003927 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003928 augroup END
3929 lvimgrep quickfix test_quickfix.vim
3930 augroup QF_Test
3931 au!
3932 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003933
3934 new | only
3935 augroup QF_Test
3936 au!
3937 au BufEnter * call setloclist(0, [], 'r')
3938 augroup END
3939 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3940 augroup QF_Test
3941 au!
3942 augroup END
3943
Bram Moolenaar3c097222017-12-21 20:54:49 +01003944 enew | only
3945endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003946
Bram Moolenaar2573af32020-03-14 17:21:34 +01003947func Test_lvimgrep_crash2()
3948 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003949 call assert_fails('lvimgrep x x', 'E471:')
3950 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003951
3952 au! BufNewFile
3953endfunc
3954
Bram Moolenaarde046542017-12-26 13:53:11 +01003955" Test for the position of the quickfix and location list window
3956func Test_qfwin_pos()
3957 " Open two windows
3958 new | only
3959 new
3960 cexpr ['F1:10:L10']
3961 copen
3962 " Quickfix window should be the bottom most window
3963 call assert_equal(3, winnr())
3964 close
3965 " Open at the very top
3966 wincmd t
3967 topleft copen
3968 call assert_equal(1, winnr())
3969 close
3970 " open left of the current window
3971 wincmd t
3972 below new
3973 leftabove copen
3974 call assert_equal(2, winnr())
3975 close
3976 " open right of the current window
3977 rightbelow copen
3978 call assert_equal(3, winnr())
3979 close
3980endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003981
3982" Tests for quickfix/location lists changed by autocommands when
3983" :vimgrep/:lvimgrep commands are running.
3984func Test_vimgrep_autocmd()
3985 call setqflist([], 'f')
3986 call writefile(['stars'], 'Xtest1.txt')
3987 call writefile(['stars'], 'Xtest2.txt')
3988
3989 " Test 1:
3990 " When searching for a pattern using :vimgrep, if the quickfix list is
3991 " changed by an autocmd, the results should be added to the correct quickfix
3992 " list.
3993 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3994 silent vimgrep stars Xtest*.txt
3995 call assert_equal(1, getqflist({'nr' : 0}).nr)
3996 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3997 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3998 au! BufRead Xtest2.txt
3999
4000 " Test 2:
4001 " When searching for a pattern using :vimgrep, if the quickfix list is
4002 " freed, then a error should be given.
4003 silent! %bwipe!
4004 call setqflist([], 'f')
4005 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4006 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4007 au! BufRead Xtest2.txt
4008
4009 " Test 3:
4010 " When searching for a pattern using :lvimgrep, if the location list is
4011 " freed, then the command should error out.
4012 silent! %bwipe!
4013 let g:save_winid = win_getid()
4014 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4015 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4016 au! BufRead Xtest2.txt
4017
4018 call delete('Xtest1.txt')
4019 call delete('Xtest2.txt')
4020 call setqflist([], 'f')
4021endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004022
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004023" Test for an autocmd changing the current directory when running vimgrep
4024func Xvimgrep_autocmd_cd(cchar)
4025 call s:setup_commands(a:cchar)
4026
4027 %bwipe
4028 let save_cwd = getcwd()
4029
4030 augroup QF_Test
4031 au!
4032 autocmd BufRead * silent cd %:p:h
4033 augroup END
4034
4035 10Xvimgrep /vim/ Xdir/**
4036 let l = g:Xgetlist()
4037 call assert_equal('f1.txt', bufname(l[0].bufnr))
4038 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4039
4040 augroup QF_Test
4041 au!
4042 augroup END
4043
4044 exe 'cd ' . save_cwd
4045endfunc
4046
4047func Test_vimgrep_autocmd_cd()
4048 call mkdir('Xdir/a', 'p')
4049 call mkdir('Xdir/b', 'p')
4050 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4051 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4052 call Xvimgrep_autocmd_cd('c')
4053 call Xvimgrep_autocmd_cd('l')
4054 %bwipe
4055 call delete('Xdir', 'rf')
4056endfunc
4057
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004058" The following test used to crash Vim
4059func Test_lhelpgrep_autocmd()
4060 lhelpgrep quickfix
4061 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4062 lhelpgrep buffer
4063 call assert_equal('help', &filetype)
4064 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4065 lhelpgrep tabpage
4066 call assert_equal('help', &filetype)
4067 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4068 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004069
4070 new | only
4071 augroup QF_Test
4072 au!
4073 au BufEnter * call setqflist([], 'f')
4074 augroup END
4075 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004076 " run the test with a help window already open
4077 help
4078 wincmd w
4079 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004080 augroup QF_Test
4081 au! BufEnter
4082 augroup END
4083
4084 new | only
4085 augroup QF_Test
4086 au!
4087 au BufEnter * call setqflist([], 'r')
4088 augroup END
4089 call assert_fails('helpgrep quickfix', 'E925:')
4090 augroup QF_Test
4091 au! BufEnter
4092 augroup END
4093
4094 new | only
4095 augroup QF_Test
4096 au!
4097 au BufEnter * call setloclist(0, [], 'r')
4098 augroup END
4099 call assert_fails('lhelpgrep quickfix', 'E926:')
4100 augroup QF_Test
4101 au! BufEnter
4102 augroup END
4103
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004104 new | only
4105endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004106
4107" Test for shortening/simplifying the file name when opening the
4108" quickfix window or when displaying the quickfix list
4109func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004110 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004111 %bwipe
4112 " Create a quickfix list with a absolute path filename
4113 let fname = getcwd() . '/test_quickfix.vim'
4114 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4115 call assert_equal(fname, bufname('test_quickfix.vim'))
4116 " Opening the quickfix window should simplify the file path
4117 cwindow
4118 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4119 cclose
4120 %bwipe
4121 " Create a quickfix list with a absolute path filename
4122 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4123 call assert_equal(fname, bufname('test_quickfix.vim'))
4124 " Displaying the quickfix list should simplify the file path
4125 silent! clist
4126 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004127 " Add a few entries for the same file with different paths and check whether
4128 " the buffer name is shortened
4129 %bwipe
4130 call setqflist([], 'f')
4131 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4132 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4133 \ {'filename' : fname, 'lnum' : 30}], ' ')
4134 copen
4135 call assert_equal(['test_quickfix.vim|10| ',
4136 \ 'test_quickfix.vim|20| ',
4137 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4138 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004139endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004140
4141" Quickfix title tests
4142" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4143" Otherwise due to indentation, the title is set with spaces at the beginning
4144" of the command.
4145func Test_qftitle()
4146 call writefile(["F1:1:Line1"], 'Xerr')
4147
4148 " :cexpr
4149 exe "cexpr readfile('Xerr')"
4150 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4151
4152 " :cgetexpr
4153 exe "cgetexpr readfile('Xerr')"
4154 call assert_equal(":cgetexpr readfile('Xerr')",
4155 \ getqflist({'title' : 1}).title)
4156
4157 " :caddexpr
4158 call setqflist([], 'f')
4159 exe "caddexpr readfile('Xerr')"
4160 call assert_equal(":caddexpr readfile('Xerr')",
4161 \ getqflist({'title' : 1}).title)
4162
4163 " :cbuffer
4164 new Xerr
4165 exe "cbuffer"
4166 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4167
4168 " :cgetbuffer
4169 edit Xerr
4170 exe "cgetbuffer"
4171 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4172
4173 " :caddbuffer
4174 call setqflist([], 'f')
4175 edit Xerr
4176 exe "caddbuffer"
4177 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4178
4179 " :cfile
4180 exe "cfile Xerr"
4181 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4182
4183 " :cgetfile
4184 exe "cgetfile Xerr"
4185 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4186
4187 " :caddfile
4188 call setqflist([], 'f')
4189 exe "caddfile Xerr"
4190 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4191
4192 " :grep
4193 set grepprg=internal
4194 exe "grep F1 Xerr"
4195 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4196
4197 " :grepadd
4198 call setqflist([], 'f')
4199 exe "grepadd F1 Xerr"
4200 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4201 set grepprg&vim
4202
4203 " :vimgrep
4204 exe "vimgrep F1 Xerr"
4205 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4206
4207 " :vimgrepadd
4208 call setqflist([], 'f')
4209 exe "vimgrepadd F1 Xerr"
4210 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4211
4212 call setqflist(['F1:10:L10'], ' ')
4213 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4214
4215 call setqflist([], 'f')
4216 call setqflist(['F1:10:L10'], 'a')
4217 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4218
4219 call setqflist([], 'f')
4220 call setqflist(['F1:10:L10'], 'r')
4221 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4222
4223 close
4224 call delete('Xerr')
4225
4226 call setqflist([], ' ', {'title' : 'Errors'})
4227 copen
4228 call assert_equal('Errors', w:quickfix_title)
4229 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4230 call assert_equal('Errors', w:quickfix_title)
4231 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004232
4233 " Switching to another quickfix list in one tab page should update the
4234 " quickfix window title and statusline in all the other tab pages also
4235 call setqflist([], 'f')
4236 %bw!
4237 cgetexpr ['file_one:1:1: error in the first quickfix list']
4238 call setqflist([], 'a', {'title': 'first quickfix list'})
4239 cgetexpr ['file_two:2:1: error in the second quickfix list']
4240 call setqflist([], 'a', {'title': 'second quickfix list'})
4241 copen
4242 wincmd t
4243 tabnew two
4244 copen
4245 wincmd t
4246 colder
4247 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4248 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4249 call assert_equal(1, tabpagewinnr(1))
4250 call assert_equal(1, tabpagewinnr(2))
4251 tabnew
4252 call setqflist([], 'a', {'title': 'new quickfix title'})
4253 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4254 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4255 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004256endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004257
4258func Test_lbuffer_with_bwipe()
4259 new
4260 new
4261 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004262 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004263 augroup END
4264 lbuffer
4265 augroup nasty
4266 au!
4267 augroup END
4268endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004269
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004270" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4271" running
4272func Xexpr_acmd_freelist(cchar)
4273 call s:setup_commands(a:cchar)
4274
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004275 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004276 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004277 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004278 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004279 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004280 augroup nasty
4281 au!
4282 augroup END
4283endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004284
4285func Test_cexpr_acmd_freelist()
4286 call Xexpr_acmd_freelist('c')
4287 call Xexpr_acmd_freelist('l')
4288endfunc
4289
4290" Test for commands that create a new quickfix/location list and jump to the
4291" first error automatically.
4292func Xjumpto_first_error_test(cchar)
4293 call s:setup_commands(a:cchar)
4294
4295 call s:create_test_file('Xtestfile1')
4296 call s:create_test_file('Xtestfile2')
4297 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4298
4299 " Test for cexpr/lexpr
4300 enew
4301 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004302 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004303 call assert_equal(2, line('.'))
4304
4305 " Test for cfile/lfile
4306 enew
4307 call writefile(l, 'Xerr')
4308 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004309 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004310 call assert_equal(2, line('.'))
4311
4312 " Test for cbuffer/lbuffer
4313 edit Xerr
4314 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004315 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004316 call assert_equal(2, line('.'))
4317
4318 call delete('Xerr')
4319 call delete('Xtestfile1')
4320 call delete('Xtestfile2')
4321endfunc
4322
4323func Test_jumpto_first_error()
4324 call Xjumpto_first_error_test('c')
4325 call Xjumpto_first_error_test('l')
4326endfunc
4327
4328" Test for a quickfix autocmd changing the quickfix/location list before
4329" jumping to the first error in the new list.
4330func Xautocmd_changelist(cchar)
4331 call s:setup_commands(a:cchar)
4332
4333 " Test for cfile/lfile
4334 call s:create_test_file('Xtestfile1')
4335 call s:create_test_file('Xtestfile2')
4336 Xexpr 'Xtestfile1:2:Line2'
4337 autocmd QuickFixCmdPost * Xolder
4338 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4339 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004340 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004341 call assert_equal(4, line('.'))
4342 autocmd! QuickFixCmdPost
4343
4344 " Test for cbuffer/lbuffer
4345 call g:Xsetlist([], 'f')
4346 Xexpr 'Xtestfile1:2:Line2'
4347 autocmd QuickFixCmdPost * Xolder
4348 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4349 edit Xerr
4350 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004351 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004352 call assert_equal(4, line('.'))
4353 autocmd! QuickFixCmdPost
4354
4355 " Test for cexpr/lexpr
4356 call g:Xsetlist([], 'f')
4357 Xexpr 'Xtestfile1:2:Line2'
4358 autocmd QuickFixCmdPost * Xolder
4359 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004360 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004361 call assert_equal(4, line('.'))
4362 autocmd! QuickFixCmdPost
4363
Bram Moolenaar851332e2018-07-03 19:16:00 +02004364 " The grepprg may not be set on non-Unix systems
4365 if has('unix')
4366 " Test for grep/lgrep
4367 call g:Xsetlist([], 'f')
4368 Xexpr 'Xtestfile1:2:Line2'
4369 autocmd QuickFixCmdPost * Xolder
4370 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004371 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004372 call assert_equal(5, line('.'))
4373 autocmd! QuickFixCmdPost
4374 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004375
4376 " Test for vimgrep/lvimgrep
4377 call g:Xsetlist([], 'f')
4378 Xexpr 'Xtestfile1:2:Line2'
4379 autocmd QuickFixCmdPost * Xolder
4380 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004381 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004382 call assert_equal(5, line('.'))
4383 autocmd! QuickFixCmdPost
4384
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004385 " Test for autocommands clearing the quickfix list before jumping to the
4386 " first error. This should not result in an error
4387 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4388 let v:errmsg = ''
4389 " Test for cfile/lfile
4390 Xfile Xerr
4391 call assert_true(v:errmsg !~# 'E42:')
4392 " Test for cbuffer/lbuffer
4393 edit Xerr
4394 Xbuffer
4395 call assert_true(v:errmsg !~# 'E42:')
4396 " Test for cexpr/lexpr
4397 Xexpr 'Xtestfile2:4:Line4'
4398 call assert_true(v:errmsg !~# 'E42:')
4399 " Test for grep/lgrep
4400 " The grepprg may not be set on non-Unix systems
4401 if has('unix')
4402 silent Xgrep Line5 Xtestfile2
4403 call assert_true(v:errmsg !~# 'E42:')
4404 endif
4405 " Test for vimgrep/lvimgrep
4406 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4407 autocmd! QuickFixCmdPost
4408
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004409 call delete('Xerr')
4410 call delete('Xtestfile1')
4411 call delete('Xtestfile2')
4412endfunc
4413
4414func Test_autocmd_changelist()
4415 call Xautocmd_changelist('c')
4416 call Xautocmd_changelist('l')
4417endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004418
4419" Tests for the ':filter /pat/ clist' command
4420func Test_filter_clist()
4421 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4422 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4423 \ split(execute('filter /Line 15/ clist'), "\n"))
4424 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4425 \ split(execute('filter /Xfile1/ clist'), "\n"))
4426 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4427
4428 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4429 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4430 call assert_equal([' 2 pqr:pat2: '],
4431 \ split(execute('filter /pqr/ clist'), "\n"))
4432 call assert_equal([' 1 abc:pat1: '],
4433 \ split(execute('filter /pat1/ clist'), "\n"))
4434endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004435
4436" Tests for the "CTRL-W <CR>" command.
4437func Xview_result_split_tests(cchar)
4438 call s:setup_commands(a:cchar)
4439
4440 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4441 call g:Xsetlist([])
4442 Xopen
4443 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004444 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004445 call assert_equal(l:win_count, winnr('$'))
4446 Xclose
4447endfunc
4448
4449func Test_view_result_split()
4450 call Xview_result_split_tests('c')
4451 call Xview_result_split_tests('l')
4452endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004453
4454" Test that :cc sets curswant
4455func Test_curswant()
4456 helpgrep quickfix
4457 normal! llll
4458 1cc
4459 call assert_equal(getcurpos()[4], virtcol('.'))
4460 cclose | helpclose
4461endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004462
4463" Test for opening a file from the quickfix window using CTRL-W <Enter>
4464" doesn't leave an empty buffer around.
4465func Test_splitview()
4466 call s:create_test_file('Xtestfile1')
4467 call s:create_test_file('Xtestfile2')
4468 new | only
4469 let last_bufnr = bufnr('Test_sv_1', 1)
4470 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4471 cgetexpr l
4472 copen
4473 let numbufs = len(getbufinfo())
4474 exe "normal \<C-W>\<CR>"
4475 copen
4476 exe "normal j\<C-W>\<CR>"
4477 " Make sure new empty buffers are not created
4478 call assert_equal(numbufs, len(getbufinfo()))
4479 " Creating a new buffer should use the next available buffer number
4480 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4481 bwipe Test_sv_1
4482 bwipe Test_sv_2
4483 new | only
4484
4485 " When split opening files from location list window, make sure that two
4486 " windows doesn't refer to the same location list
4487 lgetexpr l
4488 let locid = getloclist(0, {'id' : 0}).id
4489 lopen
4490 exe "normal \<C-W>\<CR>"
4491 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4492 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4493 new | only
4494
4495 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004496 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004497 lhelpgrep window
4498 let locid = getloclist(0, {'id' : 0}).id
4499 lwindow
4500 exe "normal j\<C-W>\<CR>"
4501 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4502 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4503 new | only
4504
Bram Moolenaar406cd902020-02-18 21:54:41 +01004505 " Using :split or :vsplit from a quickfix window should behave like a :new
4506 " or a :vnew command
4507 copen
4508 split
4509 call assert_equal(3, winnr('$'))
4510 let l = getwininfo()
4511 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4512 close
4513 copen
4514 vsplit
4515 let l = getwininfo()
4516 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4517 new | only
4518
Bram Moolenaarb2443732018-11-11 22:50:27 +01004519 call delete('Xtestfile1')
4520 call delete('Xtestfile2')
4521endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004522
4523" Test for parsing entries using visual screen column
4524func Test_viscol()
4525 enew
4526 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4527 edit Xfile1
4528
4529 " Use byte offset for column number
4530 set efm&
4531 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4532 call assert_equal([5, 8], [col('.'), virtcol('.')])
4533 cnext
4534 call assert_equal([9, 12], [col('.'), virtcol('.')])
4535 cnext
4536 call assert_equal([14, 20], [col('.'), virtcol('.')])
4537
4538 " Use screen column offset for column number
4539 set efm=%f:%l:%v:%m
4540 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4541 call assert_equal([5, 8], [col('.'), virtcol('.')])
4542 cnext
4543 call assert_equal([9, 12], [col('.'), virtcol('.')])
4544 cnext
4545 call assert_equal([14, 20], [col('.'), virtcol('.')])
4546 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4547 call assert_equal([5, 8], [col('.'), virtcol('.')])
4548 cnext
4549 call assert_equal([10, 16], [col('.'), virtcol('.')])
4550 cnext
4551 call assert_equal([14, 20], [col('.'), virtcol('.')])
4552
4553 enew
4554 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4555
4556 " Use byte offset for column number
4557 set efm&
4558 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4559 call assert_equal([8, 10], [col('.'), virtcol('.')])
4560 cnext
4561 call assert_equal([11, 17], [col('.'), virtcol('.')])
4562 cnext
4563 call assert_equal([16, 25], [col('.'), virtcol('.')])
4564
4565 " Use screen column offset for column number
4566 set efm=%f:%l:%v:%m
4567 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4568 call assert_equal([8, 10], [col('.'), virtcol('.')])
4569 cnext
4570 call assert_equal([11, 17], [col('.'), virtcol('.')])
4571 cnext
4572 call assert_equal([16, 25], [col('.'), virtcol('.')])
4573
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004574 " Use screen column number with a multi-line error message
4575 enew
4576 call writefile(["à test"], 'Xfile1')
4577 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4578 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4579 call assert_equal('Xfile1', @%)
4580 call assert_equal([0, 1, 4, 0], getpos('.'))
4581
4582 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4583 " does not break this
4584 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4585 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4586 call assert_equal('Xfile1', @%)
4587 call assert_equal([0, 1, 3, 0], getpos('.'))
4588
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004589 enew | only
4590 set efm&
4591 call delete('Xfile1')
4592endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004593
4594" Test for the quickfix window buffer
4595func Xqfbuf_test(cchar)
4596 call s:setup_commands(a:cchar)
4597
4598 " Quickfix buffer should be reused across closing and opening a quickfix
4599 " window
4600 Xexpr "F1:10:Line10"
4601 Xopen
4602 let qfbnum = bufnr('')
4603 Xclose
4604 " Even after the quickfix window is closed, the buffer should be loaded
4605 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004606 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004607 Xopen
4608 " Buffer should be reused when opening the window again
4609 call assert_equal(qfbnum, bufnr(''))
4610 Xclose
4611
4612 if a:cchar == 'l'
4613 %bwipe
4614 " For a location list, when both the file window and the location list
4615 " window for the list are closed, then the buffer should be freed.
4616 new | only
4617 lexpr "F1:10:Line10"
4618 let wid = win_getid()
4619 lopen
4620 let qfbnum = bufnr('')
4621 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4622 close
4623 " When the location list window is closed, the buffer name should not
4624 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004625 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004626 call assert_true(bufloaded(qfbnum))
4627
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004628 " After deleting a location list buffer using ":bdelete", opening the
4629 " location list window should mark the buffer as a location list buffer.
4630 exe "bdelete " . qfbnum
4631 lopen
4632 call assert_equal("quickfix", &buftype)
4633 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4634 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4635 call assert_false(&swapfile)
4636 lclose
4637
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004638 " When the location list is cleared for the window, the buffer should be
4639 " removed
4640 call setloclist(0, [], 'f')
4641 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004642 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004643
4644 " When the location list is freed with the location list window open, the
4645 " location list buffer should not be lost. It should be reused when the
4646 " location list is again populated.
4647 lexpr "F1:10:Line10"
4648 lopen
4649 let wid = win_getid()
4650 let qfbnum = bufnr('')
4651 wincmd p
4652 call setloclist(0, [], 'f')
4653 lexpr "F1:10:Line10"
4654 lopen
4655 call assert_equal(wid, win_getid())
4656 call assert_equal(qfbnum, bufnr(''))
4657 lclose
4658
4659 " When the window with the location list is closed, the buffer should be
4660 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004661 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004662 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004663 endif
4664endfunc
4665
4666func Test_qfbuf()
4667 call Xqfbuf_test('c')
4668 call Xqfbuf_test('l')
4669endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004670
4671" If there is an autocmd to use only one window, then opening the location
4672" list window used to crash Vim.
4673func Test_winonly_autocmd()
4674 call s:create_test_file('Xtest1')
4675 " Autocmd to show only one Vim window at a time
4676 autocmd WinEnter * only
4677 new
4678 " Load the location list
4679 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4680 let loclistid = getloclist(0, {'id' : 0}).id
4681 " Open the location list window. Only this window will be shown and the file
4682 " window is closed.
4683 lopen
4684 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4685 " Jump to an entry in the location list and make sure that the cursor is
4686 " positioned correctly.
4687 ll 3
4688 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004689 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004690 call assert_equal(15, line('.'))
4691 " Cleanup
4692 autocmd! WinEnter
4693 new | only
4694 call delete('Xtest1')
4695endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004696
4697" Test to make sure that an empty quickfix buffer is not reused for loading
4698" a normal buffer.
4699func Test_empty_qfbuf()
4700 enew | only
4701 call writefile(["Test"], 'Xfile1')
4702 call setqflist([], 'f')
4703 copen | only
4704 let qfbuf = bufnr('')
4705 edit Xfile1
4706 call assert_notequal(qfbuf, bufnr(''))
4707 enew
4708 call delete('Xfile1')
4709endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004710
4711" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004712" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004713func Xtest_below(cchar)
4714 call s:setup_commands(a:cchar)
4715
4716 " No quickfix/location list
4717 call assert_fails('Xbelow', 'E42:')
4718 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004719 call assert_fails('Xbefore', 'E42:')
4720 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004721
4722 " Empty quickfix/location list
4723 call g:Xsetlist([])
4724 call assert_fails('Xbelow', 'E42:')
4725 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004726 call assert_fails('Xbefore', 'E42:')
4727 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004728
4729 call s:create_test_file('X1')
4730 call s:create_test_file('X2')
4731 call s:create_test_file('X3')
4732 call s:create_test_file('X4')
4733
4734 " Invalid entries
4735 edit X1
4736 call g:Xsetlist(["E1", "E2"])
4737 call assert_fails('Xbelow', 'E42:')
4738 call assert_fails('Xabove', 'E42:')
4739 call assert_fails('3Xbelow', 'E42:')
4740 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004741 call assert_fails('Xbefore', 'E42:')
4742 call assert_fails('Xafter', 'E42:')
4743 call assert_fails('3Xbefore', 'E42:')
4744 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004745
4746 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004747 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 +02004748 edit +7 X2
4749 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004750 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004751 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004752 normal 7G
4753 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004754 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004755 call assert_fails('Xbefore', 'E553:')
4756
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004757 normal 2j
4758 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004759 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004760 normal 7G
4761 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004762 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004763
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004764 " Last error in this file
4765 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004766 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004767 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004768 normal gg
4769 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004770 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004771 call assert_fails('Xafter', 'E553:')
4772
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004773 " First error in this file
4774 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004775 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004776 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004777 normal G
4778 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004779 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004780 call assert_fails('Xbefore', 'E553:')
4781
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004782 normal gg
4783 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004784 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004785 normal gg
4786 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004787 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004788
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004789 normal G
4790 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004791 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004792 normal G
4793 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004794 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004795
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004796 edit X4
4797 call assert_fails('Xabove', 'E42:')
4798 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004799 call assert_fails('Xbefore', 'E42:')
4800 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004801 if a:cchar == 'l'
4802 " If a buffer has location list entries from some other window but not
4803 " from the current window, then the commands should fail.
4804 edit X1 | split | call setloclist(0, [], 'f')
4805 call assert_fails('Xabove', 'E776:')
4806 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004807 call assert_fails('Xbefore', 'E776:')
4808 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004809 close
4810 endif
4811
4812 " Test for lines with multiple quickfix entries
4813 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4814 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4815 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4816 edit +1 X2
4817 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004818 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004819 normal 1G
4820 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004821 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004822
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004823 normal gg
4824 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004825 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004826 normal gg
4827 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004828 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004829
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004830 normal G
4831 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004832 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004833 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004834 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004835 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004836
4837 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004838 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004839 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004840 normal G
4841 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004842 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004843
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004844 normal 10G
4845 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004846 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004847 normal 10G$
4848 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004849 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004850
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004851 normal 10G
4852 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004853 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004854 normal 9G
4855 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004856 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004857
4858 " Invalid range
4859 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004860 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004861 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004862 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004863 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004864 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004865 endif
4866
4867 call delete('X1')
4868 call delete('X2')
4869 call delete('X3')
4870 call delete('X4')
4871endfunc
4872
4873func Test_cbelow()
4874 call Xtest_below('c')
4875 call Xtest_below('l')
4876endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004877
4878func Test_quickfix_count()
4879 let commands = [
4880 \ 'cNext',
4881 \ 'cNfile',
4882 \ 'cabove',
4883 \ 'cbelow',
4884 \ 'cfirst',
4885 \ 'clast',
4886 \ 'cnewer',
4887 \ 'cnext',
4888 \ 'cnfile',
4889 \ 'colder',
4890 \ 'cprevious',
4891 \ 'crewind',
4892 \
4893 \ 'lNext',
4894 \ 'lNfile',
4895 \ 'labove',
4896 \ 'lbelow',
4897 \ 'lfirst',
4898 \ 'llast',
4899 \ 'lnewer',
4900 \ 'lnext',
4901 \ 'lnfile',
4902 \ 'lolder',
4903 \ 'lprevious',
4904 \ 'lrewind',
4905 \ ]
4906 for cmd in commands
4907 call assert_fails('-1' .. cmd, 'E16:')
4908 call assert_fails('.' .. cmd, 'E16:')
4909 call assert_fails('%' .. cmd, 'E16:')
4910 call assert_fails('$' .. cmd, 'E16:')
4911 endfor
4912endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004913
4914" Test for aborting quickfix commands using QuickFixCmdPre
4915func Xtest_qfcmd_abort(cchar)
4916 call s:setup_commands(a:cchar)
4917
4918 call g:Xsetlist([], 'f')
4919
4920 " cexpr/lexpr
4921 let e = ''
4922 try
4923 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4924 catch /.*/
4925 let e = v:exception
4926 endtry
4927 call assert_equal('AbortCmd', e)
4928 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4929
4930 " cfile/lfile
4931 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4932 let e = ''
4933 try
4934 Xfile Xfile1
4935 catch /.*/
4936 let e = v:exception
4937 endtry
4938 call assert_equal('AbortCmd', e)
4939 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4940 call delete('Xfile1')
4941
4942 " cgetbuffer/lgetbuffer
4943 enew!
4944 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4945 let e = ''
4946 try
4947 Xgetbuffer
4948 catch /.*/
4949 let e = v:exception
4950 endtry
4951 call assert_equal('AbortCmd', e)
4952 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4953 enew!
4954
4955 " vimgrep/lvimgrep
4956 let e = ''
4957 try
4958 Xvimgrep /func/ test_quickfix.vim
4959 catch /.*/
4960 let e = v:exception
4961 endtry
4962 call assert_equal('AbortCmd', e)
4963 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4964
4965 " helpgrep/lhelpgrep
4966 let e = ''
4967 try
4968 Xhelpgrep quickfix
4969 catch /.*/
4970 let e = v:exception
4971 endtry
4972 call assert_equal('AbortCmd', e)
4973 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4974
4975 " grep/lgrep
4976 if has('unix')
4977 let e = ''
4978 try
4979 silent Xgrep func test_quickfix.vim
4980 catch /.*/
4981 let e = v:exception
4982 endtry
4983 call assert_equal('AbortCmd', e)
4984 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4985 endif
4986endfunc
4987
4988func Test_qfcmd_abort()
4989 augroup QF_Test
4990 au!
4991 autocmd QuickFixCmdPre * throw "AbortCmd"
4992 augroup END
4993
4994 call Xtest_qfcmd_abort('c')
4995 call Xtest_qfcmd_abort('l')
4996
4997 augroup QF_Test
4998 au!
4999 augroup END
5000endfunc
5001
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005002" Test for using a file in one of the parent directories.
5003func Test_search_in_dirstack()
5004 call mkdir('Xtestdir/a/b/c', 'p')
5005 let save_cwd = getcwd()
5006 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5007 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5008 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5009 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5010
5011 let lines = "Entering dir Xtestdir\n" .
5012 \ "Entering dir a\n" .
5013 \ "Entering dir b\n" .
5014 \ "Xfile2:2:X2_L2\n" .
5015 \ "Leaving dir a\n" .
5016 \ "Xfile1:2:X1_L2\n" .
5017 \ "Xfile3:1:X3_L1\n" .
5018 \ "Entering dir c\n" .
5019 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005020 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005021 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005022 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005023 call assert_equal(11, getqflist({'size' : 0}).size)
5024 call assert_equal(4, getqflist({'idx' : 0}).idx)
5025 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005026 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005027 cnext
5028 call assert_equal(6, getqflist({'idx' : 0}).idx)
5029 call assert_equal('X1_L2', getline('.'))
5030 cnext
5031 call assert_equal(7, getqflist({'idx' : 0}).idx)
5032 call assert_equal(1, line('$'))
5033 call assert_equal('', getline(1))
5034 cnext
5035 call assert_equal(9, getqflist({'idx' : 0}).idx)
5036 call assert_equal(1, line('$'))
5037 call assert_equal('', getline(1))
5038
5039 set efm&
5040 exe 'cd ' . save_cwd
5041 call delete('Xtestdir', 'rf')
5042endfunc
5043
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005044" Test for :cquit
5045func Test_cquit()
5046 " Exit Vim with a non-zero value
5047 if RunVim([], ["cquit 7"], '')
5048 call assert_equal(7, v:shell_error)
5049 endif
5050
5051 if RunVim([], ["50cquit"], '')
5052 call assert_equal(50, v:shell_error)
5053 endif
5054
5055 " Exit Vim with default value
5056 if RunVim([], ["cquit"], '')
5057 call assert_equal(1, v:shell_error)
5058 endif
5059
5060 " Exit Vim with zero value
5061 if RunVim([], ["cquit 0"], '')
5062 call assert_equal(0, v:shell_error)
5063 endif
5064
5065 " Exit Vim with negative value
5066 call assert_fails('-3cquit', 'E16:')
5067endfunc
5068
Bram Moolenaar858ba062020-05-31 23:11:59 +02005069" Test for getting a specific item from a quickfix list
5070func Xtest_getqflist_by_idx(cchar)
5071 call s:setup_commands(a:cchar)
5072 " Empty list
5073 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5074 Xexpr ['F1:10:L10', 'F1:20:L20']
5075 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5076 call assert_equal(bufnr('F1'), l[0].bufnr)
5077 call assert_equal(20, l[0].lnum)
5078 call assert_equal('L20', l[0].text)
5079 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5080 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5081 %bwipe!
5082endfunc
5083
5084func Test_getqflist_by_idx()
5085 call Xtest_getqflist_by_idx('c')
5086 call Xtest_getqflist_by_idx('l')
5087endfunc
5088
5089" Test for the 'quickfixtextfunc' setting
5090func Tqfexpr(info)
5091 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005092 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005093 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005094 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005095 endif
5096
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005097 let l = []
5098 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5099 let e = qfl[idx]
5100 let s = ''
5101 if e.bufnr != 0
5102 let bname = bufname(e.bufnr)
5103 let s ..= fnamemodify(bname, ':.')
5104 endif
5105 let s ..= '-'
5106 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5107 let s ..= e.text
5108 call add(l, s)
5109 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005110
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005111 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005112endfunc
5113
5114func Xtest_qftextfunc(cchar)
5115 call s:setup_commands(a:cchar)
5116
5117 set efm=%f:%l:%c:%m
5118 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005119 call assert_equal('Tqfexpr', &quickfixtextfunc)
5120 call assert_equal('',
5121 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005122 call g:Xsetlist([
5123 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5124 \ 'end_col': 7, 'text': 'green'},
5125 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5126 \ 'end_col': 8, 'text': 'blue'},
5127 \ ])
5128
Bram Moolenaar858ba062020-05-31 23:11:59 +02005129 Xwindow
5130 call assert_equal('F1-L10C2-green', getline(1))
5131 call assert_equal('F1-L20C4-blue', getline(2))
5132 Xclose
5133 set quickfixtextfunc&vim
5134 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005135 call assert_equal('F1|10 col 2-7| green', getline(1))
5136 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005137 Xclose
5138 set efm&
5139 set quickfixtextfunc&
5140
5141 " Test for per list 'quickfixtextfunc' setting
5142 func PerQfText(info)
5143 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005144 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005145 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005146 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005147 endif
5148 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005149 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005150 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005151 let l = []
5152 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5153 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5154 endfor
5155 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005156 endfunc
5157 set quickfixtextfunc=Tqfexpr
5158 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5159 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5160 Xwindow
5161 call assert_equal('Line 10, Col 2', getline(1))
5162 call assert_equal('Line 20, Col 4', getline(2))
5163 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005164 call assert_equal(function('PerQfText'),
5165 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005166 " Add entries to the list when the quickfix buffer is hidden
5167 Xaddexpr ['F1:30:6:red']
5168 Xwindow
5169 call assert_equal('Line 30, Col 6', getline(3))
5170 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005171 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005172 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005173 set quickfixtextfunc&
5174 delfunc PerQfText
5175
5176 " Non-existing function
5177 set quickfixtextfunc=Tabc
5178 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5179 call assert_fails("Xwindow", 'E117:')
5180 Xclose
5181 set quickfixtextfunc&
5182
5183 " set option to a non-function
5184 set quickfixtextfunc=[10,\ 20]
5185 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5186 call assert_fails("Xwindow", 'E117:')
5187 Xclose
5188 set quickfixtextfunc&
5189
5190 " set option to a function with different set of arguments
5191 func Xqftext(a, b, c)
5192 return a:a .. a:b .. a:c
5193 endfunc
5194 set quickfixtextfunc=Xqftext
5195 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5196 call assert_fails("Xwindow", 'E119:')
5197 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005198
5199 " set option to a function that returns a list with non-strings
5200 func Xqftext2(d)
5201 return ['one', [], 'two']
5202 endfunc
5203 set quickfixtextfunc=Xqftext2
5204 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5205 \ 'E730:')
5206 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005207 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5208 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005209 Xclose
5210
Bram Moolenaar858ba062020-05-31 23:11:59 +02005211 set quickfixtextfunc&
5212 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005213 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005214
5215 " set the global option to a lambda function
5216 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5217 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5218 Xwindow
5219 call assert_equal(['green', 'blue'], getline(1, '$'))
5220 Xclose
5221 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)
5222 set quickfixtextfunc&
5223
5224 " use a lambda function that returns an empty list
5225 set quickfixtextfunc={d\ ->\ []}
5226 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5227 Xwindow
5228 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5229 \ getline(1, '$'))
5230 Xclose
5231 set quickfixtextfunc&
5232
5233 " use a lambda function that returns a list with empty strings
5234 set quickfixtextfunc={d\ ->\ ['',\ '']}
5235 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5236 Xwindow
5237 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5238 \ getline(1, '$'))
5239 Xclose
5240 set quickfixtextfunc&
5241
5242 " set the per-quickfix list text function to a lambda function
5243 call g:Xsetlist([], ' ',
5244 \ {'quickfixtextfunc' :
5245 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5246 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5247 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5248 Xwindow
5249 call assert_equal('Line 10, Col 2', getline(1))
5250 call assert_equal('Line 20, Col 4', getline(2))
5251 Xclose
5252 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5253 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005254endfunc
5255
5256func Test_qftextfunc()
5257 call Xtest_qftextfunc('c')
5258 call Xtest_qftextfunc('l')
5259endfunc
5260
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005261" Test for updating a location list for some other window and check that
5262" 'qftextfunc' uses the correct location list.
5263func Test_qftextfunc_other_loclist()
5264 %bw!
5265 call setloclist(0, [], 'f')
5266
5267 " create a window and a location list for it and open the location list
5268 " window
5269 lexpr ['F1:10:12:one', 'F1:20:14:two']
5270 let w1_id = win_getid()
5271 call setloclist(0, [], ' ',
5272 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5273 \ 'quickfixtextfunc':
5274 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5275 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5276 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5277 lwindow
5278 let w2_id = win_getid()
5279
5280 " create another window and a location list for it and open the location
5281 " list window
5282 topleft new
5283 let w3_id = win_getid()
5284 call setloclist(0, [], ' ',
5285 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5286 \ 'quickfixtextfunc':
5287 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5288 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5289 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5290 lwindow
5291 let w4_id = win_getid()
5292
5293 topleft new
5294 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5295 let w5_id = win_getid()
5296
5297 " change the location list for some other window
5298 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5299 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5300 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5301 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5302 \ getbufline(winbufnr(w2_id), 1, '$'))
5303 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5304 \ getbufline(winbufnr(w4_id), 1, '$'))
5305 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5306 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5307 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5308 \ getbufline(winbufnr(w2_id), 1, '$'))
5309 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5310 \ getbufline(winbufnr(w4_id), 1, '$'))
5311
5312 call win_gotoid(w5_id)
5313 lwindow
5314 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5315 \ getline(1, '$'))
5316 %bw!
5317endfunc
5318
Bram Moolenaarec98e932020-06-08 19:35:59 +02005319" Running :lhelpgrep command more than once in a help window, doesn't jump to
5320" the help topic
5321func Test_lhelpgrep_from_help_window()
5322 call mkdir('Xtestdir/doc', 'p')
5323 call writefile(['window'], 'Xtestdir/doc/a.txt')
5324 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5325 let save_rtp = &rtp
5326 let &rtp = 'Xtestdir'
5327 lhelpgrep window
5328 lhelpgrep buffer
5329 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5330 lhelpgrep window
5331 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5332 let &rtp = save_rtp
5333 call delete('Xtestdir', 'rf')
5334 new | only!
5335endfunc
5336
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005337" Test for the crash fixed by 7.3.715
5338func Test_setloclist_crash()
5339 %bw!
5340 let g:BufNum = bufnr()
5341 augroup QF_Test
5342 au!
5343 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5344 augroup END
5345
5346 try
5347 lvimgrep /.*/ *.mak
5348 catch /E926:/
5349 endtry
5350 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5351 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5352
5353 augroup QF_Test
5354 au!
5355 augroup END
5356 unlet g:BufNum
5357 %bw!
5358endfunc
5359
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005360" Test for adding an invalid entry with the quickfix window open and making
5361" sure that the window contents are not changed
5362func Test_add_invalid_entry_with_qf_window()
5363 call setqflist([], 'f')
5364 cexpr "Xfile1:10:aa"
5365 copen
5366 call setqflist(['bb'], 'a')
5367 call assert_equal(1, line('$'))
5368 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
thinca6864efa2021-06-19 20:45:20 +02005369 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())
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005370 cclose
5371endfunc
5372
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005373" Test for very weird problem: autocommand causes a failure, resulting opening
5374" the quickfix window to fail. This still splits the window, but otherwise
5375" should not mess up buffers.
5376func Test_quickfix_window_fails_to_open()
5377 CheckScreendump
5378
5379 let lines =<< trim END
5380 anything
5381 try
5382 anything
5383 endtry
5384 END
5385 call writefile(lines, 'XquickfixFails')
5386
5387 let lines =<< trim END
5388 split XquickfixFails
5389 silent vimgrep anything %
5390 normal o
5391 au BufLeave * ++once source XquickfixFails
5392 " This will trigger the autocommand, which causes an error, what follows
5393 " is aborted but the window was already split.
5394 silent! cwindow
5395 END
5396 call writefile(lines, 'XtestWinFails')
5397 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5398 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5399
5400 " clean up
5401 call term_sendkeys(buf, ":bwipe!\<CR>")
5402 call term_wait(buf)
5403 call StopVimInTerminal(buf)
5404 call delete('XtestWinFails')
5405 call delete('XquickfixFails')
5406endfunc
5407
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005408" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005409" is changed.
5410func Xqfbuf_update(cchar)
5411 call s:setup_commands(a:cchar)
5412
5413 Xexpr "F1:1:line1"
5414 Xopen
5415 call assert_equal(['F1|1| line1'], getline(1, '$'))
5416 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5417
5418 " Test setqflist() using the 'lines' key in 'what'
5419 " add a new entry
5420 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5421 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5422 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5423 " replace all the entries with a single entry
5424 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5425 call assert_equal(['F3|3| line3'], getline(1, '$'))
5426 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5427 " remove all the entries
5428 call g:Xsetlist([], 'r', {'lines' : []})
5429 call assert_equal([''], getline(1, '$'))
5430 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5431 " add a new list
5432 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5433 call assert_equal(['F4|4| line4'], getline(1, '$'))
5434 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5435
5436 " Test setqflist() using the 'items' key in 'what'
5437 " add a new entry
5438 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5439 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5440 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5441 " replace all the entries with a single entry
5442 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5443 call assert_equal(['F6|6| line6'], getline(1, '$'))
5444 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5445 " remove all the entries
5446 call g:Xsetlist([], 'r', {'items' : []})
5447 call assert_equal([''], getline(1, '$'))
5448 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5449 " add a new list
5450 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5451 call assert_equal(['F7|7| line7'], getline(1, '$'))
5452 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5453
5454 call g:Xsetlist([], ' ', {})
5455 call assert_equal([''], getline(1, '$'))
5456 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5457
5458 Xclose
5459endfunc
5460
5461func Test_qfbuf_update()
5462 call Xqfbuf_update('c')
5463 call Xqfbuf_update('l')
5464endfunc
5465
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005466func Test_vimgrep_noswapfile()
5467 set noswapfile
5468 call writefile(['one', 'two', 'three'], 'Xgreppie')
5469 vimgrep two Xgreppie
5470 call assert_equal('two', getline('.'))
5471
5472 call delete('Xgreppie')
5473 set swapfile
5474endfunc
5475
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005476" Test for the :vimgrep 'f' flag (fuzzy match)
5477func Xvimgrep_fuzzy_match(cchar)
5478 call s:setup_commands(a:cchar)
5479
5480 Xvimgrep /three one/f Xfile*
5481 let l = g:Xgetlist()
5482 call assert_equal(2, len(l))
5483 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5484 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5485 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5486 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5487
5488 Xvimgrep /the/f Xfile*
5489 let l = g:Xgetlist()
5490 call assert_equal(3, len(l))
5491 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5492 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5493 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5494 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5495 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5496 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5497
5498 Xvimgrep /aaa/fg Xfile*
5499 let l = g:Xgetlist()
5500 call assert_equal(4, len(l))
5501 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5502 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5503 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5504 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5505 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5506 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5507 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5508 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5509
5510 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5511endfunc
5512
5513func Test_vimgrep_fuzzy_match()
5514 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5515 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5516 call Xvimgrep_fuzzy_match('c')
5517 call Xvimgrep_fuzzy_match('l')
5518 call delete('Xfile1')
5519 call delete('Xfile2')
5520endfunc
5521
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005522" vim: shiftwidth=2 sts=2 expandtab