blob: b242ac5fa2da9cf29ba80c718535f6875436442c [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 Moolenaar1d30fde2021-10-20 21:58:42 +0100789func Test_bufwinenter_once()
790 augroup QfBufWinEnter
791 au!
792 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
793 augroup END
794 let g:got_afile = ''
795 copen
796 call assert_equal('got quickfix', g:got_afile)
797
798 cclose
799 unlet g:got_afile
800 augroup QfBufWinEnter
801 au!
802 augroup END
803 augroup! QfBufWinEnter
804endfunc
805
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100806func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200807 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100808
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200809 Xgetexpr ['file:1:1:message']
810 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100811 if a:cchar == 'c'
812 call setqflist(l, 'r')
813 else
814 call setloclist(0, l, 'r')
815 endif
816
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200817 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100818 if a:cchar == 'c'
819 let title = ':setqflist()'
820 else
821 let title = ':setloclist()'
822 endif
823 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200824 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100825endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100826
827" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100828func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200829 call XqfTitleTests('c')
830 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100831endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100832
833" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100834func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100835 let save_efm = &efm
836 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
837 cgetexpr ['WWWW', 'EEEE', 'CCCC']
838 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
839 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
840 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
841 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
842 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
843 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
844 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
845 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
846 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100847endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100848
849" This will test for problems in quickfix:
850" A. incorrectly copying location lists which caused the location list to show
851" a different name than the file that was actually being displayed.
852" B. not reusing the window for which the location list window is opened but
853" instead creating new windows.
854" C. make sure that the location list window is not reused instead of the
855" window it belongs to.
856"
857" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100858func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100859 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
860 let word = substitute(base, '\v(.*)\..*', '\1', '')
861
862 setl modifiable
863 setl noreadonly
864 setl noswapfile
865 setl bufhidden=delete
866 %del _
867 " For problem 2:
868 " 'buftype' has to be set to reproduce the constant opening of new windows
869 setl buftype=nofile
870
871 call setline(1, word)
872
873 setl nomodified
874 setl nomodifiable
875 setl readonly
876 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100877endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100878
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100879func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200880 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100881
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200882 augroup testgroup
883 au!
884 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
885 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100886
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200887 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100888
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200889 let qflist = []
890 for word in words
891 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
892 " NOTE: problem 1:
893 " intentionally not setting 'lnum' so that the quickfix entries are not
894 " valid
895 eval qflist->setloclist(0, ' ')
896 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100897
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200898 " Test A
899 lrewind
900 enew
901 lopen
902 4lnext
903 vert split
904 wincmd L
905 lopen
906 wincmd p
907 lnext
908 let fileName = expand("%")
909 wincmd p
910 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
911 let fileName = substitute(fileName, '\\', '/', 'g')
912 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
913 call assert_equal("test://bar.txt", fileName)
914 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100915
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200916 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100917
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200918 " Test B:
919 lrewind
920 lopen
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 call assert_equal(2, winnr('$'))
930 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100931
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200932 " Test C:
933 lrewind
934 lopen
935 " Let's move the location list window to the top to check whether it (the
936 " first window found) will be reused when we try to open new windows:
937 wincmd K
938 2
939 exe "normal \<CR>"
940 wincmd p
941 3
942 exe "normal \<CR>"
943 wincmd p
944 4
945 exe "normal \<CR>"
946 1wincmd w
947 call assert_equal('quickfix', &buftype)
948 2wincmd w
949 let bufferName = expand("%")
950 let bufferName = substitute(bufferName, '\\', '/', 'g')
951 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100952
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200953 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100954
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200955 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100956endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100957
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100958func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200959 augroup testgroup
960 au!
961 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
962 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100963
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200964 func! R(n)
965 quit
966 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100967
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200968 new
969 let q = []
970 call add(q, {'filename': 'test_curwin.txt' })
971 call setloclist(0, q)
972 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100973
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200974 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100975endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100976
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100977func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200978 call writefile(['loclistfoo'], 'loclistfoo')
979 call writefile(['loclistbar'], 'loclistbar')
980 set switchbuf=usetab
981
982 edit loclistfoo
983 tabedit loclistbar
984 silent lgrep loclistfoo loclist*
985 call assert_equal(1, tabpagenr())
986
987 enew | only | tabonly
988 set switchbuf&vim
989 call delete('loclistfoo')
990 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100991endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200992
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100993" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100994func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200995 " The 'errorformat' setting is different on non-Unix systems.
996 " This test works only on Unix-like systems.
997 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100998
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200999 let l =<< trim [DATA]
1000 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1001 "Xtestfile", line 6 col 19; this is an error
1002 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1003 Xtestfile:9: parse error before `asd'
1004 make: *** [vim] Error 1
1005 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001006
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001007 2 returned
1008 "Xtestfile", line 11 col 1; this is an error
1009 "Xtestfile", line 12 col 2; this is another error
1010 "Xtestfile", line 14:10; this is an error in column 10
1011 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1012 "Xtestfile", linenr 16: yet another problem
1013 Error in "Xtestfile" at line 17:
1014 x should be a dot
1015 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1016 ^
1017 Error in "Xtestfile" at line 18:
1018 x should be a dot
1019 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1020 .............^
1021 Error in "Xtestfile" at line 19:
1022 x should be a dot
1023 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1024 --------------^
1025 Error in "Xtestfile" at line 20:
1026 x should be a dot
1027 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1028 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001029
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001030 Does anyone know what is the problem and how to correction it?
1031 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1032 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1033 [DATA]
1034
1035 call writefile(l, 'Xerrorfile1')
1036 call writefile(l[:-2], 'Xerrorfile2')
1037
1038 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001039 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1040 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1041 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1042 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1043 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1044 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1045 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1046 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1047 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1048 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1049 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1051 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1052 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1055 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1056 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1060[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001061 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001062
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001063 let save_efm = &efm
1064 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1065 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001066
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001067 exe 'cf Xerrorfile2'
1068 clast
1069 copen
1070 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1071 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001072
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001073 exe 'cf Xerrorfile1'
1074 call assert_equal([4, 12], [line('.'), col('.')])
1075 cn
1076 call assert_equal([6, 19], [line('.'), col('.')])
1077 cn
1078 call assert_equal([9, 2], [line('.'), col('.')])
1079 cn
1080 call assert_equal([10, 2], [line('.'), col('.')])
1081 cn
1082 call assert_equal([11, 1], [line('.'), col('.')])
1083 cn
1084 call assert_equal([12, 2], [line('.'), col('.')])
1085 cn
1086 call assert_equal([14, 10], [line('.'), col('.')])
1087 cn
1088 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1089 cn
1090 call assert_equal([16, 2], [line('.'), col('.')])
1091 cn
1092 call assert_equal([17, 6], [line('.'), col('.')])
1093 cn
1094 call assert_equal([18, 7], [line('.'), col('.')])
1095 cn
1096 call assert_equal([19, 8], [line('.'), col('.')])
1097 cn
1098 call assert_equal([20, 9], [line('.'), col('.')])
1099 clast
1100 cprev
1101 cprev
1102 wincmd w
1103 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1104 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001105
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001106 let &efm = save_efm
1107 call delete('Xerrorfile1')
1108 call delete('Xerrorfile2')
1109 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001110endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001111
Bram Moolenaarab47c612016-06-14 22:02:26 +02001112" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001113func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001114 call s:setup_commands(a:cchar)
1115
Bram Moolenaarab47c612016-06-14 22:02:26 +02001116 let save_efm=&efm
1117 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1118
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001119 let lines = ["Entering dir 'dir1/a'",
1120 \ 'habits2.txt:1:Nine Healthy Habits',
1121 \ "Entering dir 'b'",
1122 \ 'habits3.txt:2:0 Hours of television',
1123 \ 'habits2.txt:7:5 Small meals',
1124 \ "Entering dir 'dir1/c'",
1125 \ 'habits4.txt:3:1 Hour of exercise',
1126 \ "Leaving dir 'dir1/c'",
1127 \ "Leaving dir 'dir1/a'",
1128 \ 'habits1.txt:4:2 Liters of water',
1129 \ "Entering dir 'dir2'",
1130 \ 'habits5.txt:5:3 Cups of hot green tea',
1131 \ "Leaving dir 'dir2'"
1132 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001133
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001134 Xexpr ""
1135 for l in lines
1136 Xaddexpr l
1137 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001138
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001139 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001140
1141 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1142 call assert_equal(1, qf[1].lnum)
1143 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1144 call assert_equal(2, qf[3].lnum)
1145 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1146 call assert_equal(7, qf[4].lnum)
1147 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1148 call assert_equal(3, qf[6].lnum)
1149 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1150 call assert_equal(4, qf[9].lnum)
1151 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1152 call assert_equal(5, qf[11].lnum)
1153
1154 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001155endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001156
1157" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001158func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001159 " Create the directory stack and files
1160 call mkdir('dir1')
1161 call mkdir('dir1/a')
1162 call mkdir('dir1/a/b')
1163 call mkdir('dir1/c')
1164 call mkdir('dir2')
1165
1166 let lines = ["Nine Healthy Habits",
1167 \ "0 Hours of television",
1168 \ "1 Hour of exercise",
1169 \ "2 Liters of water",
1170 \ "3 Cups of hot green tea",
1171 \ "4 Short mental breaks",
1172 \ "5 Small meals",
1173 \ "6 AM wake up time",
1174 \ "7 Minutes of laughter",
1175 \ "8 Hours of sleep (at least)",
1176 \ "9 PM end of the day and off to bed"
1177 \ ]
1178 call writefile(lines, 'habits1.txt')
1179 call writefile(lines, 'dir1/a/habits2.txt')
1180 call writefile(lines, 'dir1/a/b/habits3.txt')
1181 call writefile(lines, 'dir1/c/habits4.txt')
1182 call writefile(lines, 'dir2/habits5.txt')
1183
1184 call s:dir_stack_tests('c')
1185 call s:dir_stack_tests('l')
1186
1187 call delete('dir1', 'rf')
1188 call delete('dir2', 'rf')
1189 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001190endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001191
Bram Moolenaar9b457942016-10-09 16:10:05 +02001192" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001193func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001194 call s:setup_commands(a:cchar)
1195
1196 let save_efm = &efm
1197
1198 let &efm =
1199 \ '%Eerror %m %l,' .
1200 \ '%-Wignored %m %l,' .
1201 \ '%+Cmore ignored %m %l,' .
1202 \ '%Zignored end'
1203 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1204 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1205 call assert_equal([['resync', 1, 4, 'E']], l)
1206
1207 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001208endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001209
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001210func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001211 call Xefm_ignore_continuations('c')
1212 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001213endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001214
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001215" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001216func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001217 call s:setup_commands(a:cchar)
1218
Bram Moolenaar049cba92016-06-26 14:38:04 +02001219 let save_efm = &efm
1220
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001221 set efm=%f:%l:%m,%f:%f:%l:%m
1222 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1223
1224 set efm=%f:%l:%m,%f:%l:%r:%m
1225 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1226
1227 set efm=%f:%l:%m,%O:%f:%l:%m
1228 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1229
1230 set efm=%f:%l:%m,%f:%l:%*[^a-z
1231 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1232
1233 set efm=%f:%l:%m,%f:%l:%*c
1234 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1235
1236 set efm=%f:%l:%m,%L%M%N
1237 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1238
1239 set efm=%f:%l:%m,%f:%l:%m:%R
1240 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1241
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001242 " Invalid regular expression
1243 set efm=%\\%%k
1244 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1245
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001246 set efm=
1247 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1248
1249 set efm=%DEntering\ dir\ abc,%f:%l:%m
1250 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1251
1252 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001253endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001254
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001255func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001256 call Xinvalid_efm_Tests('c')
1257 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001258endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001259
1260" TODO:
1261" Add tests for the following formats in 'errorformat'
1262" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001263func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001264 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001265
1266 " Test for %s format in efm
1267 set efm=%f:%s
1268 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001269 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001270 call assert_equal('^\VLine search text\$', l[0].pattern)
1271 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001272
Bram Moolenaaree85df32017-03-19 14:19:50 +01001273 let l = split(execute('clist', ''), "\n")
1274 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1275
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001276 " Test for a long line
1277 cexpr 'Xtestfile:' . repeat('a', 1026)
1278 let l = getqflist()
1279 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1280
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001281 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001282 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001283 [Xtestfile1]
1284 (1,17) error: ';' missing
1285 (21,2) warning: variable 'z' not defined
1286 (67,3) error: end of file found before string ended
1287 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001288
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001289 [Xtestfile2]
1290 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001291
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001292 [Xtestfile3]
1293 NEW compiler v1.1
1294 (2,2) warning: variable 'x' not defined
1295 (67,3) warning: 's' already defined
1296 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001297 [DATA]
1298
Bram Moolenaaree85df32017-03-19 14:19:50 +01001299 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001300 " To exercise the push/pop file functionality in quickfix, the test files
1301 " need to be created.
1302 call writefile(['Line1'], 'Xtestfile1')
1303 call writefile(['Line2'], 'Xtestfile2')
1304 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001305 cexpr ""
1306 for l in lines
1307 caddexpr l
1308 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001309 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001310 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001311 call assert_equal(21, l[2].lnum)
1312 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001313 call assert_equal('w', l[2].type)
1314 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001315 call delete('Xtestfile1')
1316 call delete('Xtestfile2')
1317 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001318
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001319 " Test for %P, %Q with non-existing files
1320 cexpr lines
1321 let l = getqflist()
1322 call assert_equal(14, len(l))
1323 call assert_equal('[Xtestfile1]', l[0].text)
1324 call assert_equal('[Xtestfile2]', l[6].text)
1325 call assert_equal('[Xtestfile3]', l[9].text)
1326
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001327 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001328 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001329 Error 275
1330 line 42
1331 column 3
1332 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001333 [DATA]
1334
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001335 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1336 cgetexpr lines
1337 let l = getqflist()
1338 call assert_equal(275, l[0].nr)
1339 call assert_equal(42, l[0].lnum)
1340 call assert_equal(3, l[0].col)
1341 call assert_equal('E', l[0].type)
1342 call assert_equal("\n' ' expected after '--'", l[0].text)
1343
1344 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001345 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001346 Error in line 147 of foo.c:
1347 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001348 [DATA]
1349
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001350 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1351 cgetexpr lines
1352 let l = getqflist()
1353 call assert_equal(147, l[0].lnum)
1354 call assert_equal('E', l[0].type)
1355 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001356
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001357 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001358 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001359 ==============================================================
1360 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1361 --------------------------------------------------------------
1362 Traceback (most recent call last):
1363 File "unittests/dbfacadeTest.py", line 89, in testFoo
1364 self.assertEquals(34, dtid)
1365 File "/usr/lib/python2.2/unittest.py", line 286, in
1366 failUnlessEqual
1367 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001368 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001369
1370 --------------------------------------------------------------
1371 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001372 [DATA]
1373
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001374 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001375 cgetexpr lines
1376 let l = getqflist()
1377 call assert_equal(8, len(l))
1378 call assert_equal(89, l[4].lnum)
1379 call assert_equal(1, l[4].valid)
1380 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001381 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001382
Bram Moolenaard76ce852018-05-01 15:02:04 +02001383 " Test for %o
1384 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001385 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1386 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001387 let l = getqflist()
1388 call assert_equal(1, len(l), string(l))
1389 call assert_equal('Language.PureScript.Types', l[0].module)
1390 copen
1391 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1392 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001393 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001394 cclose
1395 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001396 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001397
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001398 " Test for a long module name
1399 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1400 let l = getqflist()
1401 call assert_equal(repeat('m', 1024), l[0].module)
1402 call assert_equal(15, l[0].lnum)
1403 call assert_equal('message', l[0].text)
1404
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001405 " The following sequence of commands used to crash Vim
1406 set efm=%W%m
1407 cgetexpr ['msg1']
1408 let l = getqflist()
1409 call assert_equal(1, len(l), string(l))
1410 call assert_equal('msg1', l[0].text)
1411 set efm=%C%m
1412 lexpr 'msg2'
1413 let l = getloclist(0)
1414 call assert_equal(1, len(l), string(l))
1415 call assert_equal('msg2', l[0].text)
1416 lopen
1417 call setqflist([], 'r')
1418 caddbuf
1419 let l = getqflist()
1420 call assert_equal(1, len(l), string(l))
1421 call assert_equal('|| msg2', l[0].text)
1422
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001423 " When matching error lines, case should be ignored. Test for this.
1424 set noignorecase
1425 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1426 call assert_equal(10, l.items[0].lnum)
1427 call assert_equal('Line 20', l.items[0].text)
1428 set ignorecase&
1429
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001430 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001431 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001432endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001433
Bram Moolenaare9283662020-06-07 14:10:47 +02001434" Test for '%t' (error type) field in 'efm'
1435func Test_efm_error_type()
1436 let save_efm = &efm
1437
1438 " error type
1439 set efm=%f:%l:%t:%m
1440 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1441 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1442 let output = split(execute('clist'), "\n")
1443 call assert_equal([
1444 \ ' 1 Xfile1:10 error: msg1',
1445 \ ' 2 Xfile1:20 warning: msg2',
1446 \ ' 3 Xfile1:30 info: msg3',
1447 \ ' 4 Xfile1:40 note: msg4',
1448 \ ' 5 Xfile1:50 R: msg5'], output)
1449
1450 " error type and a error number
1451 set efm=%f:%l:%t:%n:%m
1452 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1453 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1454 let output = split(execute('clist'), "\n")
1455 call assert_equal([
1456 \ ' 1 Xfile1:10 error 2: msg1',
1457 \ ' 2 Xfile1:20 warning 4: msg2',
1458 \ ' 3 Xfile1:30 info 6: msg3',
1459 \ ' 4 Xfile1:40 note 8: msg4',
1460 \ ' 5 Xfile1:50 R 3: msg5'], output)
1461 let &efm = save_efm
1462endfunc
1463
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001464func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001465 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001466 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001467 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001468 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001469 colder
1470 cgetexpr []
1471 endfunc
1472 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001473 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001474 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001475 lolder
1476 lgetexpr []
1477 endfunc
1478 endif
1479
1480 augroup testgroup
1481 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001482 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001483 augroup END
1484
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001485 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001486 let words = [ "a", "b" ]
1487 let qflist = []
1488 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001489 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001490 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001491 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001492 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001493
1494 augroup! testgroup
1495endfunc
1496
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001497func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001498 call XquickfixChangedByAutocmd('c')
1499 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001500endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001501
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001502func Test_setloclist_in_autocommand()
1503 call writefile(['test1', 'test2'], 'Xfile')
1504 edit Xfile
1505 let s:bufnr = bufnr()
1506 call setloclist(1,
1507 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1508 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1509
1510 augroup Test_LocList
1511 au!
1512 autocmd BufEnter * call setloclist(1,
1513 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1514 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1515 augroup END
1516
1517 lopen
1518 call assert_fails('exe "normal j\<CR>"', 'E926:')
1519
1520 augroup Test_LocList
1521 au!
1522 augroup END
1523 call delete('Xfile')
1524endfunc
1525
Bram Moolenaar8b201792016-03-25 15:01:10 +01001526func Test_caddbuffer_to_empty()
1527 helpgr quickfix
1528 call setqflist([], 'r')
1529 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001530 try
1531 cn
1532 catch
1533 " number of matches is unknown
1534 call assert_true(v:exception =~ 'E553:')
1535 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001536 quit!
1537endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001538
1539func Test_cgetexpr_works()
1540 " this must not crash Vim
1541 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001542 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001543endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001544
1545" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001546func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001547 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001548
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001549 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001550 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001551 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001552 call assert_equal(2, len(l))
1553 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001554 call assert_equal(3, l[1].end_lnum)
1555 call assert_equal(4, l[1].col)
1556 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001557
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001558 Xnext
1559 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1560 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001561 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001562 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001563 call assert_equal(3, line('.'))
1564
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001565 " Appending entries to the list should not change the cursor position
1566 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001567 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001568 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001569 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001570 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1571 call assert_equal(1, line('.'))
1572 close
1573
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001574 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001575 \ {'bufnr': a:bnum, 'lnum': 4},
1576 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001577 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001578 call assert_equal(3, len(l))
1579 call assert_equal(5, l[2].lnum)
1580
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001581 call g:Xsetlist([])
1582 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001583 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001584
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001585 " Tests for setting the 'valid' flag
1586 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1587 Xwindow
1588 call assert_equal(1, winnr('$'))
1589 let l = g:Xgetlist()
1590 call g:Xsetlist(l)
1591 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001592 " Adding a non-valid entry should not mark the list as having valid entries
1593 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1594 Xwindow
1595 call assert_equal(1, winnr('$'))
1596
1597 " :cnext/:cprev should still work even with invalid entries in the list
1598 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1599 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1600 call g:Xsetlist(l)
1601 Xnext
1602 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1603 Xprev
1604 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1605 " :cnext/:cprev should still work after appending invalid entries to an
1606 " empty list
1607 call g:Xsetlist([])
1608 call g:Xsetlist(l, 'a')
1609 Xnext
1610 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1611 Xprev
1612 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1613
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001614 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1615 Xwindow
1616 call assert_equal(2, winnr('$'))
1617 Xclose
1618 let save_efm = &efm
1619 set efm=%m
1620 Xgetexpr 'TestMessage'
1621 let l = g:Xgetlist()
1622 call g:Xsetlist(l)
1623 call assert_equal(1, g:Xgetlist()[0].valid)
1624 let &efm = save_efm
1625
Bram Moolenaaree85df32017-03-19 14:19:50 +01001626 " Error cases:
1627 " Refer to a non-existing buffer and pass a non-dictionary type
1628 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1629 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1630 call g:Xsetlist([[1, 2,3]])
1631 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001632 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001633endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001634
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001635func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001636 new Xtestfile | only
1637 let bnum = bufnr('%')
1638 call setline(1, range(1,5))
1639
1640 call SetXlistTests('c', bnum)
1641 call SetXlistTests('l', bnum)
1642
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001643 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001644 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001645endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001646
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001647func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001648 call s:setup_commands(a:cchar)
1649
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001650 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001651 let @/ = 'Test_'
1652 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001654 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001655 Xvimgrep empty test_quickfix.vim
1656 call assert_true(len(g:Xgetlist()) > 0)
1657 Xvimgrep matches test_quickfix.vim
1658 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001659 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001660 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001661 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001662 call g:Xsetlist([], 'r')
1663 call assert_true(len(g:Xgetlist()) == 0)
1664 Xolder
1665 call assert_equal(testlen, len(g:Xgetlist()))
1666 Xnewer
1667 Xnewer
1668 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001669endfunc
1670
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001671func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001672 call Xlist_empty_middle('c')
1673 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001674endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001675
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001676func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001677 call s:setup_commands(a:cchar)
1678
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001679 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001680 Xvimgrep one test_quickfix.vim
1681 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001682 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001683 Xvimgrep two test_quickfix.vim
1684 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001685 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001686 Xvimgrep three test_quickfix.vim
1687 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001688 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001689 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001690 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001691 call g:Xsetlist([], 'r')
1692 call assert_true(len(g:Xgetlist()) == 0)
1693 Xnewer
1694 call assert_equal(twolen, len(g:Xgetlist()))
1695 Xnewer
1696 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001697endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001698
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001699func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001700 call Xlist_empty_older('c')
1701 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001702endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001703
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001704func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001705 call s:setup_commands(a:cchar)
1706
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001707 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1708 \ {'filename': 'fnameB', 'text': 'B'}]
1709 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1710 \ {'filename': 'fnameD', 'text': 'D'},
1711 \ {'filename': 'fnameE', 'text': 'E'}]
1712
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001713 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001714 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001715 silent! Xnewer 99
1716 call g:Xsetlist(list1)
1717 call g:Xsetlist(list2)
1718 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001719 call assert_equal(3, len(li))
1720 call assert_equal('C', li[0]['text'])
1721 call assert_equal('D', li[1]['text'])
1722 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001723 silent! Xolder
1724 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001725 call assert_equal(2, len(li))
1726 call assert_equal('A', li[0]['text'])
1727 call assert_equal('B', li[1]['text'])
1728
1729 " {action} is specified ' '.
1730 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001731 silent! Xnewer 99
1732 call g:Xsetlist(list1)
1733 call g:Xsetlist(list2, ' ')
1734 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001735 call assert_equal(3, len(li))
1736 call assert_equal('C', li[0]['text'])
1737 call assert_equal('D', li[1]['text'])
1738 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 silent! Xolder
1740 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001741 call assert_equal(2, len(li))
1742 call assert_equal('A', li[0]['text'])
1743 call assert_equal('B', li[1]['text'])
1744
1745 " {action} is specified 'a'.
1746 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001747 silent! Xnewer 99
1748 call g:Xsetlist(list1)
1749 call g:Xsetlist(list2, 'a')
1750 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001751 call assert_equal(5, len(li))
1752 call assert_equal('A', li[0]['text'])
1753 call assert_equal('B', li[1]['text'])
1754 call assert_equal('C', li[2]['text'])
1755 call assert_equal('D', li[3]['text'])
1756 call assert_equal('E', li[4]['text'])
1757
1758 " {action} is specified 'r'.
1759 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001760 silent! Xnewer 99
1761 call g:Xsetlist(list1)
1762 call g:Xsetlist(list2, 'r')
1763 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001764 call assert_equal(3, len(li))
1765 call assert_equal('C', li[0]['text'])
1766 call assert_equal('D', li[1]['text'])
1767 call assert_equal('E', li[2]['text'])
1768
1769 " Test for wrong value.
1770 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001771 call assert_fails("call g:Xsetlist(0)", 'E714:')
1772 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1773 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1774 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1775 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001776endfunc
1777
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001778func Test_setqflist_invalid_nr()
1779 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001780 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001781endfunc
1782
Bram Moolenaar99234f22020-02-10 22:56:54 +01001783func Test_setqflist_user_sets_buftype()
1784 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1785 set buftype=quickfix
1786 call setqflist([], 'a')
1787 enew
1788endfunc
1789
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001790func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001791 call XquickfixSetListWithAct('c')
1792 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001793endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001794
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001795func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001796 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001797
Bram Moolenaar049cba92016-06-26 14:38:04 +02001798 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001799 call assert_equal(1, l[0].lnum)
1800 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001801 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001802 call assert_equal(2, l[1].lnum)
1803 call assert_equal(1, l[1].col)
1804 call assert_equal(4070, len(l[1].text))
1805 call assert_equal(3, l[2].lnum)
1806 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001807 call assert_equal(4070, len(l[2].text))
1808 call assert_equal(4, l[3].lnum)
1809 call assert_equal(1, l[3].col)
1810 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001811
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001812 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001813endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001814
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001815func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001816 call s:setup_commands(a:cchar)
1817
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001818 let testfile = 'samples/quickfix.txt'
1819
1820 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001821 exe 'Xgetfile' testfile
1822 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001823
1824 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001825 Xexpr readfile(testfile)
1826 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001827
1828 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001829 Xexpr join(readfile(testfile), "\n")
1830 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001831
1832 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001833 exe 'edit' testfile
1834 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001835 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001836endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001837
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001838func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001839 call s:long_lines_tests('c')
1840 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001841endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001842
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001843func Test_cgetfile_on_long_lines()
1844 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1845 " are read at a time.
1846 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1847 let lines = [
1848 \ '/tmp/file1:1:1:aaa',
1849 \ '/tmp/file2:1:1:%s',
1850 \ '/tmp/file3:1:1:bbb',
1851 \ '/tmp/file4:1:1:ccc',
1852 \ ]
1853 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1854 call writefile(lines, 'Xcqetfile.txt')
1855 cgetfile Xcqetfile.txt
1856 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1857 endfor
1858 call delete('Xcqetfile.txt')
1859endfunc
1860
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001861func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001862 let l = []
1863 for i in range(1, 20)
1864 call add(l, 'Line' . i)
1865 endfor
1866 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001867endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001868
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001869func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001870 call s:create_test_file('Xqftestfile1')
1871 call s:create_test_file('Xqftestfile2')
1872 call s:create_test_file('Xqftestfile3')
1873
1874 new | only
1875 edit Xqftestfile1
1876 let file1_winid = win_getid()
1877 new Xqftestfile2
1878 let file2_winid = win_getid()
1879 cgetexpr ['Xqftestfile1:5:Line5',
1880 \ 'Xqftestfile1:6:Line6',
1881 \ 'Xqftestfile2:10:Line10',
1882 \ 'Xqftestfile2:11:Line11',
1883 \ 'Xqftestfile3:15:Line15',
1884 \ 'Xqftestfile3:16:Line16']
1885
1886 new
1887 let winid = win_getid()
1888 cfirst | cnext
1889 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001890 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001891 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001892 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001893 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001894
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001895 " Test for 'switchbuf' set to search for files in windows in the current
1896 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001897 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001898 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001899 cfirst | cnext
1900 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001901 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001902 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001903 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001904 call assert_equal(file2_winid, win_getid())
1905
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001906 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1907 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001908 enew | only
1909 set switchbuf=usetab
1910 tabedit Xqftestfile1
1911 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001912 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001913 tabfirst
1914 cfirst | cnext
1915 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001916 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001917 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001918 6cnext
1919 call assert_equal(4, tabpagenr())
1920 2cpfile
1921 call assert_equal(2, tabpagenr())
1922 2cnfile
1923 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001924 tabfirst | tabonly | enew
1925
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001926 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001927 set switchbuf=split
1928 cfirst | cnext
1929 call assert_equal(1, winnr('$'))
1930 cnext | cnext
1931 call assert_equal(2, winnr('$'))
1932 cnext | cnext
1933 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001934
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001935 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001936 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001937 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001938 cfirst | cnext
1939 call assert_equal(1, tabpagenr('$'))
1940 cnext | cnext
1941 call assert_equal(2, tabpagenr('$'))
1942 cnext | cnext
1943 call assert_equal(3, tabpagenr('$'))
1944 tabfirst | enew | tabonly | only
1945
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001946 set switchbuf=uselast
1947 split
1948 let last_winid = win_getid()
1949 copen
1950 exe "normal 1G\<CR>"
1951 call assert_equal(last_winid, win_getid())
1952 enew | only
1953
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001954 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1955 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001956 set switchbuf=
1957 edit Xqftestfile1
1958 let file1_winid = win_getid()
1959 new Xqftestfile2
1960 let file2_winid = win_getid()
1961 copen
1962 exe "normal 1G\<CR>"
1963 call assert_equal(file1_winid, win_getid())
1964 copen
1965 exe "normal 3G\<CR>"
1966 call assert_equal(file2_winid, win_getid())
1967 copen | only
1968 exe "normal 5G\<CR>"
1969 call assert_equal(2, winnr('$'))
1970 call assert_equal(1, bufwinnr('Xqftestfile3'))
1971
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001972 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001973 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001974 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001975 set switchbuf=usetab
1976 tabedit Xqftestfile1
1977 tabedit Xqftestfile2
1978 tabedit Xqftestfile3
1979 tabfirst
1980 copen | only
1981 clast
1982 call assert_equal(4, tabpagenr())
1983 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001984
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001985 " Jumping to a file that is not present in any of the tabpages and the
1986 " current tabpage doesn't have any usable windows, should open it in a new
1987 " window in the current tabpage.
1988 copen | only
1989 cfirst
1990 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001991 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001992
1993 " If opening a file changes 'switchbuf', then the new value should be
1994 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001995 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001996 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1997 enew | only
1998 set switchbuf&vim
1999 cexpr "Xqftestfile1:1:10"
2000 call assert_equal('split', &switchbuf)
2001 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2002 enew | only
2003 set switchbuf=useopen
2004 cexpr "Xqftestfile1:1:10"
2005 call assert_equal('usetab', &switchbuf)
2006 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2007 enew | only
2008 set switchbuf=useopen
2009 cexpr "Xqftestfile1:1:10"
2010 call assert_equal('', &switchbuf)
2011
Bram Moolenaar049cba92016-06-26 14:38:04 +02002012 call delete('Xqftestfile1')
2013 call delete('Xqftestfile2')
2014 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002015 set switchbuf&vim
2016
2017 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002018endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002019
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002020func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002021 call s:setup_commands(a:cchar)
2022
2023 enew | only
2024
Bram Moolenaarc1542742016-07-20 21:44:37 +02002025 let fname = 'Xqftestfile' . a:cchar
2026 call s:create_test_file(fname)
2027 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002028
Bram Moolenaarc1542742016-07-20 21:44:37 +02002029 Xgetexpr [fname . ':5:Line5',
2030 \ fname . ':10:Line10',
2031 \ fname . ':15:Line15',
2032 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002033
2034 6,14delete
2035 call append(6, ['Buffer', 'Window'])
2036
2037 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002038 call assert_equal(5, l[0].lnum)
2039 call assert_equal(6, l[2].lnum)
2040 call assert_equal(13, l[3].lnum)
2041
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002042 " If a file doesn't have any quickfix entries, then deleting lines in the
2043 " file should not update the quickfix list
2044 call g:Xsetlist([], 'f')
2045 1,2delete
2046 call assert_equal([], g:Xgetlist())
2047
Bram Moolenaar049cba92016-06-26 14:38:04 +02002048 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002049 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002050endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002051
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002052func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002053 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002054 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002055 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002056 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002057endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002058
2059" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002060func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002061 call s:setup_commands(a:cchar)
2062
2063 " The following lines are used for the grep test. Don't remove.
2064 " Grep_Test_Text: Match 1
2065 " Grep_Test_Text: Match 2
2066 " GrepAdd_Test_Text: Match 1
2067 " GrepAdd_Test_Text: Match 2
2068 enew! | only
2069 set makeef&vim
2070 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002071 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002072 Xopen
2073 call assert_true(w:quickfix_title =~ '^:grep')
2074 Xclose
2075 enew
2076 set makeef=Temp_File_##
2077 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002078 call assert_true(len(g:Xgetlist()) == 9)
2079
2080 " Try with 'grepprg' set to 'internal'
2081 set grepprg=internal
2082 silent Xgrep Grep_Test_Text: test_quickfix.vim
2083 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2084 call assert_true(len(g:Xgetlist()) == 9)
2085 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002086
2087 call writefile(['Vim'], 'XtestTempFile')
2088 set makeef=XtestTempFile
2089 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002090 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002091 call assert_false(filereadable('XtestTempFile'))
2092 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002093endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002094
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002095func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002096 " The grepprg may not be set on non-Unix systems
2097 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002098
2099 call s:test_xgrep('c')
2100 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002101endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002102
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002103func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002104 " Use one 'errorformat' for two windows. Add an expression to each of them,
2105 " make sure they each keep their own state.
2106 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2107 call mkdir('Xone/a', 'p')
2108 call mkdir('Xtwo/a', 'p')
2109 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2110 call writefile(lines, 'Xone/a/one.txt')
2111 call writefile(lines, 'Xtwo/a/two.txt')
2112
2113 new one
2114 let one_id = win_getid()
2115 lexpr ""
2116 new two
2117 let two_id = win_getid()
2118 lexpr ""
2119
2120 laddexpr "Entering dir 'Xtwo/a'"
2121 call win_gotoid(one_id)
2122 laddexpr "Entering dir 'Xone/a'"
2123 call win_gotoid(two_id)
2124 laddexpr 'two.txt:5:two two two'
2125 call win_gotoid(one_id)
2126 laddexpr 'one.txt:3:one one one'
2127
2128 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002129 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2130 call assert_equal(3, loc_one[1].lnum)
2131
2132 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002133 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2134 call assert_equal(5, loc_two[1].lnum)
2135
2136 call win_gotoid(one_id)
2137 bwipe!
2138 call win_gotoid(two_id)
2139 bwipe!
2140 call delete('Xone', 'rf')
2141 call delete('Xtwo', 'rf')
2142endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002143
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002144func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002145 call s:setup_commands(a:cchar)
2146
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002147 " Calling lbottom without any errors should fail
2148 if a:cchar == 'l'
2149 call assert_fails('lbottom', 'E776:')
2150 endif
2151
Bram Moolenaar875feea2017-06-11 16:07:51 +02002152 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002153 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002154 let wid = win_getid()
2155 call assert_equal(1, line('.'))
2156 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002157 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002158 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002159 call win_gotoid(wid)
2160 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002161 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002162endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002163
2164" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002165func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002166 call XbottomTests('c')
2167 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002168endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002169
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002170func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002171 call s:setup_commands(a:cchar)
2172
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002173 " clear all lists after the first one, then replace the first one.
2174 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002175 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002176 let entry = {'filename': 'foo', 'lnum': 42}
2177 call g:Xsetlist([entry], 'r')
2178 call g:Xsetlist([entry, entry])
2179 call g:Xsetlist([entry, entry, entry])
2180 let res = split(execute(a:cchar . 'hist'), "\n")
2181 call assert_equal(3, len(res))
2182 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2183 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2184 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2185 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002186
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002187 " Test for changing the quickfix lists
2188 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2189 exe '1' . a:cchar . 'hist'
2190 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2191 exe '3' . a:cchar . 'hist'
2192 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2193 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2194 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2195
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002196 call g:Xsetlist([], 'f')
2197 let l = split(execute(a:cchar . 'hist'), "\n")
2198 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002199 if a:cchar == 'c'
2200 call assert_fails('4chist', 'E16:')
2201 else
2202 call assert_fails('4lhist', 'E776:')
2203 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002204
2205 " An empty list should still show the stack history
2206 call g:Xsetlist([])
2207 let res = split(execute(a:cchar . 'hist'), "\n")
2208 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2209
2210 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002211endfunc
2212
2213func Test_history()
2214 call HistoryTest('c')
2215 call HistoryTest('l')
2216endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002217
2218func Test_duplicate_buf()
2219 " make sure we can get the highest buffer number
2220 edit DoesNotExist
2221 edit DoesNotExist2
2222 let last_buffer = bufnr("$")
2223
2224 " make sure only one buffer is created
2225 call writefile(['this one', 'that one'], 'Xgrepthis')
2226 vimgrep one Xgrepthis
2227 vimgrep one Xgrepthis
2228 call assert_equal(last_buffer + 1, bufnr("$"))
2229
2230 call delete('Xgrepthis')
2231endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002232
2233" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002234func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002235 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002236
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002237 " Error cases
2238 call assert_fails('call g:Xgetlist(99)', 'E715:')
2239 call assert_fails('call g:Xsetlist(99)', 'E714:')
2240 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002241
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002242 " Set and get the title
2243 call g:Xsetlist([])
2244 Xopen
2245 wincmd p
2246 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2247 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2248 call assert_equal(0, s)
2249 let d = g:Xgetlist({"title":1})
2250 call assert_equal('Sample', d.title)
2251 " Try setting title to a non-string value
2252 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2253 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2254
2255 Xopen
2256 call assert_equal('Sample', w:quickfix_title)
2257 Xclose
2258
2259 " Tests for action argument
2260 silent! Xolder 999
2261 let qfnr = g:Xgetlist({'all':1}).nr
2262 call g:Xsetlist([], 'r', {'title' : 'N1'})
2263 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2264 call g:Xsetlist([], ' ', {'title' : 'N2'})
2265 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2266
2267 let res = g:Xgetlist({'nr': 0})
2268 call assert_equal(qfnr + 1, res.nr)
2269 call assert_equal(['nr'], keys(res))
2270
2271 call g:Xsetlist([], ' ', {'title' : 'N3'})
2272 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2273
2274 " Changing the title of an earlier quickfix list
2275 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2276 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2277
2278 " Changing the title of an invalid quickfix list
2279 call assert_equal(-1, g:Xsetlist([], ' ',
2280 \ {'title' : 'SomeTitle', 'nr' : 99}))
2281 call assert_equal(-1, g:Xsetlist([], ' ',
2282 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2283
2284 if a:cchar == 'c'
2285 copen
2286 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2287 cclose
2288 endif
2289
2290 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002291 call assert_fails('call g:Xgetlist([])', 'E715:')
2292 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002293 let s = g:Xsetlist([], 'a', {'abc':1})
2294 call assert_equal(-1, s)
2295
2296 call assert_equal({}, g:Xgetlist({'abc':1}))
2297 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2298 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2299
2300 if a:cchar == 'l'
2301 call assert_equal({}, getloclist(99, {'title': 1}))
2302 endif
2303
2304 " Context related tests
2305 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2306 call assert_equal(0, s)
2307 call test_garbagecollect_now()
2308 let d = g:Xgetlist({'context':1})
2309 call assert_equal([1,2,3], d.context)
2310 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2311 let d = g:Xgetlist({'context':1})
2312 call assert_equal({'color':'green'}, d.context)
2313 call g:Xsetlist([], 'a', {'context':"Context info"})
2314 let d = g:Xgetlist({'context':1})
2315 call assert_equal("Context info", d.context)
2316 call g:Xsetlist([], 'a', {'context':246})
2317 let d = g:Xgetlist({'context':1})
2318 call assert_equal(246, d.context)
2319 " set other Vim data types as context
2320 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2321 if has('channel')
2322 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2323 endif
2324 if has('job')
2325 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2326 endif
2327 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2328 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2329 call g:Xsetlist([], 'a', {'context' : ''})
2330 call test_garbagecollect_now()
2331 if a:cchar == 'l'
2332 " Test for copying context across two different location lists
2333 new | only
2334 let w1_id = win_getid()
2335 let l = [1]
2336 call setloclist(0, [], 'a', {'context':l})
2337 new
2338 let w2_id = win_getid()
2339 call add(l, 2)
2340 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2341 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2342 unlet! l
2343 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2344 only
2345 call setloclist(0, [], 'f')
2346 call assert_equal('', getloclist(0, {'context':1}).context)
2347 endif
2348
2349 " Test for changing the context of previous quickfix lists
2350 call g:Xsetlist([], 'f')
2351 Xexpr "One"
2352 Xexpr "Two"
2353 Xexpr "Three"
2354 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2355 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2356 " Also, check for setting the context using quickfix list number zero.
2357 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2358 call test_garbagecollect_now()
2359 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2360 call assert_equal([1], l.context)
2361 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2362 call assert_equal([2], l.context)
2363 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2364 call assert_equal([3], l.context)
2365
2366 " Test for changing the context through reference and for garbage
2367 " collection of quickfix context
2368 let l = ["red"]
2369 call g:Xsetlist([], ' ', {'context' : l})
2370 call add(l, "blue")
2371 let x = g:Xgetlist({'context' : 1})
2372 call add(x.context, "green")
2373 call assert_equal(["red", "blue", "green"], l)
2374 call assert_equal(["red", "blue", "green"], x.context)
2375 unlet l
2376 call test_garbagecollect_now()
2377 let m = g:Xgetlist({'context' : 1})
2378 call assert_equal(["red", "blue", "green"], m.context)
2379
2380 " Test for setting/getting items
2381 Xexpr ""
2382 let qfprev = g:Xgetlist({'nr':0})
2383 let s = g:Xsetlist([], ' ', {'title':'Green',
2384 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2385 call assert_equal(0, s)
2386 let qfcur = g:Xgetlist({'nr':0})
2387 call assert_true(qfcur.nr == qfprev.nr + 1)
2388 let l = g:Xgetlist({'items':1})
2389 call assert_equal('F1', bufname(l.items[0].bufnr))
2390 call assert_equal(10, l.items[0].lnum)
2391 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2392 \ {'filename':'F2', 'lnum':30}]})
2393 let l = g:Xgetlist({'items':1})
2394 call assert_equal('F2', bufname(l.items[2].bufnr))
2395 call assert_equal(30, l.items[2].lnum)
2396 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2397 let l = g:Xgetlist({'items':1})
2398 call assert_equal('F3', bufname(l.items[0].bufnr))
2399 call assert_equal(40, l.items[0].lnum)
2400 call g:Xsetlist([], 'r', {'items' : []})
2401 let l = g:Xgetlist({'items':1})
2402 call assert_equal(0, len(l.items))
2403
2404 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2405 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2406 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2407 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2408
2409 " Test for getting id of window associated with a location list window
2410 if a:cchar == 'l'
2411 only
2412 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2413 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002414 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002415 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2416 wincmd w
2417 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2418 only
2419 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002420
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002421 " The following used to crash Vim with address sanitizer
2422 call g:Xsetlist([], 'f')
2423 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2424 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002425
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002426 " Try setting the items using a string
2427 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002428
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002429 " Save and restore the quickfix stack
2430 call g:Xsetlist([], 'f')
2431 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2432 Xexpr "File1:10:Line1"
2433 Xexpr "File2:20:Line2"
2434 Xexpr "File3:30:Line3"
2435 let last_qf = g:Xgetlist({'nr':'$'}).nr
2436 call assert_equal(3, last_qf)
2437 let qstack = []
2438 for i in range(1, last_qf)
2439 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2440 endfor
2441 call g:Xsetlist([], 'f')
2442 for i in range(len(qstack))
2443 call g:Xsetlist([], ' ', qstack[i])
2444 endfor
2445 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2446 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2447 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2448 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2449 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002450
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002451 " Swap two quickfix lists
2452 Xexpr "File1:10:Line10"
2453 Xexpr "File2:20:Line20"
2454 Xexpr "File3:30:Line30"
2455 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2456 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2457 let l1=g:Xgetlist({'nr':1,'all':1})
2458 let l2=g:Xgetlist({'nr':2,'all':1})
2459 let save_id = l1.id
2460 let l1.id=l2.id
2461 let l2.id=save_id
2462 call g:Xsetlist([], 'r', l1)
2463 call g:Xsetlist([], 'r', l2)
2464 let newl1=g:Xgetlist({'nr':1,'all':1})
2465 let newl2=g:Xgetlist({'nr':2,'all':1})
2466 call assert_equal('Fruits', newl1.title)
2467 call assert_equal(['Fruits'], newl1.context)
2468 call assert_equal('Line20', newl1.items[0].text)
2469 call assert_equal('Colors', newl2.title)
2470 call assert_equal(['Colors'], newl2.context)
2471 call assert_equal('Line10', newl2.items[0].text)
2472 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002473
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002474 " Cannot specify both a non-empty list argument and a dict argument
2475 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002476endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002477
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002478func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002479 call Xproperty_tests('c')
2480 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002481endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002482
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002483" Test for setting the current index in the location/quickfix list
2484func Xtest_setqfidx(cchar)
2485 call s:setup_commands(a:cchar)
2486
2487 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2488 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2489 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2490
2491 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2492 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2493 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2494 Xolder 2
2495 Xopen
2496 call assert_equal(3, line('.'))
2497 Xnewer
2498 call assert_equal(2, line('.'))
2499 Xnewer
2500 call assert_equal(2, line('.'))
2501 " Update the current index with the quickfix window open
2502 wincmd w
2503 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2504 Xopen
2505 call assert_equal(3, line('.'))
2506 Xclose
2507
2508 " Set the current index to the last entry
2509 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2510 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2511 " A large value should set the index to the last index
2512 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2513 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2514 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2515 " Invalid index values
2516 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2517 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2518 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2519 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2520 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2521 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2522 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2523
2524 call g:Xsetlist([], 'f')
2525 new | only
2526endfunc
2527
2528func Test_setqfidx()
2529 call Xtest_setqfidx('c')
2530 call Xtest_setqfidx('l')
2531endfunc
2532
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002533" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002534func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002535 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002536endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002537
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002538func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002539 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2540 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2541
2542 let g:acmds = []
2543 cexpr "F1:10:Line 10"
2544 caddexpr "F1:20:Line 20"
2545 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002546 cexpr ""
2547 caddexpr ""
2548 cgetexpr ""
2549 silent! cexpr non_existing_func()
2550 silent! caddexpr non_existing_func()
2551 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002552 let l = ['precexpr',
2553 \ 'postcexpr',
2554 \ 'precaddexpr',
2555 \ 'postcaddexpr',
2556 \ 'precgetexpr',
2557 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002558 \ 'precexpr',
2559 \ 'postcexpr',
2560 \ 'precaddexpr',
2561 \ 'postcaddexpr',
2562 \ 'precgetexpr',
2563 \ 'postcgetexpr',
2564 \ 'precexpr',
2565 \ 'precaddexpr',
2566 \ 'precgetexpr']
2567 call assert_equal(l, g:acmds)
2568
2569 let g:acmds = []
2570 enew! | call append(0, "F2:10:Line 10")
2571 cbuffer!
2572 enew! | call append(0, "F2:20:Line 20")
2573 cgetbuffer
2574 enew! | call append(0, "F2:30:Line 30")
2575 caddbuffer
2576 new
2577 let bnum = bufnr('%')
2578 bunload
2579 exe 'silent! cbuffer! ' . bnum
2580 exe 'silent! cgetbuffer ' . bnum
2581 exe 'silent! caddbuffer ' . bnum
2582 enew!
2583 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002584 \ 'postcbuffer',
2585 \ 'precgetbuffer',
2586 \ 'postcgetbuffer',
2587 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002588 \ 'postcaddbuffer',
2589 \ 'precbuffer',
2590 \ 'precgetbuffer',
2591 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002592 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002593
2594 call writefile(['Xtest:1:Line1'], 'Xtest')
2595 call writefile([], 'Xempty')
2596 let g:acmds = []
2597 cfile Xtest
2598 caddfile Xtest
2599 cgetfile Xtest
2600 cfile Xempty
2601 caddfile Xempty
2602 cgetfile Xempty
2603 silent! cfile do_not_exist
2604 silent! caddfile do_not_exist
2605 silent! cgetfile do_not_exist
2606 let l = ['precfile',
2607 \ 'postcfile',
2608 \ 'precaddfile',
2609 \ 'postcaddfile',
2610 \ 'precgetfile',
2611 \ 'postcgetfile',
2612 \ 'precfile',
2613 \ 'postcfile',
2614 \ 'precaddfile',
2615 \ 'postcaddfile',
2616 \ 'precgetfile',
2617 \ 'postcgetfile',
2618 \ 'precfile',
2619 \ 'postcfile',
2620 \ 'precaddfile',
2621 \ 'postcaddfile',
2622 \ 'precgetfile',
2623 \ 'postcgetfile']
2624 call assert_equal(l, g:acmds)
2625
2626 let g:acmds = []
2627 helpgrep quickfix
2628 silent! helpgrep non_existing_help_topic
2629 vimgrep test Xtest
2630 vimgrepadd test Xtest
2631 silent! vimgrep non_existing_test Xtest
2632 silent! vimgrepadd non_existing_test Xtest
2633 set makeprg=
2634 silent! make
2635 set makeprg&
2636 let l = ['prehelpgrep',
2637 \ 'posthelpgrep',
2638 \ 'prehelpgrep',
2639 \ 'posthelpgrep',
2640 \ 'previmgrep',
2641 \ 'postvimgrep',
2642 \ 'previmgrepadd',
2643 \ 'postvimgrepadd',
2644 \ 'previmgrep',
2645 \ 'postvimgrep',
2646 \ 'previmgrepadd',
2647 \ 'postvimgrepadd',
2648 \ 'premake',
2649 \ 'postmake']
2650 call assert_equal(l, g:acmds)
2651
2652 if has('unix')
2653 " Run this test only on Unix-like systems. The grepprg may not be set on
2654 " non-Unix systems.
2655 " The following lines are used for the grep test. Don't remove.
2656 " Grep_Autocmd_Text: Match 1
2657 " GrepAdd_Autocmd_Text: Match 2
2658 let g:acmds = []
2659 silent grep Grep_Autocmd_Text test_quickfix.vim
2660 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2661 silent grep abc123def Xtest
2662 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002663 set grepprg=internal
2664 silent grep Grep_Autocmd_Text test_quickfix.vim
2665 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2666 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2667 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2668 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002669 let l = ['pregrep',
2670 \ 'postgrep',
2671 \ 'pregrepadd',
2672 \ 'postgrepadd',
2673 \ 'pregrep',
2674 \ 'postgrep',
2675 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002676 \ 'postgrepadd',
2677 \ 'pregrep',
2678 \ 'postgrep',
2679 \ 'pregrepadd',
2680 \ 'postgrepadd',
2681 \ 'prelgrep',
2682 \ 'postlgrep',
2683 \ 'prelgrepadd',
2684 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002685 call assert_equal(l, g:acmds)
2686 endif
2687
2688 call delete('Xtest')
2689 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002690 au! QuickFixCmdPre
2691 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002692endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002693
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002694func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002695 set efm=%m
2696 lgetexpr '?'
2697
2698 try
2699 call DoesNotExit()
2700 catch
2701 lgetexpr '1'
2702 finally
2703 lgetexpr '1'
2704 endtry
2705
2706 call assert_equal('1', getloclist(0)[0].text)
2707
2708 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002709endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002710
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002711func Test_caddbuffer_wrong()
2712 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002713 let save_efm = &efm
2714 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2715 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2716 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002717 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002718 bwipe!
2719endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002720
2721func Test_caddexpr_wrong()
2722 " This used to cause a memory access in freed memory.
2723 cbuffer
2724 cbuffer
2725 copen
2726 let save_efm = &efm
2727 set efm=%
2728 call assert_fails('caddexpr ""', 'E376:')
2729 let &efm = save_efm
2730endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002731
2732func Test_dirstack_cleanup()
2733 " This used to cause a memory access in freed memory.
2734 let save_efm = &efm
2735 lexpr '0'
2736 lopen
2737 fun X(c)
2738 let save_efm=&efm
2739 set efm=%D%f
2740 if a:c == 'c'
2741 caddexpr '::'
2742 else
2743 laddexpr ':0:0'
2744 endif
2745 let &efm=save_efm
2746 endfun
2747 call X('c')
2748 call X('l')
2749 call setqflist([], 'r')
2750 caddbuffer
2751 let &efm = save_efm
2752endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002753
2754" Tests for jumping to entries from the location list window and quickfix
2755" window
2756func Test_cwindow_jump()
2757 set efm=%f%%%l%%%m
2758 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2759 lopen | only
2760 lfirst
2761 call assert_true(winnr('$') == 2)
2762 call assert_true(winnr() == 1)
2763 " Location list for the new window should be set
2764 call assert_true(getloclist(0)[2].text == 'Line 30')
2765
2766 " Open a scratch buffer
2767 " Open a new window and create a location list
2768 " Open the location list window and close the other window
2769 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002770 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002771 " should not be used.
2772 enew | only
2773 set buftype=nofile
2774 below new
2775 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2776 lopen
2777 2wincmd c
2778 lnext
2779 call assert_true(winnr('$') == 3)
2780 call assert_true(winnr() == 2)
2781
2782 " Open two windows with two different location lists
2783 " Open the location list window and close the previous window
2784 " Jump to an entry in the location list window
2785 " Should open the file in the first window and not set the location list.
2786 enew | only
2787 lgetexpr ["F1%5%Line 5"]
2788 below new
2789 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2790 lopen
2791 2wincmd c
2792 lnext
2793 call assert_true(winnr() == 1)
2794 call assert_true(getloclist(0)[0].text == 'Line 5')
2795
2796 enew | only
2797 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2798 copen
2799 cnext
2800 call assert_true(winnr('$') == 2)
2801 call assert_true(winnr() == 1)
2802
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002803 " open the quickfix buffer in two windows and jump to an entry. Should open
2804 " the file in the first quickfix window.
2805 enew | only
2806 copen
2807 let bnum = bufnr('')
2808 exe 'sbuffer ' . bnum
2809 wincmd b
2810 cfirst
2811 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002812 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002813 enew | only
2814 exe 'sb' bnum
2815 exe 'botright sb' bnum
2816 wincmd t
2817 clast
2818 call assert_equal(2, winnr())
2819 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2820 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2821
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002822 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002823 " window by wrapping around the window list.
2824 enew | only
2825 call setloclist(0, [], 'f')
2826 new | new
2827 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2828 lopen
2829 1close
2830 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2831 lnext
2832 call assert_equal(3, winnr())
2833 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2834
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002835 enew | only
2836 set efm&vim
2837endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002838
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002839func Test_cwindow_highlight()
2840 CheckScreendump
2841
2842 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002843 call setline(1, ['some', 'text', 'with', 'matches'])
2844 write XCwindow
2845 vimgrep e XCwindow
2846 redraw
2847 cwindow 4
2848 END
2849 call writefile(lines, 'XtestCwindow')
2850 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2851 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2852
2853 call term_sendkeys(buf, ":cnext\<CR>")
2854 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2855
2856 " clean up
2857 call StopVimInTerminal(buf)
2858 call delete('XtestCwindow')
2859 call delete('XCwindow')
2860endfunc
2861
Bram Moolenaaree85df32017-03-19 14:19:50 +01002862func XvimgrepTests(cchar)
2863 call s:setup_commands(a:cchar)
2864
2865 call writefile(['Editor:VIM vim',
2866 \ 'Editor:Emacs EmAcS',
2867 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002868 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002869
2870 " Error cases
2871 call assert_fails('Xvimgrep /abc *', 'E682:')
2872
2873 let @/=''
2874 call assert_fails('Xvimgrep // *', 'E35:')
2875
2876 call assert_fails('Xvimgrep abc', 'E683:')
2877 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2878 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2879
2880 Xexpr ""
2881 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002882 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002883 let l = g:Xgetlist()
2884 call assert_equal(2, len(l))
2885 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2886
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002887 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002888 let l = g:Xgetlist()
2889 call assert_equal(2, len(l))
2890 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002891 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002892 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002893 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002894
2895 1Xvimgrep ?Editor? Xtestfile*
2896 let l = g:Xgetlist()
2897 call assert_equal(1, len(l))
2898 call assert_equal('Editor:VIM vim', l[0].text)
2899
2900 edit +3 Xtestfile2
2901 Xvimgrep +\cemacs+j Xtestfile1
2902 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002903 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002904 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2905
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002906 " Test for unloading a buffer after vimgrep searched the buffer
2907 %bwipe
2908 Xvimgrep /Editor/j Xtestfile*
2909 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2910 call assert_equal([], getbufinfo('Xtestfile2'))
2911
Bram Moolenaaree85df32017-03-19 14:19:50 +01002912 call delete('Xtestfile1')
2913 call delete('Xtestfile2')
2914endfunc
2915
2916" Tests for the :vimgrep command
2917func Test_vimgrep()
2918 call XvimgrepTests('c')
2919 call XvimgrepTests('l')
2920endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002921
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002922func Test_vimgrep_wildcards_expanded_once()
2923 new X[id-01] file.txt
2924 call setline(1, 'some text to search for')
2925 vimgrep text %
2926 bwipe!
2927endfunc
2928
Bram Moolenaar1c299432018-10-28 14:36:09 +01002929" Test for incsearch highlighting of the :vimgrep pattern
2930" This test used to cause "E315: ml_get: invalid lnum" errors.
2931func Test_vimgrep_incsearch()
2932 enew
2933 set incsearch
2934 call test_override("char_avail", 1)
2935
2936 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2937 let l = getqflist()
2938 call assert_equal(2, len(l))
2939
2940 call test_override("ALL", 0)
2941 set noincsearch
2942endfunc
2943
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002944" Test vimgrep with the last search pattern not set
2945func Test_vimgrep_with_no_last_search_pat()
2946 let lines =<< trim [SCRIPT]
2947 call assert_fails('vimgrep // *', 'E35:')
2948 call writefile(v:errors, 'Xresult')
2949 qall!
2950 [SCRIPT]
2951 call writefile(lines, 'Xscript')
2952 if RunVim([], [], '--clean -S Xscript')
2953 call assert_equal([], readfile('Xresult'))
2954 endif
2955 call delete('Xscript')
2956 call delete('Xresult')
2957endfunc
2958
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002959" Test vimgrep without swap file
2960func Test_vimgrep_without_swap_file()
2961 let lines =<< trim [SCRIPT]
2962 vimgrep grep test_c*
2963 call writefile(['done'], 'Xresult')
2964 qall!
2965 [SCRIPT]
2966 call writefile(lines, 'Xscript')
2967 if RunVim([], [], '--clean -n -S Xscript Xscript')
2968 call assert_equal(['done'], readfile('Xresult'))
2969 endif
2970 call delete('Xscript')
2971 call delete('Xresult')
2972endfunc
2973
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002974func Test_vimgrep_existing_swapfile()
2975 call writefile(['match apple with apple'], 'Xapple')
2976 call writefile(['swapfile'], '.Xapple.swp')
2977 let g:foundSwap = 0
2978 let g:ignoreSwapExists = 1
2979 augroup grep
2980 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2981 augroup END
2982 vimgrep apple Xapple
2983 call assert_equal(1, g:foundSwap)
2984 call assert_match('.Xapple.swo', swapname(''))
2985
2986 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002987 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002988 augroup grep
2989 au! SwapExists
2990 augroup END
2991 unlet g:ignoreSwapExists
2992endfunc
2993
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002994func XfreeTests(cchar)
2995 call s:setup_commands(a:cchar)
2996
2997 enew | only
2998
2999 " Deleting the quickfix stack should work even When the current list is
3000 " somewhere in the middle of the stack
3001 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3002 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3003 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3004 Xolder
3005 call g:Xsetlist([], 'f')
3006 call assert_equal(0, len(g:Xgetlist()))
3007
3008 " After deleting the stack, adding a new list should create a stack with a
3009 " single list.
3010 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3011 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3012
3013 " Deleting the stack from a quickfix window should update/clear the
3014 " quickfix/location list window.
3015 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3016 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3017 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3018 Xolder
3019 Xwindow
3020 call g:Xsetlist([], 'f')
3021 call assert_equal(2, winnr('$'))
3022 call assert_equal(1, line('$'))
3023 Xclose
3024
3025 " Deleting the stack from a non-quickfix window should update/clear the
3026 " quickfix/location list window.
3027 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3028 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3029 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3030 Xolder
3031 Xwindow
3032 wincmd p
3033 call g:Xsetlist([], 'f')
3034 call assert_equal(0, len(g:Xgetlist()))
3035 wincmd p
3036 call assert_equal(2, winnr('$'))
3037 call assert_equal(1, line('$'))
3038
3039 " After deleting the location list stack, if the location list window is
3040 " opened, then a new location list should be created. So opening the
3041 " location list window again should not create a new window.
3042 if a:cchar == 'l'
3043 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3044 wincmd p
3045 lopen
3046 call assert_equal(2, winnr('$'))
3047 endif
3048 Xclose
3049endfunc
3050
Bram Moolenaar74240d32017-12-10 15:26:15 +01003051" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003052func Test_qf_free()
3053 call XfreeTests('c')
3054 call XfreeTests('l')
3055endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003056
3057" Test for buffer overflow when parsing lines and adding new entries to
3058" the quickfix list.
3059func Test_bufoverflow()
3060 set efm=%f:%l:%m
3061 cgetexpr ['File1:100:' . repeat('x', 1025)]
3062
3063 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3064 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3065
3066 set efm=%DEntering\ directory\ %f,%f:%l:%m
3067 cgetexpr ['Entering directory ' . repeat('a', 1006),
3068 \ 'File1:10:Hello World']
3069 set efm&vim
3070endfunc
3071
Bram Moolenaar875feea2017-06-11 16:07:51 +02003072" Tests for getting the quickfix stack size
3073func XsizeTests(cchar)
3074 call s:setup_commands(a:cchar)
3075
3076 call g:Xsetlist([], 'f')
3077 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003078 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3079 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003080
3081 Xexpr "File1:10:Line1"
3082 Xexpr "File2:20:Line2"
3083 Xexpr "File3:30:Line3"
3084 Xolder | Xolder
3085 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3086 call g:Xsetlist([], 'f')
3087
3088 Xexpr "File1:10:Line1"
3089 Xexpr "File2:20:Line2"
3090 Xexpr "File3:30:Line3"
3091 Xolder | Xolder
3092 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3093 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3094endfunc
3095
3096func Test_Qf_Size()
3097 call XsizeTests('c')
3098 call XsizeTests('l')
3099endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003100
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003101func Test_cclose_from_copen()
3102 augroup QF_Test
3103 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003104 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003105 augroup END
3106 copen
3107 augroup QF_Test
3108 au!
3109 augroup END
3110 augroup! QF_Test
3111endfunc
3112
Bram Moolenaar18141832017-06-25 21:17:25 +02003113func Test_cclose_in_autocmd()
3114 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3115 " event will be triggered.
3116 call test_override('starting', 1)
3117 augroup QF_Test
3118 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003119 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003120 augroup END
3121 copen
3122 augroup QF_Test
3123 au!
3124 augroup END
3125 augroup! QF_Test
3126 call test_override('starting', 0)
3127endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003128
Bram Moolenaar379fb762018-08-30 15:58:28 +02003129" Check that ":file" without an argument is possible even when "curbuf_lock"
3130" is set.
3131func Test_file_from_copen()
3132 " Works without argument.
3133 augroup QF_Test
3134 au!
3135 au FileType qf file
3136 augroup END
3137 copen
3138
3139 augroup QF_Test
3140 au!
3141 augroup END
3142 cclose
3143
3144 " Fails with argument.
3145 augroup QF_Test
3146 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003147 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003148 augroup END
3149 copen
3150 augroup QF_Test
3151 au!
3152 augroup END
3153 cclose
3154
3155 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003156endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003157
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003158func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003159 augroup QF_Test
3160 au!
3161 au FileType qf resize 5
3162 augroup END
3163 try
3164 " This should succeed without any exception. No other buffers are
3165 " involved in the autocmd.
3166 copen
3167 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003168 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003169 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003170 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003171 augroup! QF_Test
3172 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003173endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003174
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003175func Test_vimgrep_with_textlock()
3176 new
3177
3178 " Simple way to execute something with "textwinlock" set.
3179 " Check that vimgrep without jumping can be executed.
3180 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3181 normal ax
3182 let qflist = getqflist()
3183 call assert_true(len(qflist) > 0)
3184 call assert_match('RunTheTest', qflist[0].text)
3185 call setqflist([], 'r')
3186 au! InsertCharPre
3187
3188 " Check that vimgrepadd without jumping can be executed.
3189 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3190 normal ax
3191 let qflist = getqflist()
3192 call assert_true(len(qflist) > 0)
3193 call assert_match('RunTheTest', qflist[0].text)
3194 call setqflist([], 'r')
3195 au! InsertCharPre
3196
3197 " Check that lvimgrep without jumping can be executed.
3198 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3199 normal ax
3200 let qflist = getloclist(0)
3201 call assert_true(len(qflist) > 0)
3202 call assert_match('RunTheTest', qflist[0].text)
3203 call setloclist(0, [], 'r')
3204 au! InsertCharPre
3205
3206 " Check that lvimgrepadd without jumping can be executed.
3207 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3208 normal ax
3209 let qflist = getloclist(0)
3210 call assert_true(len(qflist) > 0)
3211 call assert_match('RunTheTest', qflist[0].text)
3212 call setloclist(0, [], 'r')
3213 au! InsertCharPre
3214
3215 " trying to jump will give an error
3216 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3217 call assert_fails('normal ax', 'E565:')
3218 au! InsertCharPre
3219
3220 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3221 call assert_fails('normal ax', 'E565:')
3222 au! InsertCharPre
3223
3224 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3225 call assert_fails('normal ax', 'E565:')
3226 au! InsertCharPre
3227
3228 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3229 call assert_fails('normal ax', 'E565:')
3230 au! InsertCharPre
3231
3232 bwipe!
3233endfunc
3234
Bram Moolenaara8788f42017-07-19 17:06:20 +02003235" Tests for the quickfix buffer b:changedtick variable
3236func Xchangedtick_tests(cchar)
3237 call s:setup_commands(a:cchar)
3238
3239 new | only
3240
3241 Xexpr "" | Xexpr "" | Xexpr ""
3242
3243 Xopen
3244 Xolder
3245 Xolder
3246 Xaddexpr "F1:10:Line10"
3247 Xaddexpr "F2:20:Line20"
3248 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3249 call g:Xsetlist([], 'f')
3250 call assert_equal(8, getbufvar('%', 'changedtick'))
3251 Xclose
3252endfunc
3253
3254func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003255 call Xchangedtick_tests('c')
3256 call Xchangedtick_tests('l')
3257endfunc
3258
3259" Tests for parsing an expression using setqflist()
3260func Xsetexpr_tests(cchar)
3261 call s:setup_commands(a:cchar)
3262
3263 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003264 call g:Xsetlist([], ' ', {'lines' : t})
3265 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003266
3267 let l = g:Xgetlist()
3268 call assert_equal(3, len(l))
3269 call assert_equal(20, l[1].lnum)
3270 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003271 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003272 let l = g:Xgetlist()
3273 call assert_equal(1, len(l))
3274 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003275 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3276 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003277
3278 call g:Xsetlist([], 'f')
3279 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003280 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3281 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3282 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3283 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003284 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3285 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003286
3287 " Adding entries using a custom efm
3288 set efm&
3289 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3290 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3291 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3292 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3293 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3294 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3295 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3296 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003297endfunc
3298
3299func Test_setexpr()
3300 call Xsetexpr_tests('c')
3301 call Xsetexpr_tests('l')
3302endfunc
3303
3304" Tests for per quickfix/location list directory stack
3305func Xmultidirstack_tests(cchar)
3306 call s:setup_commands(a:cchar)
3307
3308 call g:Xsetlist([], 'f')
3309 Xexpr "" | Xexpr ""
3310
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003311 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3312 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3313 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3314 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003315
3316 let l1 = g:Xgetlist({'nr':1, 'items':1})
3317 let l2 = g:Xgetlist({'nr':2, 'items':1})
3318 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3319 call assert_equal(3, l1.items[1].lnum)
3320 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3321 call assert_equal(5, l2.items[1].lnum)
3322endfunc
3323
3324func Test_multidirstack()
3325 call mkdir('Xone/a', 'p')
3326 call mkdir('Xtwo/a', 'p')
3327 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3328 call writefile(lines, 'Xone/a/one.txt')
3329 call writefile(lines, 'Xtwo/a/two.txt')
3330 let save_efm = &efm
3331 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3332
3333 call Xmultidirstack_tests('c')
3334 call Xmultidirstack_tests('l')
3335
3336 let &efm = save_efm
3337 call delete('Xone', 'rf')
3338 call delete('Xtwo', 'rf')
3339endfunc
3340
3341" Tests for per quickfix/location list file stack
3342func Xmultifilestack_tests(cchar)
3343 call s:setup_commands(a:cchar)
3344
3345 call g:Xsetlist([], 'f')
3346 Xexpr "" | Xexpr ""
3347
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003348 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3349 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3350 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3351 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003352
3353 let l1 = g:Xgetlist({'nr':1, 'items':1})
3354 let l2 = g:Xgetlist({'nr':2, 'items':1})
3355 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3356 call assert_equal(3, l1.items[1].lnum)
3357 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3358 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003359
3360 " Test for start of a new error line in the same line where a previous
3361 " error line ends with a file stack.
3362 let efm_val = 'Error\ l%l\ in\ %f,'
3363 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3364 let l = g:Xgetlist({'lines' : [
3365 \ '(one.txt',
3366 \ 'Error l4 in one.txt',
3367 \ ') (two.txt',
3368 \ 'Error l6 in two.txt',
3369 \ ')',
3370 \ 'Error l8 in one.txt'
3371 \ ], 'efm' : efm_val})
3372 call assert_equal(3, len(l.items))
3373 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3374 call assert_equal(4, l.items[0].lnum)
3375 call assert_equal('one.txt', l.items[0].text)
3376 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3377 call assert_equal(6, l.items[1].lnum)
3378 call assert_equal('two.txt', l.items[1].text)
3379 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3380 call assert_equal(8, l.items[2].lnum)
3381 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003382endfunc
3383
3384func Test_multifilestack()
3385 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3386 call writefile(lines, 'one.txt')
3387 call writefile(lines, 'two.txt')
3388 let save_efm = &efm
3389 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3390
3391 call Xmultifilestack_tests('c')
3392 call Xmultifilestack_tests('l')
3393
3394 let &efm = save_efm
3395 call delete('one.txt')
3396 call delete('two.txt')
3397endfunc
3398
3399" Tests for per buffer 'efm' setting
3400func Test_perbuf_efm()
3401 call writefile(["File1-10-Line10"], 'one.txt')
3402 call writefile(["File2#20#Line20"], 'two.txt')
3403 set efm=%f#%l#%m
3404 new | only
3405 new
3406 setlocal efm=%f-%l-%m
3407 cfile one.txt
3408 wincmd w
3409 caddfile two.txt
3410
3411 let l = getqflist()
3412 call assert_equal(10, l[0].lnum)
3413 call assert_equal('Line20', l[1].text)
3414
3415 set efm&
3416 new | only
3417 call delete('one.txt')
3418 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003419endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003420
3421" Open multiple help windows using ":lhelpgrep
3422" This test used to crash Vim
3423func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003424 new | only
3425 lhelpgrep window
3426 lopen
3427 e#
3428 lhelpgrep buffer
3429 call assert_equal(3, winnr('$'))
3430 call assert_true(len(getloclist(1)) != 0)
3431 call assert_true(len(getloclist(2)) != 0)
3432 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003433endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003434
3435" Tests for adding new quickfix lists using setqflist()
3436func XaddQf_tests(cchar)
3437 call s:setup_commands(a:cchar)
3438
3439 " Create a new list using ' ' for action
3440 call g:Xsetlist([], 'f')
3441 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3442 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3443 call assert_equal(1, l.nr)
3444 call assert_equal('Test1', l.title)
3445
3446 " Create a new list using ' ' for action and '$' for 'nr'
3447 call g:Xsetlist([], 'f')
3448 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3449 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3450 call assert_equal(1, l.nr)
3451 call assert_equal('Test2', l.title)
3452
3453 " Create a new list using 'a' for action
3454 call g:Xsetlist([], 'f')
3455 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3456 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3457 call assert_equal(1, l.nr)
3458 call assert_equal('Test3', l.title)
3459
3460 " Create a new list using 'a' for action and '$' for 'nr'
3461 call g:Xsetlist([], 'f')
3462 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3463 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3464 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3465 call assert_equal(1, l.nr)
3466 call assert_equal('Test4', l.title)
3467
3468 " Adding a quickfix list should remove all the lists following the current
3469 " list.
3470 Xexpr "" | Xexpr "" | Xexpr ""
3471 silent! 10Xolder
3472 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3473 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3474 call assert_equal(2, l.nr)
3475 call assert_equal('Test5', l.title)
3476
3477 " Add a quickfix list using '$' as the list number.
3478 let lastqf = g:Xgetlist({'nr':'$'}).nr
3479 silent! 99Xolder
3480 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3481 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3482 call assert_equal(lastqf + 1, l.nr)
3483 call assert_equal('Test6', l.title)
3484
3485 " Add a quickfix list using 'nr' set to one more than the quickfix
3486 " list size.
3487 let lastqf = g:Xgetlist({'nr':'$'}).nr
3488 silent! 99Xolder
3489 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3490 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3491 call assert_equal(lastqf + 1, l.nr)
3492 call assert_equal('Test7', l.title)
3493
3494 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3495 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3496 silent! 99Xolder
3497 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3498 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3499 call assert_equal(10, l.nr)
3500 call assert_equal('Test8', l.title)
3501
3502 " Add a quickfix list using 'nr' set to a value greater than 10
3503 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3504
3505 " Try adding a quickfix list with 'nr' set to a value greater than the
3506 " quickfix list size but less than 10.
3507 call g:Xsetlist([], 'f')
3508 Xexpr "" | Xexpr "" | Xexpr ""
3509 silent! 99Xolder
3510 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3511
3512 " Add a quickfix list using 'nr' set to a some string or list
3513 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3514endfunc
3515
3516func Test_add_qf()
3517 call XaddQf_tests('c')
3518 call XaddQf_tests('l')
3519endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003520
3521" Test for getting the quickfix list items from some text without modifying
3522" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003523func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003524 call s:setup_commands(a:cchar)
3525 call g:Xsetlist([], 'f')
3526
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003527 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003528 call assert_equal(2, len(l))
3529 call assert_equal(30, l[1].lnum)
3530
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003531 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3532 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3533 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3534 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003535
Bram Moolenaar36538222017-09-02 19:51:44 +02003536 " Parse text using a custom efm
3537 set efm&
3538 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3539 call assert_equal('Line30', l[0].text)
3540 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3541 call assert_equal('File3:30:Line30', l[0].text)
3542 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3543 call assert_equal({}, l)
3544 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3545 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3546
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003547 " Make sure that the quickfix stack is not modified
3548 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3549endfunc
3550
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003551func Test_get_list_from_lines()
3552 call XgetListFromLines('c')
3553 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003554endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003555
3556" Tests for the quickfix list id
3557func Xqfid_tests(cchar)
3558 call s:setup_commands(a:cchar)
3559
3560 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003561 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003562 Xexpr ''
3563 let start_id = g:Xgetlist({'id' : 0}).id
3564 Xexpr '' | Xexpr ''
3565 Xolder
3566 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3567 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3568 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003569 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003570 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003571 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3572 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003573
3574 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3575 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003576 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003577 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3578 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3579 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3580
3581 let qfid = g:Xgetlist({'id':0, 'nr':0})
3582 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003583 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003584endfunc
3585
3586func Test_qf_id()
3587 call Xqfid_tests('c')
3588 call Xqfid_tests('l')
3589endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003590
3591func Xqfjump_tests(cchar)
3592 call s:setup_commands(a:cchar)
3593
3594 call writefile(["Line1\tFoo", "Line2"], 'F1')
3595 call writefile(["Line1\tBar", "Line2"], 'F2')
3596 call writefile(["Line1\tBaz", "Line2"], 'F3')
3597
3598 call g:Xsetlist([], 'f')
3599
3600 " Tests for
3601 " Jumping to a line using a pattern
3602 " Jumping to a column greater than the last column in a line
3603 " Jumping to a line greater than the last line in the file
3604 let l = []
3605 for i in range(1, 7)
3606 call add(l, {})
3607 endfor
3608 let l[0].filename='F1'
3609 let l[0].pattern='Line1'
3610 let l[1].filename='F2'
3611 let l[1].pattern='Line1'
3612 let l[2].filename='F3'
3613 let l[2].pattern='Line1'
3614 let l[3].filename='F3'
3615 let l[3].lnum=1
3616 let l[3].col=9
3617 let l[3].vcol=1
3618 let l[4].filename='F3'
3619 let l[4].lnum=99
3620 let l[5].filename='F3'
3621 let l[5].lnum=1
3622 let l[5].col=99
3623 let l[5].vcol=1
3624 let l[6].filename='F3'
3625 let l[6].pattern='abcxyz'
3626
3627 call g:Xsetlist([], ' ', {'items' : l})
3628 Xopen | only
3629 2Xnext
3630 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003631 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003632 Xnext
3633 call assert_equal(7, col('.'))
3634 Xnext
3635 call assert_equal(2, line('.'))
3636 Xnext
3637 call assert_equal(9, col('.'))
3638 2
3639 Xnext
3640 call assert_equal(2, line('.'))
3641
3642 if a:cchar == 'l'
3643 " When jumping to a location list entry in the location list window and
3644 " no usable windows are available, then a new window should be opened.
3645 enew! | new | only
3646 call g:Xsetlist([], 'f')
3647 setlocal buftype=nofile
3648 new
3649 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']})
3650 Xopen
3651 let winid = win_getid()
3652 wincmd p
3653 close
3654 call win_gotoid(winid)
3655 Xnext
3656 call assert_equal(3, winnr('$'))
3657 call assert_equal(1, winnr())
3658 call assert_equal(2, line('.'))
3659
3660 " When jumping to an entry in the location list window and the window
3661 " associated with the location list is not present and a window containing
3662 " the file is already present, then that window should be used.
3663 close
3664 belowright new
3665 call g:Xsetlist([], 'f')
3666 edit F3
3667 call win_gotoid(winid)
3668 Xlast
3669 call assert_equal(3, winnr())
3670 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3671 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3672 endif
3673
3674 " Cleanup
3675 enew!
3676 new | only
3677
3678 call delete('F1')
3679 call delete('F2')
3680 call delete('F3')
3681endfunc
3682
3683func Test_qfjump()
3684 call Xqfjump_tests('c')
3685 call Xqfjump_tests('l')
3686endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003687
3688" Tests for the getqflist() and getloclist() functions when the list is not
3689" present or is empty
3690func Xgetlist_empty_tests(cchar)
3691 call s:setup_commands(a:cchar)
3692
3693 " Empty quickfix stack
3694 call g:Xsetlist([], 'f')
3695 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3696 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3697 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3698 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3699 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3700 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3701 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3702 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003703 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003704 if a:cchar == 'c'
3705 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003706 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003707 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3708 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003709 else
3710 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3711 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003712 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003713 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003714 \ g:Xgetlist({'all' : 0}))
3715 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003716
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003717 " Quickfix window with empty stack
3718 silent! Xopen
3719 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003720 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003721 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3722 Xclose
3723
Bram Moolenaara6d48492017-12-12 22:45:31 +01003724 " Empty quickfix list
3725 Xexpr ""
3726 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3727 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3728 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3729 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3730 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3731 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3732 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3733 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003734 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003735
3736 let qfid = g:Xgetlist({'id' : 0}).id
3737 call g:Xsetlist([], 'f')
3738
3739 " Non-existing quickfix identifier
3740 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3741 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3742 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3743 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3744 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3745 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3746 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3747 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003748 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003749 if a:cchar == 'c'
3750 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3751 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003752 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003753 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3754 else
3755 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3756 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003757 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3758 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003759 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3760 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003761
3762 " Non-existing quickfix list number
3763 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3764 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3765 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3766 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3767 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3768 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3769 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3770 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003771 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003772 if a:cchar == 'c'
3773 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3774 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003775 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3776 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003777 else
3778 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3779 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003780 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3781 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003782 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003783endfunc
3784
3785func Test_getqflist()
3786 call Xgetlist_empty_tests('c')
3787 call Xgetlist_empty_tests('l')
3788endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003789
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003790func Test_getqflist_invalid_nr()
3791 " The following commands used to crash Vim
3792 cexpr ""
3793 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3794
3795 " Cleanup
3796 call setqflist([], 'r')
3797endfunc
3798
Bram Moolenaarb254af32017-12-18 19:48:58 +01003799" Tests for the quickfix/location list changedtick
3800func Xqftick_tests(cchar)
3801 call s:setup_commands(a:cchar)
3802
3803 call g:Xsetlist([], 'f')
3804
3805 Xexpr "F1:10:Line10"
3806 let qfid = g:Xgetlist({'id' : 0}).id
3807 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3808 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3809 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3810 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3811 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3812 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3813 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3814 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3815 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3816
3817 enew!
3818 call append(0, ["F5:50:L50", "F6:60:L60"])
3819 Xaddbuffer
3820 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3821 enew!
3822
3823 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3824 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3825 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3826 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3827 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3828 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3829 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3830 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3831 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3832 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3833 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3834
3835 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3836 Xfile Xone
3837 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3838 Xaddfile Xone
3839 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3840
3841 " Test case for updating a non-current quickfix list
3842 call g:Xsetlist([], 'f')
3843 Xexpr "F1:1:L1"
3844 Xexpr "F2:2:L2"
3845 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3846 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3847 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3848
3849 call delete("Xone")
3850endfunc
3851
3852func Test_qf_tick()
3853 call Xqftick_tests('c')
3854 call Xqftick_tests('l')
3855endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003856
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003857" Test helpgrep with lang specifier
3858func Xtest_helpgrep_with_lang_specifier(cchar)
3859 call s:setup_commands(a:cchar)
3860 Xhelpgrep Vim@en
3861 call assert_equal('help', &filetype)
3862 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3863 new | only
3864endfunc
3865
3866func Test_helpgrep_with_lang_specifier()
3867 call Xtest_helpgrep_with_lang_specifier('c')
3868 call Xtest_helpgrep_with_lang_specifier('l')
3869endfunc
3870
Bram Moolenaar12237442017-12-19 12:38:52 +01003871" The following test used to crash Vim.
3872" Open the location list window and close the regular window associated with
3873" the location list. When the garbage collection runs now, it incorrectly
3874" marks the location list context as not in use and frees the context.
3875func Test_ll_window_ctx()
3876 call setloclist(0, [], 'f')
3877 call setloclist(0, [], 'a', {'context' : []})
3878 lopen | only
3879 call test_garbagecollect_now()
3880 echo getloclist(0, {'context' : 1}).context
3881 enew | only
3882endfunc
3883
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003884" The following test used to crash vim
3885func Test_lfile_crash()
3886 sp Xtest
3887 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003888 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003889 au! QuickFixCmdPre
3890endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003891
3892" The following test used to crash vim
3893func Test_lbuffer_crash()
3894 sv Xtest
3895 augroup QF_Test
3896 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003897 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003898 augroup END
3899 lbuffer
3900 augroup QF_Test
3901 au!
3902 augroup END
3903endfunc
3904
3905" The following test used to crash vim
3906func Test_lexpr_crash()
3907 augroup QF_Test
3908 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003909 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003910 augroup END
3911 lexpr ""
3912 augroup QF_Test
3913 au!
3914 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003915
Bram Moolenaar3c097222017-12-21 20:54:49 +01003916 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003917 augroup QF_Test
3918 au!
3919 au BufNew * call setloclist(0, [], 'f')
3920 augroup END
3921 lexpr 'x:1:x'
3922 augroup QF_Test
3923 au!
3924 augroup END
3925
3926 enew | only
3927 lexpr ''
3928 lopen
3929 augroup QF_Test
3930 au!
3931 au FileType * call setloclist(0, [], 'f')
3932 augroup END
3933 lexpr ''
3934 augroup QF_Test
3935 au!
3936 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003937endfunc
3938
3939" The following test used to crash Vim
3940func Test_lvimgrep_crash()
3941 sv Xtest
3942 augroup QF_Test
3943 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003944 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003945 augroup END
3946 lvimgrep quickfix test_quickfix.vim
3947 augroup QF_Test
3948 au!
3949 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003950
3951 new | only
3952 augroup QF_Test
3953 au!
3954 au BufEnter * call setloclist(0, [], 'r')
3955 augroup END
3956 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3957 augroup QF_Test
3958 au!
3959 augroup END
3960
Bram Moolenaar3c097222017-12-21 20:54:49 +01003961 enew | only
3962endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003963
Bram Moolenaar2573af32020-03-14 17:21:34 +01003964func Test_lvimgrep_crash2()
3965 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003966 call assert_fails('lvimgrep x x', 'E471:')
3967 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003968
3969 au! BufNewFile
3970endfunc
3971
Bram Moolenaarde046542017-12-26 13:53:11 +01003972" Test for the position of the quickfix and location list window
3973func Test_qfwin_pos()
3974 " Open two windows
3975 new | only
3976 new
3977 cexpr ['F1:10:L10']
3978 copen
3979 " Quickfix window should be the bottom most window
3980 call assert_equal(3, winnr())
3981 close
3982 " Open at the very top
3983 wincmd t
3984 topleft copen
3985 call assert_equal(1, winnr())
3986 close
3987 " open left of the current window
3988 wincmd t
3989 below new
3990 leftabove copen
3991 call assert_equal(2, winnr())
3992 close
3993 " open right of the current window
3994 rightbelow copen
3995 call assert_equal(3, winnr())
3996 close
3997endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003998
3999" Tests for quickfix/location lists changed by autocommands when
4000" :vimgrep/:lvimgrep commands are running.
4001func Test_vimgrep_autocmd()
4002 call setqflist([], 'f')
4003 call writefile(['stars'], 'Xtest1.txt')
4004 call writefile(['stars'], 'Xtest2.txt')
4005
4006 " Test 1:
4007 " When searching for a pattern using :vimgrep, if the quickfix list is
4008 " changed by an autocmd, the results should be added to the correct quickfix
4009 " list.
4010 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4011 silent vimgrep stars Xtest*.txt
4012 call assert_equal(1, getqflist({'nr' : 0}).nr)
4013 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4014 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4015 au! BufRead Xtest2.txt
4016
4017 " Test 2:
4018 " When searching for a pattern using :vimgrep, if the quickfix list is
4019 " freed, then a error should be given.
4020 silent! %bwipe!
4021 call setqflist([], 'f')
4022 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4023 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4024 au! BufRead Xtest2.txt
4025
4026 " Test 3:
4027 " When searching for a pattern using :lvimgrep, if the location list is
4028 " freed, then the command should error out.
4029 silent! %bwipe!
4030 let g:save_winid = win_getid()
4031 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4032 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4033 au! BufRead Xtest2.txt
4034
4035 call delete('Xtest1.txt')
4036 call delete('Xtest2.txt')
4037 call setqflist([], 'f')
4038endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004039
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004040" Test for an autocmd changing the current directory when running vimgrep
4041func Xvimgrep_autocmd_cd(cchar)
4042 call s:setup_commands(a:cchar)
4043
4044 %bwipe
4045 let save_cwd = getcwd()
4046
4047 augroup QF_Test
4048 au!
4049 autocmd BufRead * silent cd %:p:h
4050 augroup END
4051
4052 10Xvimgrep /vim/ Xdir/**
4053 let l = g:Xgetlist()
4054 call assert_equal('f1.txt', bufname(l[0].bufnr))
4055 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4056
4057 augroup QF_Test
4058 au!
4059 augroup END
4060
4061 exe 'cd ' . save_cwd
4062endfunc
4063
4064func Test_vimgrep_autocmd_cd()
4065 call mkdir('Xdir/a', 'p')
4066 call mkdir('Xdir/b', 'p')
4067 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4068 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4069 call Xvimgrep_autocmd_cd('c')
4070 call Xvimgrep_autocmd_cd('l')
4071 %bwipe
4072 call delete('Xdir', 'rf')
4073endfunc
4074
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004075" The following test used to crash Vim
4076func Test_lhelpgrep_autocmd()
4077 lhelpgrep quickfix
4078 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4079 lhelpgrep buffer
4080 call assert_equal('help', &filetype)
4081 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4082 lhelpgrep tabpage
4083 call assert_equal('help', &filetype)
4084 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4085 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004086
4087 new | only
4088 augroup QF_Test
4089 au!
4090 au BufEnter * call setqflist([], 'f')
4091 augroup END
4092 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004093 " run the test with a help window already open
4094 help
4095 wincmd w
4096 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004097 augroup QF_Test
4098 au! BufEnter
4099 augroup END
4100
4101 new | only
4102 augroup QF_Test
4103 au!
4104 au BufEnter * call setqflist([], 'r')
4105 augroup END
4106 call assert_fails('helpgrep quickfix', 'E925:')
4107 augroup QF_Test
4108 au! BufEnter
4109 augroup END
4110
4111 new | only
4112 augroup QF_Test
4113 au!
4114 au BufEnter * call setloclist(0, [], 'r')
4115 augroup END
4116 call assert_fails('lhelpgrep quickfix', 'E926:')
4117 augroup QF_Test
4118 au! BufEnter
4119 augroup END
4120
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004121 new | only
4122endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004123
4124" Test for shortening/simplifying the file name when opening the
4125" quickfix window or when displaying the quickfix list
4126func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004127 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004128 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004129 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004130 let fname = getcwd() . '/test_quickfix.vim'
4131 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4132 call assert_equal(fname, bufname('test_quickfix.vim'))
4133 " Opening the quickfix window should simplify the file path
4134 cwindow
4135 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4136 cclose
4137 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004138 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004139 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4140 call assert_equal(fname, bufname('test_quickfix.vim'))
4141 " Displaying the quickfix list should simplify the file path
4142 silent! clist
4143 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004144 " Add a few entries for the same file with different paths and check whether
4145 " the buffer name is shortened
4146 %bwipe
4147 call setqflist([], 'f')
4148 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4149 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4150 \ {'filename' : fname, 'lnum' : 30}], ' ')
4151 copen
4152 call assert_equal(['test_quickfix.vim|10| ',
4153 \ 'test_quickfix.vim|20| ',
4154 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4155 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004156endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004157
4158" Quickfix title tests
4159" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4160" Otherwise due to indentation, the title is set with spaces at the beginning
4161" of the command.
4162func Test_qftitle()
4163 call writefile(["F1:1:Line1"], 'Xerr')
4164
4165 " :cexpr
4166 exe "cexpr readfile('Xerr')"
4167 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4168
4169 " :cgetexpr
4170 exe "cgetexpr readfile('Xerr')"
4171 call assert_equal(":cgetexpr readfile('Xerr')",
4172 \ getqflist({'title' : 1}).title)
4173
4174 " :caddexpr
4175 call setqflist([], 'f')
4176 exe "caddexpr readfile('Xerr')"
4177 call assert_equal(":caddexpr readfile('Xerr')",
4178 \ getqflist({'title' : 1}).title)
4179
4180 " :cbuffer
4181 new Xerr
4182 exe "cbuffer"
4183 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4184
4185 " :cgetbuffer
4186 edit Xerr
4187 exe "cgetbuffer"
4188 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4189
4190 " :caddbuffer
4191 call setqflist([], 'f')
4192 edit Xerr
4193 exe "caddbuffer"
4194 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4195
4196 " :cfile
4197 exe "cfile Xerr"
4198 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4199
4200 " :cgetfile
4201 exe "cgetfile Xerr"
4202 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4203
4204 " :caddfile
4205 call setqflist([], 'f')
4206 exe "caddfile Xerr"
4207 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4208
4209 " :grep
4210 set grepprg=internal
4211 exe "grep F1 Xerr"
4212 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4213
4214 " :grepadd
4215 call setqflist([], 'f')
4216 exe "grepadd F1 Xerr"
4217 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4218 set grepprg&vim
4219
4220 " :vimgrep
4221 exe "vimgrep F1 Xerr"
4222 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4223
4224 " :vimgrepadd
4225 call setqflist([], 'f')
4226 exe "vimgrepadd F1 Xerr"
4227 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4228
4229 call setqflist(['F1:10:L10'], ' ')
4230 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4231
4232 call setqflist([], 'f')
4233 call setqflist(['F1:10:L10'], 'a')
4234 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4235
4236 call setqflist([], 'f')
4237 call setqflist(['F1:10:L10'], 'r')
4238 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4239
4240 close
4241 call delete('Xerr')
4242
4243 call setqflist([], ' ', {'title' : 'Errors'})
4244 copen
4245 call assert_equal('Errors', w:quickfix_title)
4246 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4247 call assert_equal('Errors', w:quickfix_title)
4248 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004249
4250 " Switching to another quickfix list in one tab page should update the
4251 " quickfix window title and statusline in all the other tab pages also
4252 call setqflist([], 'f')
4253 %bw!
4254 cgetexpr ['file_one:1:1: error in the first quickfix list']
4255 call setqflist([], 'a', {'title': 'first quickfix list'})
4256 cgetexpr ['file_two:2:1: error in the second quickfix list']
4257 call setqflist([], 'a', {'title': 'second quickfix list'})
4258 copen
4259 wincmd t
4260 tabnew two
4261 copen
4262 wincmd t
4263 colder
4264 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4265 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4266 call assert_equal(1, tabpagewinnr(1))
4267 call assert_equal(1, tabpagewinnr(2))
4268 tabnew
4269 call setqflist([], 'a', {'title': 'new quickfix title'})
4270 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4271 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4272 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004273endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004274
4275func Test_lbuffer_with_bwipe()
4276 new
4277 new
4278 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004279 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004280 augroup END
4281 lbuffer
4282 augroup nasty
4283 au!
4284 augroup END
4285endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004286
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004287" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4288" running
4289func Xexpr_acmd_freelist(cchar)
4290 call s:setup_commands(a:cchar)
4291
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004292 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004293 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004294 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004295 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004296 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004297 augroup nasty
4298 au!
4299 augroup END
4300endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004301
4302func Test_cexpr_acmd_freelist()
4303 call Xexpr_acmd_freelist('c')
4304 call Xexpr_acmd_freelist('l')
4305endfunc
4306
4307" Test for commands that create a new quickfix/location list and jump to the
4308" first error automatically.
4309func Xjumpto_first_error_test(cchar)
4310 call s:setup_commands(a:cchar)
4311
4312 call s:create_test_file('Xtestfile1')
4313 call s:create_test_file('Xtestfile2')
4314 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4315
4316 " Test for cexpr/lexpr
4317 enew
4318 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004319 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004320 call assert_equal(2, line('.'))
4321
4322 " Test for cfile/lfile
4323 enew
4324 call writefile(l, 'Xerr')
4325 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004326 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004327 call assert_equal(2, line('.'))
4328
4329 " Test for cbuffer/lbuffer
4330 edit Xerr
4331 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004332 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004333 call assert_equal(2, line('.'))
4334
4335 call delete('Xerr')
4336 call delete('Xtestfile1')
4337 call delete('Xtestfile2')
4338endfunc
4339
4340func Test_jumpto_first_error()
4341 call Xjumpto_first_error_test('c')
4342 call Xjumpto_first_error_test('l')
4343endfunc
4344
4345" Test for a quickfix autocmd changing the quickfix/location list before
4346" jumping to the first error in the new list.
4347func Xautocmd_changelist(cchar)
4348 call s:setup_commands(a:cchar)
4349
4350 " Test for cfile/lfile
4351 call s:create_test_file('Xtestfile1')
4352 call s:create_test_file('Xtestfile2')
4353 Xexpr 'Xtestfile1:2:Line2'
4354 autocmd QuickFixCmdPost * Xolder
4355 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4356 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004357 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004358 call assert_equal(4, line('.'))
4359 autocmd! QuickFixCmdPost
4360
4361 " Test for cbuffer/lbuffer
4362 call g:Xsetlist([], 'f')
4363 Xexpr 'Xtestfile1:2:Line2'
4364 autocmd QuickFixCmdPost * Xolder
4365 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4366 edit Xerr
4367 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004368 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004369 call assert_equal(4, line('.'))
4370 autocmd! QuickFixCmdPost
4371
4372 " Test for cexpr/lexpr
4373 call g:Xsetlist([], 'f')
4374 Xexpr 'Xtestfile1:2:Line2'
4375 autocmd QuickFixCmdPost * Xolder
4376 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004377 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004378 call assert_equal(4, line('.'))
4379 autocmd! QuickFixCmdPost
4380
Bram Moolenaar851332e2018-07-03 19:16:00 +02004381 " The grepprg may not be set on non-Unix systems
4382 if has('unix')
4383 " Test for grep/lgrep
4384 call g:Xsetlist([], 'f')
4385 Xexpr 'Xtestfile1:2:Line2'
4386 autocmd QuickFixCmdPost * Xolder
4387 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004388 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004389 call assert_equal(5, line('.'))
4390 autocmd! QuickFixCmdPost
4391 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004392
4393 " Test for vimgrep/lvimgrep
4394 call g:Xsetlist([], 'f')
4395 Xexpr 'Xtestfile1:2:Line2'
4396 autocmd QuickFixCmdPost * Xolder
4397 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004398 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004399 call assert_equal(5, line('.'))
4400 autocmd! QuickFixCmdPost
4401
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004402 " Test for autocommands clearing the quickfix list before jumping to the
4403 " first error. This should not result in an error
4404 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4405 let v:errmsg = ''
4406 " Test for cfile/lfile
4407 Xfile Xerr
4408 call assert_true(v:errmsg !~# 'E42:')
4409 " Test for cbuffer/lbuffer
4410 edit Xerr
4411 Xbuffer
4412 call assert_true(v:errmsg !~# 'E42:')
4413 " Test for cexpr/lexpr
4414 Xexpr 'Xtestfile2:4:Line4'
4415 call assert_true(v:errmsg !~# 'E42:')
4416 " Test for grep/lgrep
4417 " The grepprg may not be set on non-Unix systems
4418 if has('unix')
4419 silent Xgrep Line5 Xtestfile2
4420 call assert_true(v:errmsg !~# 'E42:')
4421 endif
4422 " Test for vimgrep/lvimgrep
4423 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4424 autocmd! QuickFixCmdPost
4425
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004426 call delete('Xerr')
4427 call delete('Xtestfile1')
4428 call delete('Xtestfile2')
4429endfunc
4430
4431func Test_autocmd_changelist()
4432 call Xautocmd_changelist('c')
4433 call Xautocmd_changelist('l')
4434endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004435
4436" Tests for the ':filter /pat/ clist' command
4437func Test_filter_clist()
4438 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4439 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4440 \ split(execute('filter /Line 15/ clist'), "\n"))
4441 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4442 \ split(execute('filter /Xfile1/ clist'), "\n"))
4443 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4444
4445 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4446 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4447 call assert_equal([' 2 pqr:pat2: '],
4448 \ split(execute('filter /pqr/ clist'), "\n"))
4449 call assert_equal([' 1 abc:pat1: '],
4450 \ split(execute('filter /pat1/ clist'), "\n"))
4451endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004452
4453" Tests for the "CTRL-W <CR>" command.
4454func Xview_result_split_tests(cchar)
4455 call s:setup_commands(a:cchar)
4456
4457 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4458 call g:Xsetlist([])
4459 Xopen
4460 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004461 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004462 call assert_equal(l:win_count, winnr('$'))
4463 Xclose
4464endfunc
4465
4466func Test_view_result_split()
4467 call Xview_result_split_tests('c')
4468 call Xview_result_split_tests('l')
4469endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004470
4471" Test that :cc sets curswant
4472func Test_curswant()
4473 helpgrep quickfix
4474 normal! llll
4475 1cc
4476 call assert_equal(getcurpos()[4], virtcol('.'))
4477 cclose | helpclose
4478endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004479
4480" Test for opening a file from the quickfix window using CTRL-W <Enter>
4481" doesn't leave an empty buffer around.
4482func Test_splitview()
4483 call s:create_test_file('Xtestfile1')
4484 call s:create_test_file('Xtestfile2')
4485 new | only
4486 let last_bufnr = bufnr('Test_sv_1', 1)
4487 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4488 cgetexpr l
4489 copen
4490 let numbufs = len(getbufinfo())
4491 exe "normal \<C-W>\<CR>"
4492 copen
4493 exe "normal j\<C-W>\<CR>"
4494 " Make sure new empty buffers are not created
4495 call assert_equal(numbufs, len(getbufinfo()))
4496 " Creating a new buffer should use the next available buffer number
4497 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4498 bwipe Test_sv_1
4499 bwipe Test_sv_2
4500 new | only
4501
4502 " When split opening files from location list window, make sure that two
4503 " windows doesn't refer to the same location list
4504 lgetexpr l
4505 let locid = getloclist(0, {'id' : 0}).id
4506 lopen
4507 exe "normal \<C-W>\<CR>"
4508 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4509 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4510 new | only
4511
4512 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004513 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004514 lhelpgrep window
4515 let locid = getloclist(0, {'id' : 0}).id
4516 lwindow
4517 exe "normal j\<C-W>\<CR>"
4518 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4519 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4520 new | only
4521
Bram Moolenaar406cd902020-02-18 21:54:41 +01004522 " Using :split or :vsplit from a quickfix window should behave like a :new
4523 " or a :vnew command
4524 copen
4525 split
4526 call assert_equal(3, winnr('$'))
4527 let l = getwininfo()
4528 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4529 close
4530 copen
4531 vsplit
4532 let l = getwininfo()
4533 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4534 new | only
4535
Bram Moolenaarb2443732018-11-11 22:50:27 +01004536 call delete('Xtestfile1')
4537 call delete('Xtestfile2')
4538endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004539
4540" Test for parsing entries using visual screen column
4541func Test_viscol()
4542 enew
4543 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4544 edit Xfile1
4545
4546 " Use byte offset for column number
4547 set efm&
4548 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4549 call assert_equal([5, 8], [col('.'), virtcol('.')])
4550 cnext
4551 call assert_equal([9, 12], [col('.'), virtcol('.')])
4552 cnext
4553 call assert_equal([14, 20], [col('.'), virtcol('.')])
4554
4555 " Use screen column offset for column number
4556 set efm=%f:%l:%v:%m
4557 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4558 call assert_equal([5, 8], [col('.'), virtcol('.')])
4559 cnext
4560 call assert_equal([9, 12], [col('.'), virtcol('.')])
4561 cnext
4562 call assert_equal([14, 20], [col('.'), virtcol('.')])
4563 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4564 call assert_equal([5, 8], [col('.'), virtcol('.')])
4565 cnext
4566 call assert_equal([10, 16], [col('.'), virtcol('.')])
4567 cnext
4568 call assert_equal([14, 20], [col('.'), virtcol('.')])
4569
4570 enew
4571 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4572
4573 " Use byte offset for column number
4574 set efm&
4575 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4576 call assert_equal([8, 10], [col('.'), virtcol('.')])
4577 cnext
4578 call assert_equal([11, 17], [col('.'), virtcol('.')])
4579 cnext
4580 call assert_equal([16, 25], [col('.'), virtcol('.')])
4581
4582 " Use screen column offset for column number
4583 set efm=%f:%l:%v:%m
4584 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4585 call assert_equal([8, 10], [col('.'), virtcol('.')])
4586 cnext
4587 call assert_equal([11, 17], [col('.'), virtcol('.')])
4588 cnext
4589 call assert_equal([16, 25], [col('.'), virtcol('.')])
4590
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004591 " Use screen column number with a multi-line error message
4592 enew
4593 call writefile(["à test"], 'Xfile1')
4594 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4595 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4596 call assert_equal('Xfile1', @%)
4597 call assert_equal([0, 1, 4, 0], getpos('.'))
4598
4599 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4600 " does not break this
4601 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4602 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4603 call assert_equal('Xfile1', @%)
4604 call assert_equal([0, 1, 3, 0], getpos('.'))
4605
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004606 enew | only
4607 set efm&
4608 call delete('Xfile1')
4609endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004610
4611" Test for the quickfix window buffer
4612func Xqfbuf_test(cchar)
4613 call s:setup_commands(a:cchar)
4614
4615 " Quickfix buffer should be reused across closing and opening a quickfix
4616 " window
4617 Xexpr "F1:10:Line10"
4618 Xopen
4619 let qfbnum = bufnr('')
4620 Xclose
4621 " Even after the quickfix window is closed, the buffer should be loaded
4622 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004623 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004624 Xopen
4625 " Buffer should be reused when opening the window again
4626 call assert_equal(qfbnum, bufnr(''))
4627 Xclose
4628
4629 if a:cchar == 'l'
4630 %bwipe
4631 " For a location list, when both the file window and the location list
4632 " window for the list are closed, then the buffer should be freed.
4633 new | only
4634 lexpr "F1:10:Line10"
4635 let wid = win_getid()
4636 lopen
4637 let qfbnum = bufnr('')
4638 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4639 close
4640 " When the location list window is closed, the buffer name should not
4641 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004642 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004643 call assert_true(bufloaded(qfbnum))
4644
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004645 " After deleting a location list buffer using ":bdelete", opening the
4646 " location list window should mark the buffer as a location list buffer.
4647 exe "bdelete " . qfbnum
4648 lopen
4649 call assert_equal("quickfix", &buftype)
4650 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4651 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4652 call assert_false(&swapfile)
4653 lclose
4654
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004655 " When the location list is cleared for the window, the buffer should be
4656 " removed
4657 call setloclist(0, [], 'f')
4658 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004659 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004660
4661 " When the location list is freed with the location list window open, the
4662 " location list buffer should not be lost. It should be reused when the
4663 " location list is again populated.
4664 lexpr "F1:10:Line10"
4665 lopen
4666 let wid = win_getid()
4667 let qfbnum = bufnr('')
4668 wincmd p
4669 call setloclist(0, [], 'f')
4670 lexpr "F1:10:Line10"
4671 lopen
4672 call assert_equal(wid, win_getid())
4673 call assert_equal(qfbnum, bufnr(''))
4674 lclose
4675
4676 " When the window with the location list is closed, the buffer should be
4677 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004678 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004679 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004680 endif
4681endfunc
4682
4683func Test_qfbuf()
4684 call Xqfbuf_test('c')
4685 call Xqfbuf_test('l')
4686endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004687
4688" If there is an autocmd to use only one window, then opening the location
4689" list window used to crash Vim.
4690func Test_winonly_autocmd()
4691 call s:create_test_file('Xtest1')
4692 " Autocmd to show only one Vim window at a time
4693 autocmd WinEnter * only
4694 new
4695 " Load the location list
4696 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4697 let loclistid = getloclist(0, {'id' : 0}).id
4698 " Open the location list window. Only this window will be shown and the file
4699 " window is closed.
4700 lopen
4701 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4702 " Jump to an entry in the location list and make sure that the cursor is
4703 " positioned correctly.
4704 ll 3
4705 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004706 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004707 call assert_equal(15, line('.'))
4708 " Cleanup
4709 autocmd! WinEnter
4710 new | only
4711 call delete('Xtest1')
4712endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004713
4714" Test to make sure that an empty quickfix buffer is not reused for loading
4715" a normal buffer.
4716func Test_empty_qfbuf()
4717 enew | only
4718 call writefile(["Test"], 'Xfile1')
4719 call setqflist([], 'f')
4720 copen | only
4721 let qfbuf = bufnr('')
4722 edit Xfile1
4723 call assert_notequal(qfbuf, bufnr(''))
4724 enew
4725 call delete('Xfile1')
4726endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004727
4728" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004729" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004730func Xtest_below(cchar)
4731 call s:setup_commands(a:cchar)
4732
4733 " No quickfix/location list
4734 call assert_fails('Xbelow', 'E42:')
4735 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004736 call assert_fails('Xbefore', 'E42:')
4737 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004738
4739 " Empty quickfix/location list
4740 call g:Xsetlist([])
4741 call assert_fails('Xbelow', 'E42:')
4742 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004743 call assert_fails('Xbefore', 'E42:')
4744 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004745
4746 call s:create_test_file('X1')
4747 call s:create_test_file('X2')
4748 call s:create_test_file('X3')
4749 call s:create_test_file('X4')
4750
4751 " Invalid entries
4752 edit X1
4753 call g:Xsetlist(["E1", "E2"])
4754 call assert_fails('Xbelow', 'E42:')
4755 call assert_fails('Xabove', 'E42:')
4756 call assert_fails('3Xbelow', 'E42:')
4757 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004758 call assert_fails('Xbefore', 'E42:')
4759 call assert_fails('Xafter', 'E42:')
4760 call assert_fails('3Xbefore', 'E42:')
4761 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004762
4763 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004764 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 +02004765 edit +7 X2
4766 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004767 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004768 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004769 normal 7G
4770 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004771 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004772 call assert_fails('Xbefore', 'E553:')
4773
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004774 normal 2j
4775 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004776 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004777 normal 7G
4778 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004779 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004780
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004781 " Last error in this file
4782 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004783 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004784 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004785 normal gg
4786 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004787 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004788 call assert_fails('Xafter', 'E553:')
4789
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004790 " First error in this file
4791 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004792 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004793 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004794 normal G
4795 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004796 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004797 call assert_fails('Xbefore', 'E553:')
4798
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004799 normal gg
4800 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004801 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004802 normal gg
4803 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004804 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004805
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004806 normal G
4807 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004808 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004809 normal G
4810 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004811 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004812
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004813 edit X4
4814 call assert_fails('Xabove', 'E42:')
4815 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004816 call assert_fails('Xbefore', 'E42:')
4817 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004818 if a:cchar == 'l'
4819 " If a buffer has location list entries from some other window but not
4820 " from the current window, then the commands should fail.
4821 edit X1 | split | call setloclist(0, [], 'f')
4822 call assert_fails('Xabove', 'E776:')
4823 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004824 call assert_fails('Xbefore', 'E776:')
4825 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004826 close
4827 endif
4828
4829 " Test for lines with multiple quickfix entries
4830 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4831 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4832 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4833 edit +1 X2
4834 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004835 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004836 normal 1G
4837 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004838 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004839
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004840 normal gg
4841 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004842 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004843 normal gg
4844 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004845 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004846
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004847 normal G
4848 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004849 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004850 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004851 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004852 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004853
4854 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004855 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004856 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004857 normal G
4858 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004859 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004860
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004861 normal 10G
4862 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004863 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004864 normal 10G$
4865 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004866 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004867
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004868 normal 10G
4869 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004870 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004871 normal 9G
4872 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004873 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004874
4875 " Invalid range
4876 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004877 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004878 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004879 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004880 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004881 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004882 endif
4883
4884 call delete('X1')
4885 call delete('X2')
4886 call delete('X3')
4887 call delete('X4')
4888endfunc
4889
4890func Test_cbelow()
4891 call Xtest_below('c')
4892 call Xtest_below('l')
4893endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004894
4895func Test_quickfix_count()
4896 let commands = [
4897 \ 'cNext',
4898 \ 'cNfile',
4899 \ 'cabove',
4900 \ 'cbelow',
4901 \ 'cfirst',
4902 \ 'clast',
4903 \ 'cnewer',
4904 \ 'cnext',
4905 \ 'cnfile',
4906 \ 'colder',
4907 \ 'cprevious',
4908 \ 'crewind',
4909 \
4910 \ 'lNext',
4911 \ 'lNfile',
4912 \ 'labove',
4913 \ 'lbelow',
4914 \ 'lfirst',
4915 \ 'llast',
4916 \ 'lnewer',
4917 \ 'lnext',
4918 \ 'lnfile',
4919 \ 'lolder',
4920 \ 'lprevious',
4921 \ 'lrewind',
4922 \ ]
4923 for cmd in commands
4924 call assert_fails('-1' .. cmd, 'E16:')
4925 call assert_fails('.' .. cmd, 'E16:')
4926 call assert_fails('%' .. cmd, 'E16:')
4927 call assert_fails('$' .. cmd, 'E16:')
4928 endfor
4929endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004930
4931" Test for aborting quickfix commands using QuickFixCmdPre
4932func Xtest_qfcmd_abort(cchar)
4933 call s:setup_commands(a:cchar)
4934
4935 call g:Xsetlist([], 'f')
4936
4937 " cexpr/lexpr
4938 let e = ''
4939 try
4940 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4941 catch /.*/
4942 let e = v:exception
4943 endtry
4944 call assert_equal('AbortCmd', e)
4945 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4946
4947 " cfile/lfile
4948 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4949 let e = ''
4950 try
4951 Xfile Xfile1
4952 catch /.*/
4953 let e = v:exception
4954 endtry
4955 call assert_equal('AbortCmd', e)
4956 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4957 call delete('Xfile1')
4958
4959 " cgetbuffer/lgetbuffer
4960 enew!
4961 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4962 let e = ''
4963 try
4964 Xgetbuffer
4965 catch /.*/
4966 let e = v:exception
4967 endtry
4968 call assert_equal('AbortCmd', e)
4969 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4970 enew!
4971
4972 " vimgrep/lvimgrep
4973 let e = ''
4974 try
4975 Xvimgrep /func/ test_quickfix.vim
4976 catch /.*/
4977 let e = v:exception
4978 endtry
4979 call assert_equal('AbortCmd', e)
4980 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4981
4982 " helpgrep/lhelpgrep
4983 let e = ''
4984 try
4985 Xhelpgrep quickfix
4986 catch /.*/
4987 let e = v:exception
4988 endtry
4989 call assert_equal('AbortCmd', e)
4990 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4991
4992 " grep/lgrep
4993 if has('unix')
4994 let e = ''
4995 try
4996 silent Xgrep func test_quickfix.vim
4997 catch /.*/
4998 let e = v:exception
4999 endtry
5000 call assert_equal('AbortCmd', e)
5001 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5002 endif
5003endfunc
5004
5005func Test_qfcmd_abort()
5006 augroup QF_Test
5007 au!
5008 autocmd QuickFixCmdPre * throw "AbortCmd"
5009 augroup END
5010
5011 call Xtest_qfcmd_abort('c')
5012 call Xtest_qfcmd_abort('l')
5013
5014 augroup QF_Test
5015 au!
5016 augroup END
5017endfunc
5018
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005019" Test for using a file in one of the parent directories.
5020func Test_search_in_dirstack()
5021 call mkdir('Xtestdir/a/b/c', 'p')
5022 let save_cwd = getcwd()
5023 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5024 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5025 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5026 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5027
5028 let lines = "Entering dir Xtestdir\n" .
5029 \ "Entering dir a\n" .
5030 \ "Entering dir b\n" .
5031 \ "Xfile2:2:X2_L2\n" .
5032 \ "Leaving dir a\n" .
5033 \ "Xfile1:2:X1_L2\n" .
5034 \ "Xfile3:1:X3_L1\n" .
5035 \ "Entering dir c\n" .
5036 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005037 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005038 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005039 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005040 call assert_equal(11, getqflist({'size' : 0}).size)
5041 call assert_equal(4, getqflist({'idx' : 0}).idx)
5042 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005043 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005044 cnext
5045 call assert_equal(6, getqflist({'idx' : 0}).idx)
5046 call assert_equal('X1_L2', getline('.'))
5047 cnext
5048 call assert_equal(7, getqflist({'idx' : 0}).idx)
5049 call assert_equal(1, line('$'))
5050 call assert_equal('', getline(1))
5051 cnext
5052 call assert_equal(9, getqflist({'idx' : 0}).idx)
5053 call assert_equal(1, line('$'))
5054 call assert_equal('', getline(1))
5055
5056 set efm&
5057 exe 'cd ' . save_cwd
5058 call delete('Xtestdir', 'rf')
5059endfunc
5060
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005061" Test for :cquit
5062func Test_cquit()
5063 " Exit Vim with a non-zero value
5064 if RunVim([], ["cquit 7"], '')
5065 call assert_equal(7, v:shell_error)
5066 endif
5067
5068 if RunVim([], ["50cquit"], '')
5069 call assert_equal(50, v:shell_error)
5070 endif
5071
5072 " Exit Vim with default value
5073 if RunVim([], ["cquit"], '')
5074 call assert_equal(1, v:shell_error)
5075 endif
5076
5077 " Exit Vim with zero value
5078 if RunVim([], ["cquit 0"], '')
5079 call assert_equal(0, v:shell_error)
5080 endif
5081
5082 " Exit Vim with negative value
5083 call assert_fails('-3cquit', 'E16:')
5084endfunc
5085
Bram Moolenaar858ba062020-05-31 23:11:59 +02005086" Test for getting a specific item from a quickfix list
5087func Xtest_getqflist_by_idx(cchar)
5088 call s:setup_commands(a:cchar)
5089 " Empty list
5090 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5091 Xexpr ['F1:10:L10', 'F1:20:L20']
5092 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5093 call assert_equal(bufnr('F1'), l[0].bufnr)
5094 call assert_equal(20, l[0].lnum)
5095 call assert_equal('L20', l[0].text)
5096 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5097 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5098 %bwipe!
5099endfunc
5100
5101func Test_getqflist_by_idx()
5102 call Xtest_getqflist_by_idx('c')
5103 call Xtest_getqflist_by_idx('l')
5104endfunc
5105
5106" Test for the 'quickfixtextfunc' setting
5107func Tqfexpr(info)
5108 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005109 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005110 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005111 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005112 endif
5113
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005114 let l = []
5115 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5116 let e = qfl[idx]
5117 let s = ''
5118 if e.bufnr != 0
5119 let bname = bufname(e.bufnr)
5120 let s ..= fnamemodify(bname, ':.')
5121 endif
5122 let s ..= '-'
5123 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5124 let s ..= e.text
5125 call add(l, s)
5126 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005127
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005128 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005129endfunc
5130
5131func Xtest_qftextfunc(cchar)
5132 call s:setup_commands(a:cchar)
5133
5134 set efm=%f:%l:%c:%m
5135 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005136 call assert_equal('Tqfexpr', &quickfixtextfunc)
5137 call assert_equal('',
5138 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005139 call g:Xsetlist([
5140 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5141 \ 'end_col': 7, 'text': 'green'},
5142 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5143 \ 'end_col': 8, 'text': 'blue'},
5144 \ ])
5145
Bram Moolenaar858ba062020-05-31 23:11:59 +02005146 Xwindow
5147 call assert_equal('F1-L10C2-green', getline(1))
5148 call assert_equal('F1-L20C4-blue', getline(2))
5149 Xclose
5150 set quickfixtextfunc&vim
5151 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005152 call assert_equal('F1|10 col 2-7| green', getline(1))
5153 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005154 Xclose
5155 set efm&
5156 set quickfixtextfunc&
5157
5158 " Test for per list 'quickfixtextfunc' setting
5159 func PerQfText(info)
5160 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005161 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005162 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005163 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005164 endif
5165 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005166 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005167 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005168 let l = []
5169 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5170 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5171 endfor
5172 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005173 endfunc
5174 set quickfixtextfunc=Tqfexpr
5175 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5176 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5177 Xwindow
5178 call assert_equal('Line 10, Col 2', getline(1))
5179 call assert_equal('Line 20, Col 4', getline(2))
5180 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005181 call assert_equal(function('PerQfText'),
5182 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005183 " Add entries to the list when the quickfix buffer is hidden
5184 Xaddexpr ['F1:30:6:red']
5185 Xwindow
5186 call assert_equal('Line 30, Col 6', getline(3))
5187 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005188 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005189 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005190 set quickfixtextfunc&
5191 delfunc PerQfText
5192
5193 " Non-existing function
5194 set quickfixtextfunc=Tabc
5195 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5196 call assert_fails("Xwindow", 'E117:')
5197 Xclose
5198 set quickfixtextfunc&
5199
5200 " set option to a non-function
5201 set quickfixtextfunc=[10,\ 20]
5202 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5203 call assert_fails("Xwindow", 'E117:')
5204 Xclose
5205 set quickfixtextfunc&
5206
5207 " set option to a function with different set of arguments
5208 func Xqftext(a, b, c)
5209 return a:a .. a:b .. a:c
5210 endfunc
5211 set quickfixtextfunc=Xqftext
5212 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5213 call assert_fails("Xwindow", 'E119:')
5214 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005215
5216 " set option to a function that returns a list with non-strings
5217 func Xqftext2(d)
5218 return ['one', [], 'two']
5219 endfunc
5220 set quickfixtextfunc=Xqftext2
5221 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5222 \ 'E730:')
5223 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005224 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5225 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005226 Xclose
5227
Bram Moolenaar858ba062020-05-31 23:11:59 +02005228 set quickfixtextfunc&
5229 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005230 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005231
5232 " set the global option to a lambda function
5233 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5234 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5235 Xwindow
5236 call assert_equal(['green', 'blue'], getline(1, '$'))
5237 Xclose
5238 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)
5239 set quickfixtextfunc&
5240
5241 " use a lambda function that returns an empty list
5242 set quickfixtextfunc={d\ ->\ []}
5243 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5244 Xwindow
5245 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5246 \ getline(1, '$'))
5247 Xclose
5248 set quickfixtextfunc&
5249
5250 " use a lambda function that returns a list with empty strings
5251 set quickfixtextfunc={d\ ->\ ['',\ '']}
5252 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5253 Xwindow
5254 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5255 \ getline(1, '$'))
5256 Xclose
5257 set quickfixtextfunc&
5258
5259 " set the per-quickfix list text function to a lambda function
5260 call g:Xsetlist([], ' ',
5261 \ {'quickfixtextfunc' :
5262 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5263 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5264 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5265 Xwindow
5266 call assert_equal('Line 10, Col 2', getline(1))
5267 call assert_equal('Line 20, Col 4', getline(2))
5268 Xclose
5269 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5270 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005271endfunc
5272
5273func Test_qftextfunc()
5274 call Xtest_qftextfunc('c')
5275 call Xtest_qftextfunc('l')
5276endfunc
5277
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005278" Test for updating a location list for some other window and check that
5279" 'qftextfunc' uses the correct location list.
5280func Test_qftextfunc_other_loclist()
5281 %bw!
5282 call setloclist(0, [], 'f')
5283
5284 " create a window and a location list for it and open the location list
5285 " window
5286 lexpr ['F1:10:12:one', 'F1:20:14:two']
5287 let w1_id = win_getid()
5288 call setloclist(0, [], ' ',
5289 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5290 \ 'quickfixtextfunc':
5291 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5292 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5293 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5294 lwindow
5295 let w2_id = win_getid()
5296
5297 " create another window and a location list for it and open the location
5298 " list window
5299 topleft new
5300 let w3_id = win_getid()
5301 call setloclist(0, [], ' ',
5302 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5303 \ 'quickfixtextfunc':
5304 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5305 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5306 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5307 lwindow
5308 let w4_id = win_getid()
5309
5310 topleft new
5311 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5312 let w5_id = win_getid()
5313
5314 " change the location list for some other window
5315 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5316 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5317 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5318 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5319 \ getbufline(winbufnr(w2_id), 1, '$'))
5320 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5321 \ getbufline(winbufnr(w4_id), 1, '$'))
5322 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5323 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5324 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5325 \ getbufline(winbufnr(w2_id), 1, '$'))
5326 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5327 \ getbufline(winbufnr(w4_id), 1, '$'))
5328
5329 call win_gotoid(w5_id)
5330 lwindow
5331 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5332 \ getline(1, '$'))
5333 %bw!
5334endfunc
5335
Bram Moolenaarec98e932020-06-08 19:35:59 +02005336" Running :lhelpgrep command more than once in a help window, doesn't jump to
5337" the help topic
5338func Test_lhelpgrep_from_help_window()
5339 call mkdir('Xtestdir/doc', 'p')
5340 call writefile(['window'], 'Xtestdir/doc/a.txt')
5341 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5342 let save_rtp = &rtp
5343 let &rtp = 'Xtestdir'
5344 lhelpgrep window
5345 lhelpgrep buffer
5346 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5347 lhelpgrep window
5348 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5349 let &rtp = save_rtp
5350 call delete('Xtestdir', 'rf')
5351 new | only!
5352endfunc
5353
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005354" Test for the crash fixed by 7.3.715
5355func Test_setloclist_crash()
5356 %bw!
5357 let g:BufNum = bufnr()
5358 augroup QF_Test
5359 au!
5360 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5361 augroup END
5362
5363 try
5364 lvimgrep /.*/ *.mak
5365 catch /E926:/
5366 endtry
5367 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5368 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5369
5370 augroup QF_Test
5371 au!
5372 augroup END
5373 unlet g:BufNum
5374 %bw!
5375endfunc
5376
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005377" Test for adding an invalid entry with the quickfix window open and making
5378" sure that the window contents are not changed
5379func Test_add_invalid_entry_with_qf_window()
5380 call setqflist([], 'f')
5381 cexpr "Xfile1:10:aa"
5382 copen
5383 call setqflist(['bb'], 'a')
5384 call assert_equal(1, line('$'))
5385 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005386 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())
5387
5388 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5389 call assert_equal(1 , line('$'))
5390 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5391 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())
5392
5393 call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5394 call assert_equal(1 , line('$'))
5395 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5396 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())
5397
5398 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5399 call assert_equal(1 , line('$'))
5400 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5401 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5402
5403 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5404 call assert_equal(1 , line('$'))
5405 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5406 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5407
5408 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5409 call assert_equal(1 , line('$'))
5410 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5411 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5412
5413 call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5414 call assert_equal(1 , line('$'))
5415 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5416 call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
5417
5418 call setqflist([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5419 call assert_equal(1 , line('$'))
5420 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5421 call assert_equal([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist())
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005422 cclose
5423endfunc
5424
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005425" Test for very weird problem: autocommand causes a failure, resulting opening
5426" the quickfix window to fail. This still splits the window, but otherwise
5427" should not mess up buffers.
5428func Test_quickfix_window_fails_to_open()
5429 CheckScreendump
5430
5431 let lines =<< trim END
5432 anything
5433 try
5434 anything
5435 endtry
5436 END
5437 call writefile(lines, 'XquickfixFails')
5438
5439 let lines =<< trim END
5440 split XquickfixFails
5441 silent vimgrep anything %
5442 normal o
5443 au BufLeave * ++once source XquickfixFails
5444 " This will trigger the autocommand, which causes an error, what follows
5445 " is aborted but the window was already split.
5446 silent! cwindow
5447 END
5448 call writefile(lines, 'XtestWinFails')
5449 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5450 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5451
5452 " clean up
5453 call term_sendkeys(buf, ":bwipe!\<CR>")
5454 call term_wait(buf)
5455 call StopVimInTerminal(buf)
5456 call delete('XtestWinFails')
5457 call delete('XquickfixFails')
5458endfunc
5459
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005460" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005461" is changed.
5462func Xqfbuf_update(cchar)
5463 call s:setup_commands(a:cchar)
5464
5465 Xexpr "F1:1:line1"
5466 Xopen
5467 call assert_equal(['F1|1| line1'], getline(1, '$'))
5468 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5469
5470 " Test setqflist() using the 'lines' key in 'what'
5471 " add a new entry
5472 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5473 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5474 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5475 " replace all the entries with a single entry
5476 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5477 call assert_equal(['F3|3| line3'], getline(1, '$'))
5478 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5479 " remove all the entries
5480 call g:Xsetlist([], 'r', {'lines' : []})
5481 call assert_equal([''], getline(1, '$'))
5482 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5483 " add a new list
5484 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5485 call assert_equal(['F4|4| line4'], getline(1, '$'))
5486 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5487
5488 " Test setqflist() using the 'items' key in 'what'
5489 " add a new entry
5490 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5491 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5492 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5493 " replace all the entries with a single entry
5494 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5495 call assert_equal(['F6|6| line6'], getline(1, '$'))
5496 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5497 " remove all the entries
5498 call g:Xsetlist([], 'r', {'items' : []})
5499 call assert_equal([''], getline(1, '$'))
5500 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5501 " add a new list
5502 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5503 call assert_equal(['F7|7| line7'], getline(1, '$'))
5504 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5505
5506 call g:Xsetlist([], ' ', {})
5507 call assert_equal([''], getline(1, '$'))
5508 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5509
5510 Xclose
5511endfunc
5512
5513func Test_qfbuf_update()
5514 call Xqfbuf_update('c')
5515 call Xqfbuf_update('l')
5516endfunc
5517
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005518func Test_vimgrep_noswapfile()
5519 set noswapfile
5520 call writefile(['one', 'two', 'three'], 'Xgreppie')
5521 vimgrep two Xgreppie
5522 call assert_equal('two', getline('.'))
5523
5524 call delete('Xgreppie')
5525 set swapfile
5526endfunc
5527
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005528" Test for the :vimgrep 'f' flag (fuzzy match)
5529func Xvimgrep_fuzzy_match(cchar)
5530 call s:setup_commands(a:cchar)
5531
5532 Xvimgrep /three one/f Xfile*
5533 let l = g:Xgetlist()
5534 call assert_equal(2, len(l))
5535 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5536 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5537 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5538 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5539
5540 Xvimgrep /the/f Xfile*
5541 let l = g:Xgetlist()
5542 call assert_equal(3, len(l))
5543 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5544 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5545 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5546 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5547 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5548 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5549
5550 Xvimgrep /aaa/fg Xfile*
5551 let l = g:Xgetlist()
5552 call assert_equal(4, len(l))
5553 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5554 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5555 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5556 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5557 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5558 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5559 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5560 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5561
5562 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5563endfunc
5564
5565func Test_vimgrep_fuzzy_match()
5566 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5567 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5568 call Xvimgrep_fuzzy_match('c')
5569 call Xvimgrep_fuzzy_match('l')
5570 call delete('Xfile1')
5571 call delete('Xfile2')
5572endfunc
5573
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005574func Test_locationlist_open_in_newtab()
5575 call s:create_test_file('Xqftestfile1')
5576 call s:create_test_file('Xqftestfile2')
5577 call s:create_test_file('Xqftestfile3')
5578
5579 %bwipe!
5580
5581 lgetexpr ['Xqftestfile1:5:Line5',
5582 \ 'Xqftestfile2:10:Line10',
5583 \ 'Xqftestfile3:16:Line16']
5584
5585 silent! llast
5586 call assert_equal(1, tabpagenr('$'))
5587 call assert_equal('Xqftestfile3', bufname())
5588
5589 set switchbuf=newtab
5590
5591 silent! lfirst
5592 call assert_equal(2, tabpagenr('$'))
5593 call assert_equal('Xqftestfile1', bufname())
5594
5595 silent! lnext
5596 call assert_equal(3, tabpagenr('$'))
5597 call assert_equal('Xqftestfile2', bufname())
5598
5599 call delete('Xqftestfile1')
5600 call delete('Xqftestfile2')
5601 call delete('Xqftestfile3')
5602 set switchbuf&vim
5603
5604 %bwipe!
5605endfunc
5606
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005607" Test for win_gettype() in quickfix and location list windows
5608func Test_win_gettype()
5609 copen
5610 call assert_equal("quickfix", win_gettype())
5611 let wid = win_getid()
5612 wincmd p
5613 call assert_equal("quickfix", win_gettype(wid))
5614 cclose
5615 lexpr ''
5616 lopen
5617 call assert_equal("loclist", win_gettype())
5618 let wid = win_getid()
5619 wincmd p
5620 call assert_equal("loclist", win_gettype(wid))
5621 lclose
5622endfunc
5623
Christian Brabandt0b226f62021-12-01 10:54:24 +00005624fun Test_vimgrep_nomatch()
5625 call XexprTests('c')
5626 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5627 copen
5628 if has("win32")
5629 call assert_fails('vimgrep foo *.zzz', 'E479:')
5630 let expected = [{'lnum': 10, 'bufnr': 0, 'end_lnum': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': 0, 'module': '', 'type': '', 'end_col': 0, 'col': 0, 'text': 'Line1'}]
5631 else
5632 call assert_fails('vimgrep foo *.zzz', 'E480:')
5633 let expected = []
5634 endif
5635 call assert_equal(expected, getqflist())
5636 cclose
5637endfunc
5638
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005639" Test for opening the quickfix window in two tab pages and then closing one
5640" of the quickfix windows. This should not make the quickfix buffer unlisted.
5641" (github issue #9300).
5642func Test_two_qf_windows()
5643 cexpr "F1:1:line1"
5644 copen
5645 tabnew
5646 copen
5647 call assert_true(&buflisted)
5648 cclose
5649 tabfirst
5650 call assert_true(&buflisted)
5651 let bnum = bufnr()
5652 cclose
5653 " if all the quickfix windows are closed, then buffer should be unlisted.
5654 call assert_false(buflisted(bnum))
5655 %bw!
5656
5657 " Repeat the test for a location list
5658 lexpr "F2:2:line2"
5659 lopen
5660 let bnum = bufnr()
5661 tabnew
5662 exe "buffer" bnum
5663 tabfirst
5664 lclose
5665 tablast
5666 call assert_true(buflisted(bnum))
5667 tabclose
5668 lopen
5669 call assert_true(buflisted(bnum))
5670 lclose
5671 call assert_false(buflisted(bnum))
5672 %bw!
5673endfunc
5674
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005675" vim: shiftwidth=2 sts=2 expandtab