blob: 511896e1856611dfde47e46958a7293d6ad48958 [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
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00004source vim9.vim
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01006
Bram Moolenaare00fdf32019-09-15 19:09:42 +02007source screendump.vim
8
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01009set encoding=utf-8
10
Bram Moolenaar2b946c92016-11-12 18:14:44 +010011func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020012 if a:cchar == 'c'
13 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
14 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020015 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020016 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020017 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010018 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020019 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020020 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020021 command! -nargs=* Xclose <mods>cclose <args>
22 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
23 command! -nargs=* Xgetfile <mods>cgetfile <args>
24 command! -nargs=* Xaddfile <mods>caddfile <args>
25 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
26 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
27 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
28 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020029 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
30 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020031 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
32 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020033 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020034 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020035 command! -nargs=* Xexpr <mods>cexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020036 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010037 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020038 command! -nargs=* Xgrep <mods> grep <args>
39 command! -nargs=* Xgrepadd <mods> grepadd <args>
40 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010041 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020042 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
43 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020044 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
45 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020046 let g:Xgetlist = function('getqflist')
47 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020048 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020049 else
50 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
51 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020052 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020053 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020054 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010055 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020056 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020057 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020058 command! -nargs=* Xclose <mods>lclose <args>
59 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
60 command! -nargs=* Xgetfile <mods>lgetfile <args>
61 command! -nargs=* Xaddfile <mods>laddfile <args>
62 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
63 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
64 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
65 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020066 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
67 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020068 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
69 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020070 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020071 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020072 command! -nargs=* Xexpr <mods>lexpr <args>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020073 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010074 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020075 command! -nargs=* Xgrep <mods> lgrep <args>
76 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
77 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010078 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020079 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
80 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020081 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
82 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020083 let g:Xgetlist = function('getloclist', [0])
84 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020085 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020086 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010087endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020088
Bram Moolenaara5d78d12021-12-15 12:28:22 +000089" This must be run before any error lists are created.
90func Test_AA_cc_no_errors()
91 call assert_fails('cc', 'E42:')
92 call assert_fails('ll', 'E42:')
93endfunc
94
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010096func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020097 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020099 if a:cchar == 'l'
100 call assert_fails('llist', 'E776:')
101 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200103 Xgetexpr []
104 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100105 call assert_true(v:errmsg ==# 'E42: No Errors')
106
107 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200108 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100109 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100110 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100111
112 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100113 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100114 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
115 \ ' 4 Xtestfile2:2 col 2: Line2',
116 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
117
118 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100119 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100120 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
121 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100122 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123
124 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
127 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
128
Bram Moolenaaree85df32017-03-19 14:19:50 +0100129 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100130 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
131
Bram Moolenaaree85df32017-03-19 14:19:50 +0100132 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100133 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
134
Bram Moolenaaree85df32017-03-19 14:19:50 +0100135 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100136 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
137 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100138
139 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100140 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100141 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
142 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100143
thinca6864efa2021-06-19 20:45:20 +0200144 " Ranged entries
145 call g:Xsetlist([{'lnum':10,'text':'Line1'},
146 \ {'lnum':20,'col':10,'text':'Line2'},
147 \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
148 \ {'lnum':40,'end_lnum':45,'text':'Line4'},
149 \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
150 \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
151 let l = split(execute('Xlist', ""), "\n")
152 call assert_equal([' 1:10: Line1',
153 \ ' 2:20 col 10: Line2',
154 \ ' 3:30 col 15-20: Line3',
155 \ ' 4:40-45: Line4',
156 \ ' 5:50-55 col 15: Line5',
157 \ ' 6:60-65 col 25-35: Line6'], l)
158
Bram Moolenaaree85df32017-03-19 14:19:50 +0100159 " Different types of errors
160 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
161 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
162 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
163 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
164 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
165 let l = split(execute('Xlist', ""), "\n")
166 call assert_equal([' 1:10 col 5 warning 11: Warning',
167 \ ' 2:20 col 10 error 22: Error',
168 \ ' 3:30 col 15 info 33: Info',
169 \ ' 4:40 col 20 x 44: Other',
170 \ ' 5:50 col 25 55: one'], l)
171
Bram Moolenaard76ce852018-05-01 15:02:04 +0200172 " Test for module names, one needs to explicitly set `'valid':v:true` so
173 call g:Xsetlist([
174 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
175 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
176 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
177 let l = split(execute('Xlist', ""), "\n")
178 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
179 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
180 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
181
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100182 " For help entries in the quickfix list, only the filename without directory
183 " should be displayed
184 Xhelpgrep setqflist()
185 let l = split(execute('Xlist 1', ''), "\n")
186 call assert_match('^ 1 [^\\/]\{-}:', l[0])
187
Bram Moolenaaree85df32017-03-19 14:19:50 +0100188 " Error cases
189 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100190endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100191
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100192func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100193 call XlistTests('c')
194 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100195endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100196
197" Tests for the :colder, :cnewer, :lolder and :lnewer commands
198" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100199" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100200func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200201 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100202
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200203 if a:cchar == 'l'
204 " No location list for the current window
205 call assert_fails('lolder', 'E776:')
206 call assert_fails('lnewer', 'E776:')
207 endif
208
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200209 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200210 call g:Xsetlist(list)
211
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100212 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100214 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
215
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200216 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100217 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
218
219 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200220 Xgetexpr ['Xtestfile1:1:3:Line1']
221 Xgetexpr ['Xtestfile2:2:2:Line2']
222 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223
224 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200225 Xolder
226 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100227 call assert_equal('Line2', l[0].text)
228
229 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 Xnewer
231 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100232 call assert_equal('Line3', l[0].text)
233
234 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200235 Xolder 2
236 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 call assert_equal('Line1', l[0].text)
238
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200239 Xnewer 2
240 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100241 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100242endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100243
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100244func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100245 call XageTests('c')
246 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100247endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100248
249" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
250" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100251func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200252 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200254 " Opening the location list window without any errors should fail
255 if a:cchar == 'l'
256 call assert_fails('lopen', 'E776:')
257 endif
258
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100259 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200260 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100261
262 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200263 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100264 call assert_true(winnr('$') == 1)
265
266 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200267 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
268 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269
270 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200271 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100272 call assert_true(winnr('$') == 2 && winnr() == 2 &&
273 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200274 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100275
276 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200277 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100278 call assert_true(winnr('$') == 1)
279
280 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200281 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100282
283 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200284 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100285 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200286 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100287
288 " Opening the window again, should move the cursor to that window
289 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200290 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100291 call assert_true(winnr('$') == 2 && winnr() == 2 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200292 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100293 \ getline('.') ==# '|| non-error 1')
294
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100295 " :cnext in quickfix window should move to the next entry
296 Xnext
297 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100298
299 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200300 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100301 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200302
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100303 " Specifying the width should adjust the width for a vertically split
304 " quickfix window.
305 vert Xopen
306 call assert_equal(10, winwidth(0))
307 vert Xopen 12
308 call assert_equal(12, winwidth(0))
309 Xclose
310
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200311 " Horizontally or vertically splitting the quickfix window should create a
312 " normal window/buffer
313 Xopen
314 wincmd s
315 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
316 call assert_equal(0, getwininfo(win_getid())[0].loclist)
317 call assert_notequal('quickfix', &buftype)
318 close
319 Xopen
320 wincmd v
321 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
322 call assert_equal(0, getwininfo(win_getid())[0].loclist)
323 call assert_notequal('quickfix', &buftype)
324 close
325 Xopen
326 Xclose
327
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200328 if a:cchar == 'c'
329 " Opening the quickfix window in multiple tab pages should reuse the
330 " quickfix buffer
331 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
332 \ 'Xtestfile3:3:1:Line3']
333 Xopen
334 let qfbufnum = bufnr('%')
335 tabnew
336 Xopen
337 call assert_equal(qfbufnum, bufnr('%'))
338 new | only | tabonly
339 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100340endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100341
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100342func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100343 call XwindowTests('c')
344 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100345endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346
Bram Moolenaar36d50222019-05-02 20:17:40 +0200347func Test_copenHeight()
348 copen
349 wincmd H
350 let height = winheight(0)
351 copen 10
352 call assert_equal(height, winheight(0))
353 quit
354endfunc
355
Bram Moolenaar1142a312019-10-16 14:51:39 +0200356func Test_copenHeight_tabline()
357 set tabline=foo showtabline=2
358 copen
359 wincmd H
360 let height = winheight(0)
361 copen 10
362 call assert_equal(height, winheight(0))
363 quit
364 set tabline& showtabline&
365endfunc
366
367
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
369" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100370func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100372
373 call writefile(['Xtestfile1:700:10:Line 700',
374 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
375
376 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200377 Xfile Xqftestfile1
378 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100379 call assert_true(len(l) == 2 &&
380 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
381 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
382
Bram Moolenaar049cba92016-06-26 14:38:04 +0200383 " Test with a non existent file
Bram Moolenaare2e40752020-09-04 21:18:46 +0200384 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200385
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100386 " Run cfile/lfile from a modified buffer
387 enew!
388 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200389 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100390 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
391
392 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200393 Xaddfile Xqftestfile1
394 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395 call assert_true(len(l) == 3 &&
396 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
397
398 call writefile(['Xtestfile1:222:77:Line 222',
399 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
400
401 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200402 Xgetfile Xqftestfile1
403 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100404 call assert_true(len(l) == 2 &&
405 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
406 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
407
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100408 " Test for a file with a long line and without a newline at the end
409 let text = repeat('x', 1024)
410 let t = 'a.txt:18:' . text
411 call writefile([t], 'Xqftestfile1', 'b')
412 silent! Xfile Xqftestfile1
413 call assert_equal(text, g:Xgetlist()[0].text)
414
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100415 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100416endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100417
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100418func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100419 call XfileTests('c')
420 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100421endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100422
423" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
424" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100425func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200426 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100427
428 enew!
429 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
430 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200431 Xbuffer!
432 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100433 call assert_true(len(l) == 2 &&
434 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
435 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
436
437 enew!
438 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
439 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200440 Xgetbuffer
441 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100442 call assert_true(len(l) == 2 &&
443 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
444 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
445
446 enew!
447 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
448 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200449 Xaddbuffer
450 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100451 call assert_true(len(l) == 4 &&
452 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
453 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
454 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200455 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100456
Bram Moolenaaree85df32017-03-19 14:19:50 +0100457 " Check for invalid buffer
458 call assert_fails('Xbuffer 199', 'E474:')
459
460 " Check for unloaded buffer
461 edit Xtestfile1
462 let bnr = bufnr('%')
463 enew!
464 call assert_fails('Xbuffer ' . bnr, 'E681:')
465
466 " Check for invalid range
467 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
468 " commands. So directly call the commands.
469 if (a:cchar == 'c')
470 call assert_fails('900,999cbuffer', 'E16:')
471 else
472 call assert_fails('900,999lbuffer', 'E16:')
473 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100474endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100475
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100476func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100477 call XbufferTests('c')
478 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100479endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100480
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100481func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200482 call s:setup_commands(a:cchar)
483
484 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100485endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200486
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100487func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200488 call XexprTests('c')
489 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100490endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200491
492" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100493func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200494 call s:setup_commands(a:cchar)
495
Bram Moolenaar74240d32017-12-10 15:26:15 +0100496 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200497 " Jumping to first or next location list entry without any error should
498 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100499 if a:cchar == 'c'
500 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100501 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100502 else
503 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100504 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200505 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100506 call assert_fails('Xnext', err)
507 call assert_fails('Xprev', err)
508 call assert_fails('Xnfile', err)
509 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100510 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200511
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100512 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100513 call assert_fails(cmd, 'E42:')
514
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200515 call s:create_test_file('Xqftestfile1')
516 call s:create_test_file('Xqftestfile2')
517
518 Xgetexpr ['Xqftestfile1:5:Line5',
519 \ 'Xqftestfile1:6:Line6',
520 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200521 \ 'Xqftestfile2:11:Line11',
522 \ 'RegularLine1',
523 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200524
525 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100526 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200527 call assert_fails('Xprev', 'E553:')
528 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200529 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200530 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200531 call assert_equal(10, line('.'))
532 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200533 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200534 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100535 5Xcc
536 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
537 2Xcc
538 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100539 if a:cchar == 'c'
540 cc
541 else
542 ll
543 endif
544 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100545 10Xcc
546 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200547 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200549 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200550 call assert_equal(11, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200551 call assert_fails('Xnext', 'E553:')
552 call assert_fails('Xnfile', 'E553:')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100553 " To process the range using quickfix list entries, directly use the
554 " quickfix commands (don't use the user defined commands)
555 if a:cchar == 'c'
556 $cc
557 else
558 $ll
559 endif
560 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200561 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200562 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200563 call assert_equal(5, line('.'))
564
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200565 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200566 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200567 call assert_equal(11, line('.'))
568 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200569 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200570 call assert_equal(5, line('.'))
571
Bram Moolenaar74240d32017-12-10 15:26:15 +0100572 " Jumping to an error from the error window using cc command
573 Xgetexpr ['Xqftestfile1:5:Line5',
574 \ 'Xqftestfile1:6:Line6',
575 \ 'Xqftestfile2:10:Line10',
576 \ 'Xqftestfile2:11:Line11']
577 Xopen
578 10Xcc
579 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200580 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100581 Xopen
582 call cursor(2, 1)
583 if a:cchar == 'c'
584 .cc
585 else
586 .ll
587 endif
588 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200589 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100590
591 " Jumping to an error from the error window (when only the error window is
592 " present)
593 Xopen | only
594 Xlast 1
595 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200596 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100597
Bram Moolenaaree85df32017-03-19 14:19:50 +0100598 Xexpr ""
599 call assert_fails('Xnext', 'E42:')
600
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200601 call delete('Xqftestfile1')
602 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200603
604 " Should be able to use next/prev with invalid entries
605 Xexpr ""
606 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
607 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100608 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200609 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
610 Xlast
611 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
612 Xfirst
613 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
614 2Xnext
615 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100616endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200617
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100618func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200619 call Xtest_browse('c')
620 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100621endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200622
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100623func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200624 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100625 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100626
Bram Moolenaarce90e362019-09-08 18:58:44 +0200627 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100628 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100629
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200630 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100631 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100632
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200633 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100634 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100635
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200636 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100637 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100638
639endfunc
640
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100641func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200642 call s:setup_commands(a:cchar)
643 Xhelpgrep quickfix
644 Xopen
645 if a:cchar == 'c'
646 let title_text = ':helpgrep quickfix'
647 else
648 let title_text = ':lhelpgrep quickfix'
649 endif
650 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200651
652 " Jumping to a help topic should open the help window
653 only
654 Xnext
655 call assert_true(&buftype == 'help')
656 call assert_true(winnr('$') == 2)
657 " Jumping to the next match should reuse the help window
658 Xnext
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
661 call assert_true(winnr('$') == 2)
662 " Jumping to the next match from the quickfix window should reuse the help
663 " window
664 Xopen
665 Xnext
666 call assert_true(&buftype == 'help')
667 call assert_true(winnr() == 1)
668 call assert_true(winnr('$') == 2)
thinca6864efa2021-06-19 20:45:20 +0200669 call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200670
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100671 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200672 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100673
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100674 " When the current window is vertically split, jumping to a help match
675 " should open the help window at the top.
676 only | enew
677 let w1 = win_getid()
678 vert new
679 let w2 = win_getid()
680 Xnext
681 let w3 = win_getid()
682 call assert_true(&buftype == 'help')
683 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100684 " See jump_to_help_window() for details
685 let w2_width = winwidth(w2)
686 if w2_width != &columns && w2_width < 80
687 call assert_equal(['col', [['leaf', w3],
688 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
689 else
690 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
691 \ ['leaf', w1]]] , winlayout())
692 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100693
694 new | only
695 set buftype=help
696 set modified
697 call assert_fails('Xnext', 'E37:')
698 set nomodified
699 new | only
700
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200701 if a:cchar == 'l'
702 " When a help window is present, running :lhelpgrep should reuse the
703 " help window and not the current window
704 new | only
705 call g:Xsetlist([], 'f')
706 help index.txt
707 wincmd w
708 lhelpgrep quickfix
709 call assert_equal(1, winnr())
710 call assert_notequal([], getloclist(1))
711 call assert_equal([], getloclist(2))
712 endif
713
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200714 new | only
715
Bram Moolenaaree85df32017-03-19 14:19:50 +0100716 " Search for non existing help string
717 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200718 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200719 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100720endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200721
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100722func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200723 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200724 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200725 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100726endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100727
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100728def Test_helpgrep_vim9_restore_cpo()
729 assert_equal('aABceFs', &cpo)
730
731 var rtp_save = &rtp
732 var dir = 'Xruntime/after'
733 &rtp ..= ',' .. dir
734 mkdir(dir .. '/ftplugin', 'p')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100735 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100736 filetype plugin on
737 silent helpgrep grail
738 cwindow
739 silent helpgrep grail
740
741 assert_equal('aABceFs', &cpo)
742 delete(dir, 'rf')
743 &rtp = rtp_save
744 cclose
745 helpclose
746enddef
747
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200748def Test_vim9_cexpr()
749 var text = 'somefile:95:error'
750 cexpr text
751 var l = getqflist()
752 assert_equal(1, l->len())
753 assert_equal(95, l[0].lnum)
754 assert_equal('error', l[0].text)
755
756 text = 'somefile:77:warning'
757 caddexpr text
758 l = getqflist()
759 assert_equal(2, l->len())
760 assert_equal(77, l[1].lnum)
761 assert_equal('warning', l[1].text)
762enddef
763
Bram Moolenaar6920c722016-01-22 22:44:10 +0100764func Test_errortitle()
765 augroup QfBufWinEnter
766 au!
767 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
768 augroup END
769 copen
770 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
771 call setqflist(a)
772 call assert_equal(':setqflist()', g:a)
773 augroup QfBufWinEnter
774 au!
775 augroup END
776 augroup! QfBufWinEnter
777endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100778
Bram Moolenaar5584df62016-03-18 21:00:51 +0100779func Test_vimgreptitle()
780 augroup QfBufWinEnter
781 au!
782 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
783 augroup END
784 try
785 vimgrep /pattern/j file
786 catch /E480/
787 endtry
788 copen
789 call assert_equal(': vimgrep /pattern/j file', g:a)
790 augroup QfBufWinEnter
791 au!
792 augroup END
793 augroup! QfBufWinEnter
794endfunc
795
Bram Moolenaar1d30fde2021-10-20 21:58:42 +0100796func Test_bufwinenter_once()
797 augroup QfBufWinEnter
798 au!
799 au BufWinEnter * let g:got_afile ..= 'got ' .. expand('<afile>')
800 augroup END
801 let g:got_afile = ''
802 copen
803 call assert_equal('got quickfix', g:got_afile)
804
805 cclose
806 unlet g:got_afile
807 augroup QfBufWinEnter
808 au!
809 augroup END
810 augroup! QfBufWinEnter
811endfunc
812
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100813func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200814 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100815
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200816 Xgetexpr ['file:1:1:message']
817 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100818 if a:cchar == 'c'
819 call setqflist(l, 'r')
820 else
821 call setloclist(0, l, 'r')
822 endif
823
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200824 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100825 if a:cchar == 'c'
826 let title = ':setqflist()'
827 else
828 let title = ':setloclist()'
829 endif
830 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200831 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100832endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100833
834" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100835func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200836 call XqfTitleTests('c')
837 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100838endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100839
840" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100841func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100842 let save_efm = &efm
843 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
844 cgetexpr ['WWWW', 'EEEE', 'CCCC']
845 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
846 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
847 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
848 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
849 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
850 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
851 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
852 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
853 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100854endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100855
856" This will test for problems in quickfix:
857" A. incorrectly copying location lists which caused the location list to show
858" a different name than the file that was actually being displayed.
859" B. not reusing the window for which the location list window is opened but
860" instead creating new windows.
861" C. make sure that the location list window is not reused instead of the
862" window it belongs to.
863"
864" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100865func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100866 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
867 let word = substitute(base, '\v(.*)\..*', '\1', '')
868
869 setl modifiable
870 setl noreadonly
871 setl noswapfile
872 setl bufhidden=delete
873 %del _
874 " For problem 2:
875 " 'buftype' has to be set to reproduce the constant opening of new windows
876 setl buftype=nofile
877
878 call setline(1, word)
879
880 setl nomodified
881 setl nomodifiable
882 setl readonly
883 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100884endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100885
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100886func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200887 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100888
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200889 augroup testgroup
890 au!
891 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
892 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100893
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200894 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100895
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200896 let qflist = []
897 for word in words
898 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
899 " NOTE: problem 1:
900 " intentionally not setting 'lnum' so that the quickfix entries are not
901 " valid
902 eval qflist->setloclist(0, ' ')
903 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100904
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200905 " Test A
906 lrewind
907 enew
908 lopen
909 4lnext
910 vert split
911 wincmd L
912 lopen
913 wincmd p
914 lnext
915 let fileName = expand("%")
916 wincmd p
917 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
918 let fileName = substitute(fileName, '\\', '/', 'g')
919 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
920 call assert_equal("test://bar.txt", fileName)
921 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100922
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200923 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100924
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200925 " Test B:
926 lrewind
927 lopen
928 2
929 exe "normal \<CR>"
930 wincmd p
931 3
932 exe "normal \<CR>"
933 wincmd p
934 4
935 exe "normal \<CR>"
936 call assert_equal(2, winnr('$'))
937 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100938
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200939 " Test C:
940 lrewind
941 lopen
942 " Let's move the location list window to the top to check whether it (the
943 " first window found) will be reused when we try to open new windows:
944 wincmd K
945 2
946 exe "normal \<CR>"
947 wincmd p
948 3
949 exe "normal \<CR>"
950 wincmd p
951 4
952 exe "normal \<CR>"
953 1wincmd w
954 call assert_equal('quickfix', &buftype)
955 2wincmd w
956 let bufferName = expand("%")
957 let bufferName = substitute(bufferName, '\\', '/', 'g')
958 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100959
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200960 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100961
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200962 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100963endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100964
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100965func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200966 augroup testgroup
967 au!
968 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
969 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100970
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200971 func! R(n)
972 quit
973 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100974
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200975 new
976 let q = []
977 call add(q, {'filename': 'test_curwin.txt' })
978 call setloclist(0, q)
979 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100980
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200981 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100982endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100983
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100984func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200985 call writefile(['loclistfoo'], 'loclistfoo')
986 call writefile(['loclistbar'], 'loclistbar')
987 set switchbuf=usetab
988
989 edit loclistfoo
990 tabedit loclistbar
991 silent lgrep loclistfoo loclist*
992 call assert_equal(1, tabpagenr())
993
994 enew | only | tabonly
995 set switchbuf&vim
996 call delete('loclistfoo')
997 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100998endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200999
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001000" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001001func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001002 " The 'errorformat' setting is different on non-Unix systems.
1003 " This test works only on Unix-like systems.
1004 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001005
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001006 let l =<< trim [DATA]
1007 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
1008 "Xtestfile", line 6 col 19; this is an error
1009 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
1010 Xtestfile:9: parse error before `asd'
1011 make: *** [vim] Error 1
1012 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001013
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001014 2 returned
1015 "Xtestfile", line 11 col 1; this is an error
1016 "Xtestfile", line 12 col 2; this is another error
1017 "Xtestfile", line 14:10; this is an error in column 10
1018 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
1019 "Xtestfile", linenr 16: yet another problem
1020 Error in "Xtestfile" at line 17:
1021 x should be a dot
1022 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1023 ^
1024 Error in "Xtestfile" at line 18:
1025 x should be a dot
1026 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1027 .............^
1028 Error in "Xtestfile" at line 19:
1029 x should be a dot
1030 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1031 --------------^
1032 Error in "Xtestfile" at line 20:
1033 x should be a dot
1034 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1035 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001036
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001037 Does anyone know what is the problem and how to correction it?
1038 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
1039 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1040 [DATA]
1041
1042 call writefile(l, 'Xerrorfile1')
1043 call writefile(l[:-2], 'Xerrorfile2')
1044
1045 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001046 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1047 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1048 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1049 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1050 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1051 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1052 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1053 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1054 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1055 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1056 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1057 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1058 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1059 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1060 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1061 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1062 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1063 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1064 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1065 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1066 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1067[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001068 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001069
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001070 let save_efm = &efm
1071 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1072 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001073
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001074 exe 'cf Xerrorfile2'
1075 clast
1076 copen
1077 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1078 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001079
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001080 exe 'cf Xerrorfile1'
1081 call assert_equal([4, 12], [line('.'), col('.')])
1082 cn
1083 call assert_equal([6, 19], [line('.'), col('.')])
1084 cn
1085 call assert_equal([9, 2], [line('.'), col('.')])
1086 cn
1087 call assert_equal([10, 2], [line('.'), col('.')])
1088 cn
1089 call assert_equal([11, 1], [line('.'), col('.')])
1090 cn
1091 call assert_equal([12, 2], [line('.'), col('.')])
1092 cn
1093 call assert_equal([14, 10], [line('.'), col('.')])
1094 cn
1095 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1096 cn
1097 call assert_equal([16, 2], [line('.'), col('.')])
1098 cn
1099 call assert_equal([17, 6], [line('.'), col('.')])
1100 cn
1101 call assert_equal([18, 7], [line('.'), col('.')])
1102 cn
1103 call assert_equal([19, 8], [line('.'), col('.')])
1104 cn
1105 call assert_equal([20, 9], [line('.'), col('.')])
1106 clast
1107 cprev
1108 cprev
1109 wincmd w
1110 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1111 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001112
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001113 let &efm = save_efm
1114 call delete('Xerrorfile1')
1115 call delete('Xerrorfile2')
1116 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001117endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001118
Bram Moolenaarab47c612016-06-14 22:02:26 +02001119" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001120func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001121 call s:setup_commands(a:cchar)
1122
Bram Moolenaarab47c612016-06-14 22:02:26 +02001123 let save_efm=&efm
1124 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1125
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001126 let lines = ["Entering dir 'dir1/a'",
1127 \ 'habits2.txt:1:Nine Healthy Habits',
1128 \ "Entering dir 'b'",
1129 \ 'habits3.txt:2:0 Hours of television',
1130 \ 'habits2.txt:7:5 Small meals',
1131 \ "Entering dir 'dir1/c'",
1132 \ 'habits4.txt:3:1 Hour of exercise',
1133 \ "Leaving dir 'dir1/c'",
1134 \ "Leaving dir 'dir1/a'",
1135 \ 'habits1.txt:4:2 Liters of water',
1136 \ "Entering dir 'dir2'",
1137 \ 'habits5.txt:5:3 Cups of hot green tea',
1138 \ "Leaving dir 'dir2'"
1139 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001140
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001141 Xexpr ""
1142 for l in lines
1143 Xaddexpr l
1144 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001145
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001146 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001147
1148 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1149 call assert_equal(1, qf[1].lnum)
1150 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1151 call assert_equal(2, qf[3].lnum)
1152 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1153 call assert_equal(7, qf[4].lnum)
1154 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1155 call assert_equal(3, qf[6].lnum)
1156 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1157 call assert_equal(4, qf[9].lnum)
1158 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1159 call assert_equal(5, qf[11].lnum)
1160
1161 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001162endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001163
1164" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001165func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001166 " Create the directory stack and files
1167 call mkdir('dir1')
1168 call mkdir('dir1/a')
1169 call mkdir('dir1/a/b')
1170 call mkdir('dir1/c')
1171 call mkdir('dir2')
1172
1173 let lines = ["Nine Healthy Habits",
1174 \ "0 Hours of television",
1175 \ "1 Hour of exercise",
1176 \ "2 Liters of water",
1177 \ "3 Cups of hot green tea",
1178 \ "4 Short mental breaks",
1179 \ "5 Small meals",
1180 \ "6 AM wake up time",
1181 \ "7 Minutes of laughter",
1182 \ "8 Hours of sleep (at least)",
1183 \ "9 PM end of the day and off to bed"
1184 \ ]
1185 call writefile(lines, 'habits1.txt')
1186 call writefile(lines, 'dir1/a/habits2.txt')
1187 call writefile(lines, 'dir1/a/b/habits3.txt')
1188 call writefile(lines, 'dir1/c/habits4.txt')
1189 call writefile(lines, 'dir2/habits5.txt')
1190
1191 call s:dir_stack_tests('c')
1192 call s:dir_stack_tests('l')
1193
1194 call delete('dir1', 'rf')
1195 call delete('dir2', 'rf')
1196 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001197endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001198
Bram Moolenaar9b457942016-10-09 16:10:05 +02001199" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001200func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001201 call s:setup_commands(a:cchar)
1202
1203 let save_efm = &efm
1204
1205 let &efm =
1206 \ '%Eerror %m %l,' .
1207 \ '%-Wignored %m %l,' .
1208 \ '%+Cmore ignored %m %l,' .
1209 \ '%Zignored end'
1210 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1211 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1212 call assert_equal([['resync', 1, 4, 'E']], l)
1213
1214 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001215endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001216
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001217func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001218 call Xefm_ignore_continuations('c')
1219 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001220endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001221
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001222" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001223func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001224 call s:setup_commands(a:cchar)
1225
Bram Moolenaar049cba92016-06-26 14:38:04 +02001226 let save_efm = &efm
1227
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001228 set efm=%f:%l:%m,%f:%f:%l:%m
1229 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1230
1231 set efm=%f:%l:%m,%f:%l:%r:%m
1232 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1233
1234 set efm=%f:%l:%m,%O:%f:%l:%m
1235 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1236
1237 set efm=%f:%l:%m,%f:%l:%*[^a-z
1238 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1239
1240 set efm=%f:%l:%m,%f:%l:%*c
1241 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1242
1243 set efm=%f:%l:%m,%L%M%N
1244 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1245
1246 set efm=%f:%l:%m,%f:%l:%m:%R
1247 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1248
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001249 " Invalid regular expression
1250 set efm=%\\%%k
1251 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1252
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001253 set efm=
1254 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1255
1256 set efm=%DEntering\ dir\ abc,%f:%l:%m
1257 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1258
1259 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001260endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001261
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001262func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001263 call Xinvalid_efm_Tests('c')
1264 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001265endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001266
1267" TODO:
1268" Add tests for the following formats in 'errorformat'
1269" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001270func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001271 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001272
1273 " Test for %s format in efm
1274 set efm=%f:%s
1275 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001276 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001277 call assert_equal('^\VLine search text\$', l[0].pattern)
1278 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001279
Bram Moolenaaree85df32017-03-19 14:19:50 +01001280 let l = split(execute('clist', ''), "\n")
1281 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1282
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001283 " Test for a long line
1284 cexpr 'Xtestfile:' . repeat('a', 1026)
1285 let l = getqflist()
1286 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1287
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001288 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001289 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001290 [Xtestfile1]
1291 (1,17) error: ';' missing
1292 (21,2) warning: variable 'z' not defined
1293 (67,3) error: end of file found before string ended
1294 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001295
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001296 [Xtestfile2]
1297 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001298
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001299 [Xtestfile3]
1300 NEW compiler v1.1
1301 (2,2) warning: variable 'x' not defined
1302 (67,3) warning: 's' already defined
1303 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001304 [DATA]
1305
Bram Moolenaaree85df32017-03-19 14:19:50 +01001306 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001307 " To exercise the push/pop file functionality in quickfix, the test files
1308 " need to be created.
1309 call writefile(['Line1'], 'Xtestfile1')
1310 call writefile(['Line2'], 'Xtestfile2')
1311 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001312 cexpr ""
1313 for l in lines
1314 caddexpr l
1315 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001316 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001317 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001318 call assert_equal(21, l[2].lnum)
1319 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001320 call assert_equal('w', l[2].type)
1321 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001322 call delete('Xtestfile1')
1323 call delete('Xtestfile2')
1324 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001325
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001326 " Test for %P, %Q with non-existing files
1327 cexpr lines
1328 let l = getqflist()
1329 call assert_equal(14, len(l))
1330 call assert_equal('[Xtestfile1]', l[0].text)
1331 call assert_equal('[Xtestfile2]', l[6].text)
1332 call assert_equal('[Xtestfile3]', l[9].text)
1333
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001334 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001335 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001336 Error 275
1337 line 42
1338 column 3
1339 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001340 [DATA]
1341
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001342 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1343 cgetexpr lines
1344 let l = getqflist()
1345 call assert_equal(275, l[0].nr)
1346 call assert_equal(42, l[0].lnum)
1347 call assert_equal(3, l[0].col)
1348 call assert_equal('E', l[0].type)
1349 call assert_equal("\n' ' expected after '--'", l[0].text)
1350
1351 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001352 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001353 Error in line 147 of foo.c:
1354 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001355 [DATA]
1356
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001357 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1358 cgetexpr lines
1359 let l = getqflist()
1360 call assert_equal(147, l[0].lnum)
1361 call assert_equal('E', l[0].type)
1362 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001363
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001364 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001365 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001366 ==============================================================
1367 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1368 --------------------------------------------------------------
1369 Traceback (most recent call last):
1370 File "unittests/dbfacadeTest.py", line 89, in testFoo
1371 self.assertEquals(34, dtid)
1372 File "/usr/lib/python2.2/unittest.py", line 286, in
1373 failUnlessEqual
1374 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001375 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001376
1377 --------------------------------------------------------------
1378 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001379 [DATA]
1380
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001381 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001382 cgetexpr lines
1383 let l = getqflist()
1384 call assert_equal(8, len(l))
1385 call assert_equal(89, l[4].lnum)
1386 call assert_equal(1, l[4].valid)
1387 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001388 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001389
Bram Moolenaard76ce852018-05-01 15:02:04 +02001390 " Test for %o
1391 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001392 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1393 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001394 let l = getqflist()
1395 call assert_equal(1, len(l), string(l))
1396 call assert_equal('Language.PureScript.Types', l[0].module)
1397 copen
1398 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1399 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001400 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001401 cclose
1402 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001403 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001404
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001405 " Test for a long module name
1406 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1407 let l = getqflist()
1408 call assert_equal(repeat('m', 1024), l[0].module)
1409 call assert_equal(15, l[0].lnum)
1410 call assert_equal('message', l[0].text)
1411
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001412 " The following sequence of commands used to crash Vim
1413 set efm=%W%m
1414 cgetexpr ['msg1']
1415 let l = getqflist()
1416 call assert_equal(1, len(l), string(l))
1417 call assert_equal('msg1', l[0].text)
1418 set efm=%C%m
1419 lexpr 'msg2'
1420 let l = getloclist(0)
1421 call assert_equal(1, len(l), string(l))
1422 call assert_equal('msg2', l[0].text)
1423 lopen
1424 call setqflist([], 'r')
1425 caddbuf
1426 let l = getqflist()
1427 call assert_equal(1, len(l), string(l))
1428 call assert_equal('|| msg2', l[0].text)
1429
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001430 " When matching error lines, case should be ignored. Test for this.
1431 set noignorecase
1432 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1433 call assert_equal(10, l.items[0].lnum)
1434 call assert_equal('Line 20', l.items[0].text)
1435 set ignorecase&
1436
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001437 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001438 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001439endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001440
Bram Moolenaare9283662020-06-07 14:10:47 +02001441" Test for '%t' (error type) field in 'efm'
1442func Test_efm_error_type()
1443 let save_efm = &efm
1444
1445 " error type
1446 set efm=%f:%l:%t:%m
1447 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1448 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1449 let output = split(execute('clist'), "\n")
1450 call assert_equal([
1451 \ ' 1 Xfile1:10 error: msg1',
1452 \ ' 2 Xfile1:20 warning: msg2',
1453 \ ' 3 Xfile1:30 info: msg3',
1454 \ ' 4 Xfile1:40 note: msg4',
1455 \ ' 5 Xfile1:50 R: msg5'], output)
1456
1457 " error type and a error number
1458 set efm=%f:%l:%t:%n:%m
1459 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1460 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1461 let output = split(execute('clist'), "\n")
1462 call assert_equal([
1463 \ ' 1 Xfile1:10 error 2: msg1',
1464 \ ' 2 Xfile1:20 warning 4: msg2',
1465 \ ' 3 Xfile1:30 info 6: msg3',
1466 \ ' 4 Xfile1:40 note 8: msg4',
1467 \ ' 5 Xfile1:50 R 3: msg5'], output)
1468 let &efm = save_efm
1469endfunc
1470
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001471func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001472 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001473 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001474 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001475 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001476 colder
1477 cgetexpr []
1478 endfunc
1479 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001480 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001481 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001482 lolder
1483 lgetexpr []
1484 endfunc
1485 endif
1486
1487 augroup testgroup
1488 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001489 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001490 augroup END
1491
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001492 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001493 let words = [ "a", "b" ]
1494 let qflist = []
1495 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001496 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001497 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001498 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001499 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001500
1501 augroup! testgroup
1502endfunc
1503
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001504func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001505 call XquickfixChangedByAutocmd('c')
1506 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001507endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001508
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001509func Test_setloclist_in_autocommand()
1510 call writefile(['test1', 'test2'], 'Xfile')
1511 edit Xfile
1512 let s:bufnr = bufnr()
1513 call setloclist(1,
1514 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1515 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1516
1517 augroup Test_LocList
1518 au!
1519 autocmd BufEnter * call setloclist(1,
1520 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1521 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1522 augroup END
1523
1524 lopen
1525 call assert_fails('exe "normal j\<CR>"', 'E926:')
1526
1527 augroup Test_LocList
1528 au!
1529 augroup END
1530 call delete('Xfile')
1531endfunc
1532
Bram Moolenaar8b201792016-03-25 15:01:10 +01001533func Test_caddbuffer_to_empty()
1534 helpgr quickfix
1535 call setqflist([], 'r')
1536 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001537 try
1538 cn
1539 catch
1540 " number of matches is unknown
1541 call assert_true(v:exception =~ 'E553:')
1542 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001543 quit!
1544endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001545
1546func Test_cgetexpr_works()
1547 " this must not crash Vim
1548 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001549 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001550endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001551
1552" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001553func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001554 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001555
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001556 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
thinca6864efa2021-06-19 20:45:20 +02001557 \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001558 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001559 call assert_equal(2, len(l))
1560 call assert_equal(2, l[1].lnum)
thinca6864efa2021-06-19 20:45:20 +02001561 call assert_equal(3, l[1].end_lnum)
1562 call assert_equal(4, l[1].col)
1563 call assert_equal(5, l[1].end_col)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001564
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001565 Xnext
1566 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1567 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001568 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001569 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001570 call assert_equal(3, line('.'))
1571
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001572 " Appending entries to the list should not change the cursor position
1573 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001574 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001575 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001576 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001577 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1578 call assert_equal(1, line('.'))
1579 close
1580
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001581 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001582 \ {'bufnr': a:bnum, 'lnum': 4},
1583 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001584 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001585 call assert_equal(3, len(l))
1586 call assert_equal(5, l[2].lnum)
1587
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001588 call g:Xsetlist([])
1589 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001590 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001591
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001592 " Tests for setting the 'valid' flag
1593 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1594 Xwindow
1595 call assert_equal(1, winnr('$'))
1596 let l = g:Xgetlist()
1597 call g:Xsetlist(l)
1598 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001599 " Adding a non-valid entry should not mark the list as having valid entries
1600 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1601 Xwindow
1602 call assert_equal(1, winnr('$'))
1603
1604 " :cnext/:cprev should still work even with invalid entries in the list
1605 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1606 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1607 call g:Xsetlist(l)
1608 Xnext
1609 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1610 Xprev
1611 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1612 " :cnext/:cprev should still work after appending invalid entries to an
1613 " empty list
1614 call g:Xsetlist([])
1615 call g:Xsetlist(l, 'a')
1616 Xnext
1617 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1618 Xprev
1619 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1620
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001621 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1622 Xwindow
1623 call assert_equal(2, winnr('$'))
1624 Xclose
1625 let save_efm = &efm
1626 set efm=%m
1627 Xgetexpr 'TestMessage'
1628 let l = g:Xgetlist()
1629 call g:Xsetlist(l)
1630 call assert_equal(1, g:Xgetlist()[0].valid)
1631 let &efm = save_efm
1632
Bram Moolenaaree85df32017-03-19 14:19:50 +01001633 " Error cases:
1634 " Refer to a non-existing buffer and pass a non-dictionary type
1635 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1636 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1637 call g:Xsetlist([[1, 2,3]])
1638 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001639 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001640endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001641
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001642func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001643 new Xtestfile | only
1644 let bnum = bufnr('%')
1645 call setline(1, range(1,5))
1646
1647 call SetXlistTests('c', bnum)
1648 call SetXlistTests('l', bnum)
1649
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001650 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001651 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001652endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001653
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001654func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001655 call s:setup_commands(a:cchar)
1656
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001657 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001658 let @/ = 'Test_'
1659 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001660 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001661 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001662 Xvimgrep empty test_quickfix.vim
1663 call assert_true(len(g:Xgetlist()) > 0)
1664 Xvimgrep matches test_quickfix.vim
1665 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001666 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001667 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001668 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001669 call g:Xsetlist([], 'r')
1670 call assert_true(len(g:Xgetlist()) == 0)
1671 Xolder
1672 call assert_equal(testlen, len(g:Xgetlist()))
1673 Xnewer
1674 Xnewer
1675 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001676endfunc
1677
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001678func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001679 call Xlist_empty_middle('c')
1680 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001681endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001682
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001683func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001684 call s:setup_commands(a:cchar)
1685
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001686 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001687 Xvimgrep one test_quickfix.vim
1688 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001689 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001690 Xvimgrep two test_quickfix.vim
1691 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001692 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001693 Xvimgrep three test_quickfix.vim
1694 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001695 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001696 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001697 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001698 call g:Xsetlist([], 'r')
1699 call assert_true(len(g:Xgetlist()) == 0)
1700 Xnewer
1701 call assert_equal(twolen, len(g:Xgetlist()))
1702 Xnewer
1703 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001704endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001705
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001706func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001707 call Xlist_empty_older('c')
1708 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001709endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001710
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001711func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001712 call s:setup_commands(a:cchar)
1713
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001714 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1715 \ {'filename': 'fnameB', 'text': 'B'}]
1716 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1717 \ {'filename': 'fnameD', 'text': 'D'},
1718 \ {'filename': 'fnameE', 'text': 'E'}]
1719
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001720 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001721 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001722 silent! Xnewer 99
1723 call g:Xsetlist(list1)
1724 call g:Xsetlist(list2)
1725 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001726 call assert_equal(3, len(li))
1727 call assert_equal('C', li[0]['text'])
1728 call assert_equal('D', li[1]['text'])
1729 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001730 silent! Xolder
1731 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001732 call assert_equal(2, len(li))
1733 call assert_equal('A', li[0]['text'])
1734 call assert_equal('B', li[1]['text'])
1735
1736 " {action} is specified ' '.
1737 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001738 silent! Xnewer 99
1739 call g:Xsetlist(list1)
1740 call g:Xsetlist(list2, ' ')
1741 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001742 call assert_equal(3, len(li))
1743 call assert_equal('C', li[0]['text'])
1744 call assert_equal('D', li[1]['text'])
1745 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001746 silent! Xolder
1747 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001748 call assert_equal(2, len(li))
1749 call assert_equal('A', li[0]['text'])
1750 call assert_equal('B', li[1]['text'])
1751
1752 " {action} is specified 'a'.
1753 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001754 silent! Xnewer 99
1755 call g:Xsetlist(list1)
1756 call g:Xsetlist(list2, 'a')
1757 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001758 call assert_equal(5, len(li))
1759 call assert_equal('A', li[0]['text'])
1760 call assert_equal('B', li[1]['text'])
1761 call assert_equal('C', li[2]['text'])
1762 call assert_equal('D', li[3]['text'])
1763 call assert_equal('E', li[4]['text'])
1764
1765 " {action} is specified 'r'.
1766 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001767 silent! Xnewer 99
1768 call g:Xsetlist(list1)
1769 call g:Xsetlist(list2, 'r')
1770 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001771 call assert_equal(3, len(li))
1772 call assert_equal('C', li[0]['text'])
1773 call assert_equal('D', li[1]['text'])
1774 call assert_equal('E', li[2]['text'])
1775
1776 " Test for wrong value.
1777 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001778 call assert_fails("call g:Xsetlist(0)", 'E714:')
1779 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1780 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1781 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1782 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001783endfunc
1784
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001785func Test_setqflist_invalid_nr()
1786 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001787 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001788endfunc
1789
Bram Moolenaar99234f22020-02-10 22:56:54 +01001790func Test_setqflist_user_sets_buftype()
1791 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1792 set buftype=quickfix
1793 call setqflist([], 'a')
1794 enew
1795endfunc
1796
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001797func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001798 call XquickfixSetListWithAct('c')
1799 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001800endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001801
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001802func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001803 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001804
Bram Moolenaar049cba92016-06-26 14:38:04 +02001805 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001806 call assert_equal(1, l[0].lnum)
1807 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001808 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001809 call assert_equal(2, l[1].lnum)
1810 call assert_equal(1, l[1].col)
1811 call assert_equal(4070, len(l[1].text))
1812 call assert_equal(3, l[2].lnum)
1813 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001814 call assert_equal(4070, len(l[2].text))
1815 call assert_equal(4, l[3].lnum)
1816 call assert_equal(1, l[3].col)
1817 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001818
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001819 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001820endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001821
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001822func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001823 call s:setup_commands(a:cchar)
1824
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001825 let testfile = 'samples/quickfix.txt'
1826
1827 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001828 exe 'Xgetfile' testfile
1829 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001830
1831 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001832 Xexpr readfile(testfile)
1833 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001834
1835 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001836 Xexpr join(readfile(testfile), "\n")
1837 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001838
1839 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001840 exe 'edit' testfile
1841 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001842 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001843endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001844
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001845func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001846 call s:long_lines_tests('c')
1847 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001848endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001849
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001850func Test_cgetfile_on_long_lines()
1851 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1852 " are read at a time.
1853 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1854 let lines = [
1855 \ '/tmp/file1:1:1:aaa',
1856 \ '/tmp/file2:1:1:%s',
1857 \ '/tmp/file3:1:1:bbb',
1858 \ '/tmp/file4:1:1:ccc',
1859 \ ]
1860 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1861 call writefile(lines, 'Xcqetfile.txt')
1862 cgetfile Xcqetfile.txt
1863 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1864 endfor
1865 call delete('Xcqetfile.txt')
1866endfunc
1867
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001868func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001869 let l = []
1870 for i in range(1, 20)
1871 call add(l, 'Line' . i)
1872 endfor
1873 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001874endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001875
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001876func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001877 call s:create_test_file('Xqftestfile1')
1878 call s:create_test_file('Xqftestfile2')
1879 call s:create_test_file('Xqftestfile3')
1880
1881 new | only
1882 edit Xqftestfile1
1883 let file1_winid = win_getid()
1884 new Xqftestfile2
1885 let file2_winid = win_getid()
1886 cgetexpr ['Xqftestfile1:5:Line5',
1887 \ 'Xqftestfile1:6:Line6',
1888 \ 'Xqftestfile2:10:Line10',
1889 \ 'Xqftestfile2:11:Line11',
1890 \ 'Xqftestfile3:15:Line15',
1891 \ 'Xqftestfile3:16:Line16']
1892
1893 new
1894 let winid = win_getid()
1895 cfirst | cnext
1896 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001897 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001898 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001899 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001901
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001902 " Test for 'switchbuf' set to search for files in windows in the current
1903 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001904 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001905 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001906 cfirst | cnext
1907 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001908 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001909 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001910 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001911 call assert_equal(file2_winid, win_getid())
1912
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001913 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1914 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001915 enew | only
1916 set switchbuf=usetab
1917 tabedit Xqftestfile1
1918 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001919 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001920 tabfirst
1921 cfirst | cnext
1922 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001923 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001924 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001925 6cnext
1926 call assert_equal(4, tabpagenr())
1927 2cpfile
1928 call assert_equal(2, tabpagenr())
1929 2cnfile
1930 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001931 tabfirst | tabonly | enew
1932
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001933 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001934 set switchbuf=split
1935 cfirst | cnext
1936 call assert_equal(1, winnr('$'))
1937 cnext | cnext
1938 call assert_equal(2, winnr('$'))
1939 cnext | cnext
1940 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001941
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001942 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001943 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001944 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001945 cfirst | cnext
1946 call assert_equal(1, tabpagenr('$'))
1947 cnext | cnext
1948 call assert_equal(2, tabpagenr('$'))
1949 cnext | cnext
1950 call assert_equal(3, tabpagenr('$'))
1951 tabfirst | enew | tabonly | only
1952
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001953 set switchbuf=uselast
1954 split
1955 let last_winid = win_getid()
1956 copen
1957 exe "normal 1G\<CR>"
1958 call assert_equal(last_winid, win_getid())
1959 enew | only
1960
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001961 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1962 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001963 set switchbuf=
1964 edit Xqftestfile1
1965 let file1_winid = win_getid()
1966 new Xqftestfile2
1967 let file2_winid = win_getid()
1968 copen
1969 exe "normal 1G\<CR>"
1970 call assert_equal(file1_winid, win_getid())
1971 copen
1972 exe "normal 3G\<CR>"
1973 call assert_equal(file2_winid, win_getid())
1974 copen | only
1975 exe "normal 5G\<CR>"
1976 call assert_equal(2, winnr('$'))
1977 call assert_equal(1, bufwinnr('Xqftestfile3'))
1978
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001979 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001980 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001981 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001982 set switchbuf=usetab
1983 tabedit Xqftestfile1
1984 tabedit Xqftestfile2
1985 tabedit Xqftestfile3
1986 tabfirst
1987 copen | only
1988 clast
1989 call assert_equal(4, tabpagenr())
1990 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001991
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001992 " Jumping to a file that is not present in any of the tabpages and the
1993 " current tabpage doesn't have any usable windows, should open it in a new
1994 " window in the current tabpage.
1995 copen | only
1996 cfirst
1997 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001998 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001999
2000 " If opening a file changes 'switchbuf', then the new value should be
2001 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02002002 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002003 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
2004 enew | only
2005 set switchbuf&vim
2006 cexpr "Xqftestfile1:1:10"
2007 call assert_equal('split', &switchbuf)
2008 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
2009 enew | only
2010 set switchbuf=useopen
2011 cexpr "Xqftestfile1:1:10"
2012 call assert_equal('usetab', &switchbuf)
2013 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
2014 enew | only
2015 set switchbuf=useopen
2016 cexpr "Xqftestfile1:1:10"
2017 call assert_equal('', &switchbuf)
2018
Bram Moolenaar049cba92016-06-26 14:38:04 +02002019 call delete('Xqftestfile1')
2020 call delete('Xqftestfile2')
2021 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002022 set switchbuf&vim
2023
2024 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002025endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002026
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002027func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002028 call s:setup_commands(a:cchar)
2029
2030 enew | only
2031
Bram Moolenaarc1542742016-07-20 21:44:37 +02002032 let fname = 'Xqftestfile' . a:cchar
2033 call s:create_test_file(fname)
2034 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02002035
Bram Moolenaarc1542742016-07-20 21:44:37 +02002036 Xgetexpr [fname . ':5:Line5',
2037 \ fname . ':10:Line10',
2038 \ fname . ':15:Line15',
2039 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02002040
2041 6,14delete
2042 call append(6, ['Buffer', 'Window'])
2043
2044 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002045 call assert_equal(5, l[0].lnum)
2046 call assert_equal(6, l[2].lnum)
2047 call assert_equal(13, l[3].lnum)
2048
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002049 " If a file doesn't have any quickfix entries, then deleting lines in the
2050 " file should not update the quickfix list
2051 call g:Xsetlist([], 'f')
2052 1,2delete
2053 call assert_equal([], g:Xgetlist())
2054
Bram Moolenaar049cba92016-06-26 14:38:04 +02002055 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002056 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002057endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002058
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002059func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002060 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002061 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002062 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002063 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002064endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002065
2066" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002067func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002068 call s:setup_commands(a:cchar)
2069
2070 " The following lines are used for the grep test. Don't remove.
2071 " Grep_Test_Text: Match 1
2072 " Grep_Test_Text: Match 2
2073 " GrepAdd_Test_Text: Match 1
2074 " GrepAdd_Test_Text: Match 2
2075 enew! | only
2076 set makeef&vim
2077 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002078 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002079 Xopen
2080 call assert_true(w:quickfix_title =~ '^:grep')
2081 Xclose
2082 enew
2083 set makeef=Temp_File_##
2084 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002085 call assert_true(len(g:Xgetlist()) == 9)
2086
2087 " Try with 'grepprg' set to 'internal'
2088 set grepprg=internal
2089 silent Xgrep Grep_Test_Text: test_quickfix.vim
2090 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2091 call assert_true(len(g:Xgetlist()) == 9)
2092 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002093
2094 call writefile(['Vim'], 'XtestTempFile')
2095 set makeef=XtestTempFile
2096 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002097 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002098 call assert_false(filereadable('XtestTempFile'))
2099 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002100endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002101
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002102func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002103 " The grepprg may not be set on non-Unix systems
2104 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002105
2106 call s:test_xgrep('c')
2107 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002108endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002109
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002110func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002111 " Use one 'errorformat' for two windows. Add an expression to each of them,
2112 " make sure they each keep their own state.
2113 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2114 call mkdir('Xone/a', 'p')
2115 call mkdir('Xtwo/a', 'p')
2116 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2117 call writefile(lines, 'Xone/a/one.txt')
2118 call writefile(lines, 'Xtwo/a/two.txt')
2119
2120 new one
2121 let one_id = win_getid()
2122 lexpr ""
2123 new two
2124 let two_id = win_getid()
2125 lexpr ""
2126
2127 laddexpr "Entering dir 'Xtwo/a'"
2128 call win_gotoid(one_id)
2129 laddexpr "Entering dir 'Xone/a'"
2130 call win_gotoid(two_id)
2131 laddexpr 'two.txt:5:two two two'
2132 call win_gotoid(one_id)
2133 laddexpr 'one.txt:3:one one one'
2134
2135 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002136 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2137 call assert_equal(3, loc_one[1].lnum)
2138
2139 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002140 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2141 call assert_equal(5, loc_two[1].lnum)
2142
2143 call win_gotoid(one_id)
2144 bwipe!
2145 call win_gotoid(two_id)
2146 bwipe!
2147 call delete('Xone', 'rf')
2148 call delete('Xtwo', 'rf')
2149endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002150
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002151func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002152 call s:setup_commands(a:cchar)
2153
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002154 " Calling lbottom without any errors should fail
2155 if a:cchar == 'l'
2156 call assert_fails('lbottom', 'E776:')
2157 endif
2158
Bram Moolenaar875feea2017-06-11 16:07:51 +02002159 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002160 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002161 let wid = win_getid()
2162 call assert_equal(1, line('.'))
2163 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002164 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002165 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002166 call win_gotoid(wid)
2167 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002168 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002169endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002170
2171" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002172func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002173 call XbottomTests('c')
2174 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002175endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002176
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002177func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002178 call s:setup_commands(a:cchar)
2179
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002180 " clear all lists after the first one, then replace the first one.
2181 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002182 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002183 let entry = {'filename': 'foo', 'lnum': 42}
2184 call g:Xsetlist([entry], 'r')
2185 call g:Xsetlist([entry, entry])
2186 call g:Xsetlist([entry, entry, entry])
2187 let res = split(execute(a:cchar . 'hist'), "\n")
2188 call assert_equal(3, len(res))
2189 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2190 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2191 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2192 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002193
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002194 " Test for changing the quickfix lists
2195 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2196 exe '1' . a:cchar . 'hist'
2197 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2198 exe '3' . a:cchar . 'hist'
2199 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2200 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2201 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2202
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002203 call g:Xsetlist([], 'f')
2204 let l = split(execute(a:cchar . 'hist'), "\n")
2205 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002206 if a:cchar == 'c'
2207 call assert_fails('4chist', 'E16:')
2208 else
2209 call assert_fails('4lhist', 'E776:')
2210 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002211
2212 " An empty list should still show the stack history
2213 call g:Xsetlist([])
2214 let res = split(execute(a:cchar . 'hist'), "\n")
2215 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2216
2217 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002218endfunc
2219
2220func Test_history()
2221 call HistoryTest('c')
2222 call HistoryTest('l')
2223endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002224
2225func Test_duplicate_buf()
2226 " make sure we can get the highest buffer number
2227 edit DoesNotExist
2228 edit DoesNotExist2
2229 let last_buffer = bufnr("$")
2230
2231 " make sure only one buffer is created
2232 call writefile(['this one', 'that one'], 'Xgrepthis')
2233 vimgrep one Xgrepthis
2234 vimgrep one Xgrepthis
2235 call assert_equal(last_buffer + 1, bufnr("$"))
2236
2237 call delete('Xgrepthis')
2238endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002239
2240" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002241func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002242 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002243
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002244 " Error cases
2245 call assert_fails('call g:Xgetlist(99)', 'E715:')
2246 call assert_fails('call g:Xsetlist(99)', 'E714:')
2247 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002248
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002249 " Set and get the title
2250 call g:Xsetlist([])
2251 Xopen
2252 wincmd p
2253 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2254 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2255 call assert_equal(0, s)
2256 let d = g:Xgetlist({"title":1})
2257 call assert_equal('Sample', d.title)
2258 " Try setting title to a non-string value
2259 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2260 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2261
2262 Xopen
2263 call assert_equal('Sample', w:quickfix_title)
2264 Xclose
2265
2266 " Tests for action argument
2267 silent! Xolder 999
2268 let qfnr = g:Xgetlist({'all':1}).nr
2269 call g:Xsetlist([], 'r', {'title' : 'N1'})
2270 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2271 call g:Xsetlist([], ' ', {'title' : 'N2'})
2272 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2273
2274 let res = g:Xgetlist({'nr': 0})
2275 call assert_equal(qfnr + 1, res.nr)
2276 call assert_equal(['nr'], keys(res))
2277
2278 call g:Xsetlist([], ' ', {'title' : 'N3'})
2279 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2280
2281 " Changing the title of an earlier quickfix list
2282 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2283 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2284
2285 " Changing the title of an invalid quickfix list
2286 call assert_equal(-1, g:Xsetlist([], ' ',
2287 \ {'title' : 'SomeTitle', 'nr' : 99}))
2288 call assert_equal(-1, g:Xsetlist([], ' ',
2289 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2290
2291 if a:cchar == 'c'
2292 copen
2293 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2294 cclose
2295 endif
2296
2297 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002298 call assert_fails('call g:Xgetlist([])', 'E715:')
2299 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002300 let s = g:Xsetlist([], 'a', {'abc':1})
2301 call assert_equal(-1, s)
2302
2303 call assert_equal({}, g:Xgetlist({'abc':1}))
2304 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2305 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2306
2307 if a:cchar == 'l'
2308 call assert_equal({}, getloclist(99, {'title': 1}))
2309 endif
2310
2311 " Context related tests
2312 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2313 call assert_equal(0, s)
2314 call test_garbagecollect_now()
2315 let d = g:Xgetlist({'context':1})
2316 call assert_equal([1,2,3], d.context)
2317 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2318 let d = g:Xgetlist({'context':1})
2319 call assert_equal({'color':'green'}, d.context)
2320 call g:Xsetlist([], 'a', {'context':"Context info"})
2321 let d = g:Xgetlist({'context':1})
2322 call assert_equal("Context info", d.context)
2323 call g:Xsetlist([], 'a', {'context':246})
2324 let d = g:Xgetlist({'context':1})
2325 call assert_equal(246, d.context)
2326 " set other Vim data types as context
2327 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2328 if has('channel')
2329 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2330 endif
2331 if has('job')
2332 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2333 endif
2334 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2335 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2336 call g:Xsetlist([], 'a', {'context' : ''})
2337 call test_garbagecollect_now()
2338 if a:cchar == 'l'
2339 " Test for copying context across two different location lists
2340 new | only
2341 let w1_id = win_getid()
2342 let l = [1]
2343 call setloclist(0, [], 'a', {'context':l})
2344 new
2345 let w2_id = win_getid()
2346 call add(l, 2)
2347 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2348 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2349 unlet! l
2350 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2351 only
2352 call setloclist(0, [], 'f')
2353 call assert_equal('', getloclist(0, {'context':1}).context)
2354 endif
2355
2356 " Test for changing the context of previous quickfix lists
2357 call g:Xsetlist([], 'f')
2358 Xexpr "One"
2359 Xexpr "Two"
2360 Xexpr "Three"
2361 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2362 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2363 " Also, check for setting the context using quickfix list number zero.
2364 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2365 call test_garbagecollect_now()
2366 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2367 call assert_equal([1], l.context)
2368 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2369 call assert_equal([2], l.context)
2370 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2371 call assert_equal([3], l.context)
2372
2373 " Test for changing the context through reference and for garbage
2374 " collection of quickfix context
2375 let l = ["red"]
2376 call g:Xsetlist([], ' ', {'context' : l})
2377 call add(l, "blue")
2378 let x = g:Xgetlist({'context' : 1})
2379 call add(x.context, "green")
2380 call assert_equal(["red", "blue", "green"], l)
2381 call assert_equal(["red", "blue", "green"], x.context)
2382 unlet l
2383 call test_garbagecollect_now()
2384 let m = g:Xgetlist({'context' : 1})
2385 call assert_equal(["red", "blue", "green"], m.context)
2386
2387 " Test for setting/getting items
2388 Xexpr ""
2389 let qfprev = g:Xgetlist({'nr':0})
2390 let s = g:Xsetlist([], ' ', {'title':'Green',
2391 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2392 call assert_equal(0, s)
2393 let qfcur = g:Xgetlist({'nr':0})
2394 call assert_true(qfcur.nr == qfprev.nr + 1)
2395 let l = g:Xgetlist({'items':1})
2396 call assert_equal('F1', bufname(l.items[0].bufnr))
2397 call assert_equal(10, l.items[0].lnum)
2398 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2399 \ {'filename':'F2', 'lnum':30}]})
2400 let l = g:Xgetlist({'items':1})
2401 call assert_equal('F2', bufname(l.items[2].bufnr))
2402 call assert_equal(30, l.items[2].lnum)
2403 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2404 let l = g:Xgetlist({'items':1})
2405 call assert_equal('F3', bufname(l.items[0].bufnr))
2406 call assert_equal(40, l.items[0].lnum)
2407 call g:Xsetlist([], 'r', {'items' : []})
2408 let l = g:Xgetlist({'items':1})
2409 call assert_equal(0, len(l.items))
2410
2411 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2412 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2413 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2414 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2415
2416 " Test for getting id of window associated with a location list window
2417 if a:cchar == 'l'
2418 only
2419 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2420 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002421 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002422 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2423 wincmd w
2424 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2425 only
2426 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002427
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002428 " The following used to crash Vim with address sanitizer
2429 call g:Xsetlist([], 'f')
2430 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2431 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002432
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002433 " Try setting the items using a string
2434 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002435
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002436 " Save and restore the quickfix stack
2437 call g:Xsetlist([], 'f')
2438 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2439 Xexpr "File1:10:Line1"
2440 Xexpr "File2:20:Line2"
2441 Xexpr "File3:30:Line3"
2442 let last_qf = g:Xgetlist({'nr':'$'}).nr
2443 call assert_equal(3, last_qf)
2444 let qstack = []
2445 for i in range(1, last_qf)
2446 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2447 endfor
2448 call g:Xsetlist([], 'f')
2449 for i in range(len(qstack))
2450 call g:Xsetlist([], ' ', qstack[i])
2451 endfor
2452 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2453 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2454 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2455 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2456 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002457
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002458 " Swap two quickfix lists
2459 Xexpr "File1:10:Line10"
2460 Xexpr "File2:20:Line20"
2461 Xexpr "File3:30:Line30"
2462 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2463 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2464 let l1=g:Xgetlist({'nr':1,'all':1})
2465 let l2=g:Xgetlist({'nr':2,'all':1})
2466 let save_id = l1.id
2467 let l1.id=l2.id
2468 let l2.id=save_id
2469 call g:Xsetlist([], 'r', l1)
2470 call g:Xsetlist([], 'r', l2)
2471 let newl1=g:Xgetlist({'nr':1,'all':1})
2472 let newl2=g:Xgetlist({'nr':2,'all':1})
2473 call assert_equal('Fruits', newl1.title)
2474 call assert_equal(['Fruits'], newl1.context)
2475 call assert_equal('Line20', newl1.items[0].text)
2476 call assert_equal('Colors', newl2.title)
2477 call assert_equal(['Colors'], newl2.context)
2478 call assert_equal('Line10', newl2.items[0].text)
2479 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002480
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002481 " Cannot specify both a non-empty list argument and a dict argument
2482 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002483endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002484
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002485func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002486 call Xproperty_tests('c')
2487 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002488endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002489
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002490" Test for setting the current index in the location/quickfix list
2491func Xtest_setqfidx(cchar)
2492 call s:setup_commands(a:cchar)
2493
2494 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2495 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2496 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2497
2498 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2499 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2500 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2501 Xolder 2
2502 Xopen
2503 call assert_equal(3, line('.'))
2504 Xnewer
2505 call assert_equal(2, line('.'))
2506 Xnewer
2507 call assert_equal(2, line('.'))
2508 " Update the current index with the quickfix window open
2509 wincmd w
2510 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2511 Xopen
2512 call assert_equal(3, line('.'))
2513 Xclose
2514
2515 " Set the current index to the last entry
2516 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2517 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2518 " A large value should set the index to the last index
2519 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2520 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2521 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2522 " Invalid index values
2523 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2524 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2525 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2526 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2527 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2528 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2529 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2530
2531 call g:Xsetlist([], 'f')
2532 new | only
2533endfunc
2534
2535func Test_setqfidx()
2536 call Xtest_setqfidx('c')
2537 call Xtest_setqfidx('l')
2538endfunc
2539
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002540" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002541func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002542 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002543endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002544
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002545func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002546 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2547 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2548
2549 let g:acmds = []
2550 cexpr "F1:10:Line 10"
2551 caddexpr "F1:20:Line 20"
2552 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002553 cexpr ""
2554 caddexpr ""
2555 cgetexpr ""
2556 silent! cexpr non_existing_func()
2557 silent! caddexpr non_existing_func()
2558 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002559 let l = ['precexpr',
2560 \ 'postcexpr',
2561 \ 'precaddexpr',
2562 \ 'postcaddexpr',
2563 \ 'precgetexpr',
2564 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002565 \ 'precexpr',
2566 \ 'postcexpr',
2567 \ 'precaddexpr',
2568 \ 'postcaddexpr',
2569 \ 'precgetexpr',
2570 \ 'postcgetexpr',
2571 \ 'precexpr',
2572 \ 'precaddexpr',
2573 \ 'precgetexpr']
2574 call assert_equal(l, g:acmds)
2575
2576 let g:acmds = []
2577 enew! | call append(0, "F2:10:Line 10")
2578 cbuffer!
2579 enew! | call append(0, "F2:20:Line 20")
2580 cgetbuffer
2581 enew! | call append(0, "F2:30:Line 30")
2582 caddbuffer
2583 new
2584 let bnum = bufnr('%')
2585 bunload
2586 exe 'silent! cbuffer! ' . bnum
2587 exe 'silent! cgetbuffer ' . bnum
2588 exe 'silent! caddbuffer ' . bnum
2589 enew!
2590 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002591 \ 'postcbuffer',
2592 \ 'precgetbuffer',
2593 \ 'postcgetbuffer',
2594 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002595 \ 'postcaddbuffer',
2596 \ 'precbuffer',
2597 \ 'precgetbuffer',
2598 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002599 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002600
2601 call writefile(['Xtest:1:Line1'], 'Xtest')
2602 call writefile([], 'Xempty')
2603 let g:acmds = []
2604 cfile Xtest
2605 caddfile Xtest
2606 cgetfile Xtest
2607 cfile Xempty
2608 caddfile Xempty
2609 cgetfile Xempty
2610 silent! cfile do_not_exist
2611 silent! caddfile do_not_exist
2612 silent! cgetfile do_not_exist
2613 let l = ['precfile',
2614 \ 'postcfile',
2615 \ 'precaddfile',
2616 \ 'postcaddfile',
2617 \ 'precgetfile',
2618 \ 'postcgetfile',
2619 \ 'precfile',
2620 \ 'postcfile',
2621 \ 'precaddfile',
2622 \ 'postcaddfile',
2623 \ 'precgetfile',
2624 \ 'postcgetfile',
2625 \ 'precfile',
2626 \ 'postcfile',
2627 \ 'precaddfile',
2628 \ 'postcaddfile',
2629 \ 'precgetfile',
2630 \ 'postcgetfile']
2631 call assert_equal(l, g:acmds)
2632
2633 let g:acmds = []
2634 helpgrep quickfix
2635 silent! helpgrep non_existing_help_topic
2636 vimgrep test Xtest
2637 vimgrepadd test Xtest
2638 silent! vimgrep non_existing_test Xtest
2639 silent! vimgrepadd non_existing_test Xtest
2640 set makeprg=
2641 silent! make
2642 set makeprg&
2643 let l = ['prehelpgrep',
2644 \ 'posthelpgrep',
2645 \ 'prehelpgrep',
2646 \ 'posthelpgrep',
2647 \ 'previmgrep',
2648 \ 'postvimgrep',
2649 \ 'previmgrepadd',
2650 \ 'postvimgrepadd',
2651 \ 'previmgrep',
2652 \ 'postvimgrep',
2653 \ 'previmgrepadd',
2654 \ 'postvimgrepadd',
2655 \ 'premake',
2656 \ 'postmake']
2657 call assert_equal(l, g:acmds)
2658
2659 if has('unix')
2660 " Run this test only on Unix-like systems. The grepprg may not be set on
2661 " non-Unix systems.
2662 " The following lines are used for the grep test. Don't remove.
2663 " Grep_Autocmd_Text: Match 1
2664 " GrepAdd_Autocmd_Text: Match 2
2665 let g:acmds = []
2666 silent grep Grep_Autocmd_Text test_quickfix.vim
2667 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2668 silent grep abc123def Xtest
2669 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002670 set grepprg=internal
2671 silent grep Grep_Autocmd_Text test_quickfix.vim
2672 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2673 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2674 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2675 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002676 let l = ['pregrep',
2677 \ 'postgrep',
2678 \ 'pregrepadd',
2679 \ 'postgrepadd',
2680 \ 'pregrep',
2681 \ 'postgrep',
2682 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002683 \ 'postgrepadd',
2684 \ 'pregrep',
2685 \ 'postgrep',
2686 \ 'pregrepadd',
2687 \ 'postgrepadd',
2688 \ 'prelgrep',
2689 \ 'postlgrep',
2690 \ 'prelgrepadd',
2691 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002692 call assert_equal(l, g:acmds)
2693 endif
2694
2695 call delete('Xtest')
2696 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002697 au! QuickFixCmdPre
2698 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002699endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002700
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002701func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002702 set efm=%m
2703 lgetexpr '?'
2704
2705 try
2706 call DoesNotExit()
2707 catch
2708 lgetexpr '1'
2709 finally
2710 lgetexpr '1'
2711 endtry
2712
2713 call assert_equal('1', getloclist(0)[0].text)
2714
2715 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002716endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002717
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002718func Test_caddbuffer_wrong()
2719 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002720 let save_efm = &efm
2721 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2722 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2723 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002724 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002725 bwipe!
2726endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002727
2728func Test_caddexpr_wrong()
2729 " This used to cause a memory access in freed memory.
2730 cbuffer
2731 cbuffer
2732 copen
2733 let save_efm = &efm
2734 set efm=%
2735 call assert_fails('caddexpr ""', 'E376:')
2736 let &efm = save_efm
2737endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002738
2739func Test_dirstack_cleanup()
2740 " This used to cause a memory access in freed memory.
2741 let save_efm = &efm
2742 lexpr '0'
2743 lopen
2744 fun X(c)
2745 let save_efm=&efm
2746 set efm=%D%f
2747 if a:c == 'c'
2748 caddexpr '::'
2749 else
2750 laddexpr ':0:0'
2751 endif
2752 let &efm=save_efm
2753 endfun
2754 call X('c')
2755 call X('l')
2756 call setqflist([], 'r')
2757 caddbuffer
2758 let &efm = save_efm
2759endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002760
2761" Tests for jumping to entries from the location list window and quickfix
2762" window
2763func Test_cwindow_jump()
2764 set efm=%f%%%l%%%m
2765 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2766 lopen | only
2767 lfirst
2768 call assert_true(winnr('$') == 2)
2769 call assert_true(winnr() == 1)
2770 " Location list for the new window should be set
2771 call assert_true(getloclist(0)[2].text == 'Line 30')
2772
2773 " Open a scratch buffer
2774 " Open a new window and create a location list
2775 " Open the location list window and close the other window
2776 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002777 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002778 " should not be used.
2779 enew | only
2780 set buftype=nofile
2781 below new
2782 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2783 lopen
2784 2wincmd c
2785 lnext
2786 call assert_true(winnr('$') == 3)
2787 call assert_true(winnr() == 2)
2788
2789 " Open two windows with two different location lists
2790 " Open the location list window and close the previous window
2791 " Jump to an entry in the location list window
2792 " Should open the file in the first window and not set the location list.
2793 enew | only
2794 lgetexpr ["F1%5%Line 5"]
2795 below new
2796 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2797 lopen
2798 2wincmd c
2799 lnext
2800 call assert_true(winnr() == 1)
2801 call assert_true(getloclist(0)[0].text == 'Line 5')
2802
2803 enew | only
2804 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2805 copen
2806 cnext
2807 call assert_true(winnr('$') == 2)
2808 call assert_true(winnr() == 1)
2809
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002810 " open the quickfix buffer in two windows and jump to an entry. Should open
2811 " the file in the first quickfix window.
2812 enew | only
2813 copen
2814 let bnum = bufnr('')
2815 exe 'sbuffer ' . bnum
2816 wincmd b
2817 cfirst
2818 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002819 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002820 enew | only
2821 exe 'sb' bnum
2822 exe 'botright sb' bnum
2823 wincmd t
2824 clast
2825 call assert_equal(2, winnr())
2826 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2827 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2828
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002829 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002830 " window by wrapping around the window list.
2831 enew | only
2832 call setloclist(0, [], 'f')
2833 new | new
2834 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2835 lopen
2836 1close
2837 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2838 lnext
2839 call assert_equal(3, winnr())
2840 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2841
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002842 enew | only
2843 set efm&vim
2844endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002845
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002846func Test_cwindow_highlight()
2847 CheckScreendump
2848
2849 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002850 call setline(1, ['some', 'text', 'with', 'matches'])
2851 write XCwindow
2852 vimgrep e XCwindow
2853 redraw
2854 cwindow 4
2855 END
2856 call writefile(lines, 'XtestCwindow')
2857 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2858 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2859
2860 call term_sendkeys(buf, ":cnext\<CR>")
2861 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2862
2863 " clean up
2864 call StopVimInTerminal(buf)
2865 call delete('XtestCwindow')
2866 call delete('XCwindow')
2867endfunc
2868
Bram Moolenaaree85df32017-03-19 14:19:50 +01002869func XvimgrepTests(cchar)
2870 call s:setup_commands(a:cchar)
2871
2872 call writefile(['Editor:VIM vim',
2873 \ 'Editor:Emacs EmAcS',
2874 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
Dominique Pelle923dce22021-11-21 11:36:04 +00002875 call writefile(['Linux', 'macOS', 'MS-Windows'], 'Xtestfile2')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002876
2877 " Error cases
2878 call assert_fails('Xvimgrep /abc *', 'E682:')
2879
2880 let @/=''
2881 call assert_fails('Xvimgrep // *', 'E35:')
2882
2883 call assert_fails('Xvimgrep abc', 'E683:')
2884 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2885 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2886
2887 Xexpr ""
2888 Xvimgrepadd Notepad Xtestfile1
Dominique Pelle923dce22021-11-21 11:36:04 +00002889 Xvimgrepadd macOS Xtestfile2
Bram Moolenaaree85df32017-03-19 14:19:50 +01002890 let l = g:Xgetlist()
2891 call assert_equal(2, len(l))
2892 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2893
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002894 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002895 let l = g:Xgetlist()
2896 call assert_equal(2, len(l))
2897 call assert_equal(8, l[0].col)
thinca6864efa2021-06-19 20:45:20 +02002898 call assert_equal(11, l[0].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002899 call assert_equal(12, l[1].col)
thinca6864efa2021-06-19 20:45:20 +02002900 call assert_equal(15, l[1].end_col)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002901
2902 1Xvimgrep ?Editor? Xtestfile*
2903 let l = g:Xgetlist()
2904 call assert_equal(1, len(l))
2905 call assert_equal('Editor:VIM vim', l[0].text)
2906
2907 edit +3 Xtestfile2
2908 Xvimgrep +\cemacs+j Xtestfile1
2909 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002910 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002911 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2912
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002913 " Test for unloading a buffer after vimgrep searched the buffer
2914 %bwipe
2915 Xvimgrep /Editor/j Xtestfile*
2916 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2917 call assert_equal([], getbufinfo('Xtestfile2'))
2918
Bram Moolenaaree85df32017-03-19 14:19:50 +01002919 call delete('Xtestfile1')
2920 call delete('Xtestfile2')
2921endfunc
2922
2923" Tests for the :vimgrep command
2924func Test_vimgrep()
2925 call XvimgrepTests('c')
2926 call XvimgrepTests('l')
2927endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002928
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002929func Test_vimgrep_wildcards_expanded_once()
2930 new X[id-01] file.txt
2931 call setline(1, 'some text to search for')
2932 vimgrep text %
2933 bwipe!
2934endfunc
2935
Bram Moolenaar1c299432018-10-28 14:36:09 +01002936" Test for incsearch highlighting of the :vimgrep pattern
2937" This test used to cause "E315: ml_get: invalid lnum" errors.
2938func Test_vimgrep_incsearch()
2939 enew
2940 set incsearch
2941 call test_override("char_avail", 1)
2942
2943 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2944 let l = getqflist()
2945 call assert_equal(2, len(l))
2946
2947 call test_override("ALL", 0)
2948 set noincsearch
2949endfunc
2950
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002951" Test vimgrep with the last search pattern not set
2952func Test_vimgrep_with_no_last_search_pat()
2953 let lines =<< trim [SCRIPT]
2954 call assert_fails('vimgrep // *', 'E35:')
2955 call writefile(v:errors, 'Xresult')
2956 qall!
2957 [SCRIPT]
2958 call writefile(lines, 'Xscript')
2959 if RunVim([], [], '--clean -S Xscript')
2960 call assert_equal([], readfile('Xresult'))
2961 endif
2962 call delete('Xscript')
2963 call delete('Xresult')
2964endfunc
2965
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002966" Test vimgrep without swap file
2967func Test_vimgrep_without_swap_file()
2968 let lines =<< trim [SCRIPT]
2969 vimgrep grep test_c*
2970 call writefile(['done'], 'Xresult')
2971 qall!
2972 [SCRIPT]
2973 call writefile(lines, 'Xscript')
2974 if RunVim([], [], '--clean -n -S Xscript Xscript')
2975 call assert_equal(['done'], readfile('Xresult'))
2976 endif
2977 call delete('Xscript')
2978 call delete('Xresult')
2979endfunc
2980
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002981func Test_vimgrep_existing_swapfile()
2982 call writefile(['match apple with apple'], 'Xapple')
2983 call writefile(['swapfile'], '.Xapple.swp')
2984 let g:foundSwap = 0
2985 let g:ignoreSwapExists = 1
2986 augroup grep
2987 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2988 augroup END
2989 vimgrep apple Xapple
2990 call assert_equal(1, g:foundSwap)
2991 call assert_match('.Xapple.swo', swapname(''))
2992
2993 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002994 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002995 augroup grep
2996 au! SwapExists
2997 augroup END
2998 unlet g:ignoreSwapExists
2999endfunc
3000
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003001func XfreeTests(cchar)
3002 call s:setup_commands(a:cchar)
3003
3004 enew | only
3005
3006 " Deleting the quickfix stack should work even When the current list is
3007 " somewhere in the middle of the stack
3008 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3009 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3010 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3011 Xolder
3012 call g:Xsetlist([], 'f')
3013 call assert_equal(0, len(g:Xgetlist()))
3014
3015 " After deleting the stack, adding a new list should create a stack with a
3016 " single list.
3017 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3018 call assert_equal(1, g:Xgetlist({'all':1}).nr)
3019
3020 " Deleting the stack from a quickfix window should update/clear the
3021 " quickfix/location list window.
3022 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3023 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3024 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3025 Xolder
3026 Xwindow
3027 call g:Xsetlist([], 'f')
3028 call assert_equal(2, winnr('$'))
3029 call assert_equal(1, line('$'))
3030 Xclose
3031
3032 " Deleting the stack from a non-quickfix window should update/clear the
3033 " quickfix/location list window.
3034 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3035 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
3036 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
3037 Xolder
3038 Xwindow
3039 wincmd p
3040 call g:Xsetlist([], 'f')
3041 call assert_equal(0, len(g:Xgetlist()))
3042 wincmd p
3043 call assert_equal(2, winnr('$'))
3044 call assert_equal(1, line('$'))
3045
3046 " After deleting the location list stack, if the location list window is
3047 " opened, then a new location list should be created. So opening the
3048 " location list window again should not create a new window.
3049 if a:cchar == 'l'
3050 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3051 wincmd p
3052 lopen
3053 call assert_equal(2, winnr('$'))
3054 endif
3055 Xclose
3056endfunc
3057
Bram Moolenaar74240d32017-12-10 15:26:15 +01003058" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003059func Test_qf_free()
3060 call XfreeTests('c')
3061 call XfreeTests('l')
3062endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003063
3064" Test for buffer overflow when parsing lines and adding new entries to
3065" the quickfix list.
3066func Test_bufoverflow()
3067 set efm=%f:%l:%m
3068 cgetexpr ['File1:100:' . repeat('x', 1025)]
3069
3070 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3071 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3072
3073 set efm=%DEntering\ directory\ %f,%f:%l:%m
3074 cgetexpr ['Entering directory ' . repeat('a', 1006),
3075 \ 'File1:10:Hello World']
3076 set efm&vim
3077endfunc
3078
Bram Moolenaar875feea2017-06-11 16:07:51 +02003079" Tests for getting the quickfix stack size
3080func XsizeTests(cchar)
3081 call s:setup_commands(a:cchar)
3082
3083 call g:Xsetlist([], 'f')
3084 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003085 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3086 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003087
3088 Xexpr "File1:10:Line1"
3089 Xexpr "File2:20:Line2"
3090 Xexpr "File3:30:Line3"
3091 Xolder | Xolder
3092 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3093 call g:Xsetlist([], 'f')
3094
3095 Xexpr "File1:10:Line1"
3096 Xexpr "File2:20:Line2"
3097 Xexpr "File3:30:Line3"
3098 Xolder | Xolder
3099 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3100 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3101endfunc
3102
3103func Test_Qf_Size()
3104 call XsizeTests('c')
3105 call XsizeTests('l')
3106endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003107
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003108func Test_cclose_from_copen()
3109 augroup QF_Test
3110 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003111 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003112 augroup END
3113 copen
3114 augroup QF_Test
3115 au!
3116 augroup END
3117 augroup! QF_Test
3118endfunc
3119
Bram Moolenaar18141832017-06-25 21:17:25 +02003120func Test_cclose_in_autocmd()
3121 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3122 " event will be triggered.
3123 call test_override('starting', 1)
3124 augroup QF_Test
3125 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003126 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003127 augroup END
3128 copen
3129 augroup QF_Test
3130 au!
3131 augroup END
3132 augroup! QF_Test
3133 call test_override('starting', 0)
3134endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003135
Bram Moolenaar379fb762018-08-30 15:58:28 +02003136" Check that ":file" without an argument is possible even when "curbuf_lock"
3137" is set.
3138func Test_file_from_copen()
3139 " Works without argument.
3140 augroup QF_Test
3141 au!
3142 au FileType qf file
3143 augroup END
3144 copen
3145
3146 augroup QF_Test
3147 au!
3148 augroup END
3149 cclose
3150
3151 " Fails with argument.
3152 augroup QF_Test
3153 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003154 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003155 augroup END
3156 copen
3157 augroup QF_Test
3158 au!
3159 augroup END
3160 cclose
3161
3162 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003163endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003164
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003165func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003166 augroup QF_Test
3167 au!
3168 au FileType qf resize 5
3169 augroup END
3170 try
3171 " This should succeed without any exception. No other buffers are
3172 " involved in the autocmd.
3173 copen
3174 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003175 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003176 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003177 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003178 augroup! QF_Test
3179 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003180endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003181
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003182func Test_vimgrep_with_textlock()
3183 new
3184
3185 " Simple way to execute something with "textwinlock" set.
3186 " Check that vimgrep without jumping can be executed.
3187 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3188 normal ax
3189 let qflist = getqflist()
3190 call assert_true(len(qflist) > 0)
3191 call assert_match('RunTheTest', qflist[0].text)
3192 call setqflist([], 'r')
3193 au! InsertCharPre
3194
3195 " Check that vimgrepadd without jumping can be executed.
3196 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3197 normal ax
3198 let qflist = getqflist()
3199 call assert_true(len(qflist) > 0)
3200 call assert_match('RunTheTest', qflist[0].text)
3201 call setqflist([], 'r')
3202 au! InsertCharPre
3203
3204 " Check that lvimgrep without jumping can be executed.
3205 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3206 normal ax
3207 let qflist = getloclist(0)
3208 call assert_true(len(qflist) > 0)
3209 call assert_match('RunTheTest', qflist[0].text)
3210 call setloclist(0, [], 'r')
3211 au! InsertCharPre
3212
3213 " Check that lvimgrepadd without jumping can be executed.
3214 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3215 normal ax
3216 let qflist = getloclist(0)
3217 call assert_true(len(qflist) > 0)
3218 call assert_match('RunTheTest', qflist[0].text)
3219 call setloclist(0, [], 'r')
3220 au! InsertCharPre
3221
3222 " trying to jump will give an error
3223 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3224 call assert_fails('normal ax', 'E565:')
3225 au! InsertCharPre
3226
3227 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3228 call assert_fails('normal ax', 'E565:')
3229 au! InsertCharPre
3230
3231 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3232 call assert_fails('normal ax', 'E565:')
3233 au! InsertCharPre
3234
3235 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3236 call assert_fails('normal ax', 'E565:')
3237 au! InsertCharPre
3238
3239 bwipe!
3240endfunc
3241
Bram Moolenaara8788f42017-07-19 17:06:20 +02003242" Tests for the quickfix buffer b:changedtick variable
3243func Xchangedtick_tests(cchar)
3244 call s:setup_commands(a:cchar)
3245
3246 new | only
3247
3248 Xexpr "" | Xexpr "" | Xexpr ""
3249
3250 Xopen
3251 Xolder
3252 Xolder
3253 Xaddexpr "F1:10:Line10"
3254 Xaddexpr "F2:20:Line20"
3255 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3256 call g:Xsetlist([], 'f')
3257 call assert_equal(8, getbufvar('%', 'changedtick'))
3258 Xclose
3259endfunc
3260
3261func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003262 call Xchangedtick_tests('c')
3263 call Xchangedtick_tests('l')
3264endfunc
3265
3266" Tests for parsing an expression using setqflist()
3267func Xsetexpr_tests(cchar)
3268 call s:setup_commands(a:cchar)
3269
3270 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003271 call g:Xsetlist([], ' ', {'lines' : t})
3272 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003273
3274 let l = g:Xgetlist()
3275 call assert_equal(3, len(l))
3276 call assert_equal(20, l[1].lnum)
3277 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003278 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003279 let l = g:Xgetlist()
3280 call assert_equal(1, len(l))
3281 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003282 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3283 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003284
3285 call g:Xsetlist([], 'f')
3286 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003287 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3288 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3289 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3290 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003291 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3292 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003293
3294 " Adding entries using a custom efm
3295 set efm&
3296 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3297 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3298 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3299 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3300 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3301 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3302 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3303 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003304endfunc
3305
3306func Test_setexpr()
3307 call Xsetexpr_tests('c')
3308 call Xsetexpr_tests('l')
3309endfunc
3310
3311" Tests for per quickfix/location list directory stack
3312func Xmultidirstack_tests(cchar)
3313 call s:setup_commands(a:cchar)
3314
3315 call g:Xsetlist([], 'f')
3316 Xexpr "" | Xexpr ""
3317
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003318 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3319 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3320 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3321 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003322
3323 let l1 = g:Xgetlist({'nr':1, 'items':1})
3324 let l2 = g:Xgetlist({'nr':2, 'items':1})
3325 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3326 call assert_equal(3, l1.items[1].lnum)
3327 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3328 call assert_equal(5, l2.items[1].lnum)
3329endfunc
3330
3331func Test_multidirstack()
3332 call mkdir('Xone/a', 'p')
3333 call mkdir('Xtwo/a', 'p')
3334 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3335 call writefile(lines, 'Xone/a/one.txt')
3336 call writefile(lines, 'Xtwo/a/two.txt')
3337 let save_efm = &efm
3338 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3339
3340 call Xmultidirstack_tests('c')
3341 call Xmultidirstack_tests('l')
3342
3343 let &efm = save_efm
3344 call delete('Xone', 'rf')
3345 call delete('Xtwo', 'rf')
3346endfunc
3347
3348" Tests for per quickfix/location list file stack
3349func Xmultifilestack_tests(cchar)
3350 call s:setup_commands(a:cchar)
3351
3352 call g:Xsetlist([], 'f')
3353 Xexpr "" | Xexpr ""
3354
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003355 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3356 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3357 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3358 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003359
3360 let l1 = g:Xgetlist({'nr':1, 'items':1})
3361 let l2 = g:Xgetlist({'nr':2, 'items':1})
3362 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3363 call assert_equal(3, l1.items[1].lnum)
3364 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3365 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003366
3367 " Test for start of a new error line in the same line where a previous
3368 " error line ends with a file stack.
3369 let efm_val = 'Error\ l%l\ in\ %f,'
3370 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3371 let l = g:Xgetlist({'lines' : [
3372 \ '(one.txt',
3373 \ 'Error l4 in one.txt',
3374 \ ') (two.txt',
3375 \ 'Error l6 in two.txt',
3376 \ ')',
3377 \ 'Error l8 in one.txt'
3378 \ ], 'efm' : efm_val})
3379 call assert_equal(3, len(l.items))
3380 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3381 call assert_equal(4, l.items[0].lnum)
3382 call assert_equal('one.txt', l.items[0].text)
3383 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3384 call assert_equal(6, l.items[1].lnum)
3385 call assert_equal('two.txt', l.items[1].text)
3386 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3387 call assert_equal(8, l.items[2].lnum)
3388 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003389endfunc
3390
3391func Test_multifilestack()
3392 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3393 call writefile(lines, 'one.txt')
3394 call writefile(lines, 'two.txt')
3395 let save_efm = &efm
3396 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3397
3398 call Xmultifilestack_tests('c')
3399 call Xmultifilestack_tests('l')
3400
3401 let &efm = save_efm
3402 call delete('one.txt')
3403 call delete('two.txt')
3404endfunc
3405
3406" Tests for per buffer 'efm' setting
3407func Test_perbuf_efm()
3408 call writefile(["File1-10-Line10"], 'one.txt')
3409 call writefile(["File2#20#Line20"], 'two.txt')
3410 set efm=%f#%l#%m
3411 new | only
3412 new
3413 setlocal efm=%f-%l-%m
3414 cfile one.txt
3415 wincmd w
3416 caddfile two.txt
3417
3418 let l = getqflist()
3419 call assert_equal(10, l[0].lnum)
3420 call assert_equal('Line20', l[1].text)
3421
3422 set efm&
3423 new | only
3424 call delete('one.txt')
3425 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003426endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003427
3428" Open multiple help windows using ":lhelpgrep
3429" This test used to crash Vim
3430func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003431 new | only
3432 lhelpgrep window
3433 lopen
3434 e#
3435 lhelpgrep buffer
3436 call assert_equal(3, winnr('$'))
3437 call assert_true(len(getloclist(1)) != 0)
3438 call assert_true(len(getloclist(2)) != 0)
3439 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003440endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003441
3442" Tests for adding new quickfix lists using setqflist()
3443func XaddQf_tests(cchar)
3444 call s:setup_commands(a:cchar)
3445
3446 " Create a new list using ' ' for action
3447 call g:Xsetlist([], 'f')
3448 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3449 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3450 call assert_equal(1, l.nr)
3451 call assert_equal('Test1', l.title)
3452
3453 " Create a new list using ' ' for action and '$' for 'nr'
3454 call g:Xsetlist([], 'f')
3455 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3456 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3457 call assert_equal(1, l.nr)
3458 call assert_equal('Test2', l.title)
3459
3460 " Create a new list using 'a' for action
3461 call g:Xsetlist([], 'f')
3462 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3463 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3464 call assert_equal(1, l.nr)
3465 call assert_equal('Test3', l.title)
3466
3467 " Create a new list using 'a' for action and '$' for 'nr'
3468 call g:Xsetlist([], 'f')
3469 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3470 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3471 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3472 call assert_equal(1, l.nr)
3473 call assert_equal('Test4', l.title)
3474
3475 " Adding a quickfix list should remove all the lists following the current
3476 " list.
3477 Xexpr "" | Xexpr "" | Xexpr ""
3478 silent! 10Xolder
3479 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3480 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3481 call assert_equal(2, l.nr)
3482 call assert_equal('Test5', l.title)
3483
3484 " Add a quickfix list using '$' as the list number.
3485 let lastqf = g:Xgetlist({'nr':'$'}).nr
3486 silent! 99Xolder
3487 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3488 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3489 call assert_equal(lastqf + 1, l.nr)
3490 call assert_equal('Test6', l.title)
3491
3492 " Add a quickfix list using 'nr' set to one more than the quickfix
3493 " list size.
3494 let lastqf = g:Xgetlist({'nr':'$'}).nr
3495 silent! 99Xolder
3496 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3497 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3498 call assert_equal(lastqf + 1, l.nr)
3499 call assert_equal('Test7', l.title)
3500
3501 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3502 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3503 silent! 99Xolder
3504 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3505 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3506 call assert_equal(10, l.nr)
3507 call assert_equal('Test8', l.title)
3508
3509 " Add a quickfix list using 'nr' set to a value greater than 10
3510 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3511
3512 " Try adding a quickfix list with 'nr' set to a value greater than the
3513 " quickfix list size but less than 10.
3514 call g:Xsetlist([], 'f')
3515 Xexpr "" | Xexpr "" | Xexpr ""
3516 silent! 99Xolder
3517 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3518
3519 " Add a quickfix list using 'nr' set to a some string or list
3520 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3521endfunc
3522
3523func Test_add_qf()
3524 call XaddQf_tests('c')
3525 call XaddQf_tests('l')
3526endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003527
3528" Test for getting the quickfix list items from some text without modifying
3529" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003530func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003531 call s:setup_commands(a:cchar)
3532 call g:Xsetlist([], 'f')
3533
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003534 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003535 call assert_equal(2, len(l))
3536 call assert_equal(30, l[1].lnum)
3537
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003538 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3539 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3540 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3541 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003542
Bram Moolenaar36538222017-09-02 19:51:44 +02003543 " Parse text using a custom efm
3544 set efm&
3545 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3546 call assert_equal('Line30', l[0].text)
3547 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3548 call assert_equal('File3:30:Line30', l[0].text)
3549 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3550 call assert_equal({}, l)
3551 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3552 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3553
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003554 " Make sure that the quickfix stack is not modified
3555 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3556endfunc
3557
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003558func Test_get_list_from_lines()
3559 call XgetListFromLines('c')
3560 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003561endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003562
3563" Tests for the quickfix list id
3564func Xqfid_tests(cchar)
3565 call s:setup_commands(a:cchar)
3566
3567 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003568 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003569 Xexpr ''
3570 let start_id = g:Xgetlist({'id' : 0}).id
3571 Xexpr '' | Xexpr ''
3572 Xolder
3573 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3574 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3575 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003576 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003577 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003578 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3579 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003580
3581 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3582 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003583 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003584 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3585 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3586 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3587
3588 let qfid = g:Xgetlist({'id':0, 'nr':0})
3589 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003590 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003591endfunc
3592
3593func Test_qf_id()
3594 call Xqfid_tests('c')
3595 call Xqfid_tests('l')
3596endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003597
3598func Xqfjump_tests(cchar)
3599 call s:setup_commands(a:cchar)
3600
3601 call writefile(["Line1\tFoo", "Line2"], 'F1')
3602 call writefile(["Line1\tBar", "Line2"], 'F2')
3603 call writefile(["Line1\tBaz", "Line2"], 'F3')
3604
3605 call g:Xsetlist([], 'f')
3606
3607 " Tests for
3608 " Jumping to a line using a pattern
3609 " Jumping to a column greater than the last column in a line
3610 " Jumping to a line greater than the last line in the file
3611 let l = []
3612 for i in range(1, 7)
3613 call add(l, {})
3614 endfor
3615 let l[0].filename='F1'
3616 let l[0].pattern='Line1'
3617 let l[1].filename='F2'
3618 let l[1].pattern='Line1'
3619 let l[2].filename='F3'
3620 let l[2].pattern='Line1'
3621 let l[3].filename='F3'
3622 let l[3].lnum=1
3623 let l[3].col=9
3624 let l[3].vcol=1
3625 let l[4].filename='F3'
3626 let l[4].lnum=99
3627 let l[5].filename='F3'
3628 let l[5].lnum=1
3629 let l[5].col=99
3630 let l[5].vcol=1
3631 let l[6].filename='F3'
3632 let l[6].pattern='abcxyz'
3633
3634 call g:Xsetlist([], ' ', {'items' : l})
3635 Xopen | only
3636 2Xnext
3637 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003638 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003639 Xnext
3640 call assert_equal(7, col('.'))
3641 Xnext
3642 call assert_equal(2, line('.'))
3643 Xnext
3644 call assert_equal(9, col('.'))
3645 2
3646 Xnext
3647 call assert_equal(2, line('.'))
3648
3649 if a:cchar == 'l'
3650 " When jumping to a location list entry in the location list window and
3651 " no usable windows are available, then a new window should be opened.
3652 enew! | new | only
3653 call g:Xsetlist([], 'f')
3654 setlocal buftype=nofile
3655 new
3656 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']})
3657 Xopen
3658 let winid = win_getid()
3659 wincmd p
3660 close
3661 call win_gotoid(winid)
3662 Xnext
3663 call assert_equal(3, winnr('$'))
3664 call assert_equal(1, winnr())
3665 call assert_equal(2, line('.'))
3666
3667 " When jumping to an entry in the location list window and the window
3668 " associated with the location list is not present and a window containing
3669 " the file is already present, then that window should be used.
3670 close
3671 belowright new
3672 call g:Xsetlist([], 'f')
3673 edit F3
3674 call win_gotoid(winid)
3675 Xlast
3676 call assert_equal(3, winnr())
3677 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3678 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3679 endif
3680
3681 " Cleanup
3682 enew!
3683 new | only
3684
3685 call delete('F1')
3686 call delete('F2')
3687 call delete('F3')
3688endfunc
3689
3690func Test_qfjump()
3691 call Xqfjump_tests('c')
3692 call Xqfjump_tests('l')
3693endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003694
3695" Tests for the getqflist() and getloclist() functions when the list is not
3696" present or is empty
3697func Xgetlist_empty_tests(cchar)
3698 call s:setup_commands(a:cchar)
3699
3700 " Empty quickfix stack
3701 call g:Xsetlist([], 'f')
3702 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3703 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3704 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3705 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3706 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3707 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3708 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3709 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003710 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003711 if a:cchar == 'c'
3712 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003713 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003714 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3715 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003716 else
3717 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3718 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003719 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003720 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003721 \ g:Xgetlist({'all' : 0}))
3722 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003723
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003724 " Quickfix window with empty stack
3725 silent! Xopen
3726 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003727 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003728 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3729 Xclose
3730
Bram Moolenaara6d48492017-12-12 22:45:31 +01003731 " Empty quickfix list
3732 Xexpr ""
3733 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3734 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3735 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3736 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3737 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3738 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3739 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3740 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003741 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003742
3743 let qfid = g:Xgetlist({'id' : 0}).id
3744 call g:Xsetlist([], 'f')
3745
3746 " Non-existing quickfix identifier
3747 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3748 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3749 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3750 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3751 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3752 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3753 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3754 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003755 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003756 if a:cchar == 'c'
3757 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3758 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003759 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003760 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3761 else
3762 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3763 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003764 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3765 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003766 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3767 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003768
3769 " Non-existing quickfix list number
3770 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3771 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3772 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3773 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3774 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3775 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3776 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3777 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003778 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003779 if a:cchar == 'c'
3780 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3781 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003782 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3783 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003784 else
3785 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3786 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003787 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3788 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003789 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003790endfunc
3791
3792func Test_getqflist()
3793 call Xgetlist_empty_tests('c')
3794 call Xgetlist_empty_tests('l')
3795endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003796
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003797func Test_getqflist_invalid_nr()
3798 " The following commands used to crash Vim
3799 cexpr ""
3800 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3801
3802 " Cleanup
3803 call setqflist([], 'r')
3804endfunc
3805
Bram Moolenaarb254af32017-12-18 19:48:58 +01003806" Tests for the quickfix/location list changedtick
3807func Xqftick_tests(cchar)
3808 call s:setup_commands(a:cchar)
3809
3810 call g:Xsetlist([], 'f')
3811
3812 Xexpr "F1:10:Line10"
3813 let qfid = g:Xgetlist({'id' : 0}).id
3814 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3815 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3816 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3817 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3818 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3819 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3820 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3821 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3822 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3823
3824 enew!
3825 call append(0, ["F5:50:L50", "F6:60:L60"])
3826 Xaddbuffer
3827 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3828 enew!
3829
3830 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3831 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3832 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3833 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3834 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3835 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3836 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3837 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3838 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3839 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3840 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3841
3842 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3843 Xfile Xone
3844 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3845 Xaddfile Xone
3846 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3847
3848 " Test case for updating a non-current quickfix list
3849 call g:Xsetlist([], 'f')
3850 Xexpr "F1:1:L1"
3851 Xexpr "F2:2:L2"
3852 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3853 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3854 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3855
3856 call delete("Xone")
3857endfunc
3858
3859func Test_qf_tick()
3860 call Xqftick_tests('c')
3861 call Xqftick_tests('l')
3862endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003863
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003864" Test helpgrep with lang specifier
3865func Xtest_helpgrep_with_lang_specifier(cchar)
3866 call s:setup_commands(a:cchar)
3867 Xhelpgrep Vim@en
3868 call assert_equal('help', &filetype)
3869 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3870 new | only
3871endfunc
3872
3873func Test_helpgrep_with_lang_specifier()
3874 call Xtest_helpgrep_with_lang_specifier('c')
3875 call Xtest_helpgrep_with_lang_specifier('l')
3876endfunc
3877
Bram Moolenaar12237442017-12-19 12:38:52 +01003878" The following test used to crash Vim.
3879" Open the location list window and close the regular window associated with
3880" the location list. When the garbage collection runs now, it incorrectly
3881" marks the location list context as not in use and frees the context.
3882func Test_ll_window_ctx()
3883 call setloclist(0, [], 'f')
3884 call setloclist(0, [], 'a', {'context' : []})
3885 lopen | only
3886 call test_garbagecollect_now()
3887 echo getloclist(0, {'context' : 1}).context
3888 enew | only
3889endfunc
3890
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003891" The following test used to crash vim
3892func Test_lfile_crash()
3893 sp Xtest
3894 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003895 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003896 au! QuickFixCmdPre
3897endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003898
3899" The following test used to crash vim
3900func Test_lbuffer_crash()
3901 sv Xtest
3902 augroup QF_Test
3903 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003904 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003905 augroup END
3906 lbuffer
3907 augroup QF_Test
3908 au!
3909 augroup END
3910endfunc
3911
3912" The following test used to crash vim
3913func Test_lexpr_crash()
3914 augroup QF_Test
3915 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003916 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003917 augroup END
3918 lexpr ""
3919 augroup QF_Test
3920 au!
3921 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003922
Bram Moolenaar3c097222017-12-21 20:54:49 +01003923 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003924 augroup QF_Test
3925 au!
3926 au BufNew * call setloclist(0, [], 'f')
3927 augroup END
3928 lexpr 'x:1:x'
3929 augroup QF_Test
3930 au!
3931 augroup END
3932
3933 enew | only
3934 lexpr ''
3935 lopen
3936 augroup QF_Test
3937 au!
3938 au FileType * call setloclist(0, [], 'f')
3939 augroup END
3940 lexpr ''
3941 augroup QF_Test
3942 au!
3943 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003944endfunc
3945
3946" The following test used to crash Vim
3947func Test_lvimgrep_crash()
3948 sv Xtest
3949 augroup QF_Test
3950 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003951 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003952 augroup END
3953 lvimgrep quickfix test_quickfix.vim
3954 augroup QF_Test
3955 au!
3956 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003957
3958 new | only
3959 augroup QF_Test
3960 au!
3961 au BufEnter * call setloclist(0, [], 'r')
3962 augroup END
3963 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3964 augroup QF_Test
3965 au!
3966 augroup END
3967
Bram Moolenaar3c097222017-12-21 20:54:49 +01003968 enew | only
3969endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003970
Bram Moolenaar2573af32020-03-14 17:21:34 +01003971func Test_lvimgrep_crash2()
3972 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003973 call assert_fails('lvimgrep x x', 'E471:')
3974 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003975
3976 au! BufNewFile
3977endfunc
3978
Bram Moolenaarde046542017-12-26 13:53:11 +01003979" Test for the position of the quickfix and location list window
3980func Test_qfwin_pos()
3981 " Open two windows
3982 new | only
3983 new
3984 cexpr ['F1:10:L10']
3985 copen
3986 " Quickfix window should be the bottom most window
3987 call assert_equal(3, winnr())
3988 close
3989 " Open at the very top
3990 wincmd t
3991 topleft copen
3992 call assert_equal(1, winnr())
3993 close
3994 " open left of the current window
3995 wincmd t
3996 below new
3997 leftabove copen
3998 call assert_equal(2, winnr())
3999 close
4000 " open right of the current window
4001 rightbelow copen
4002 call assert_equal(3, winnr())
4003 close
4004endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02004005
4006" Tests for quickfix/location lists changed by autocommands when
4007" :vimgrep/:lvimgrep commands are running.
4008func Test_vimgrep_autocmd()
4009 call setqflist([], 'f')
4010 call writefile(['stars'], 'Xtest1.txt')
4011 call writefile(['stars'], 'Xtest2.txt')
4012
4013 " Test 1:
4014 " When searching for a pattern using :vimgrep, if the quickfix list is
4015 " changed by an autocmd, the results should be added to the correct quickfix
4016 " list.
4017 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
4018 silent vimgrep stars Xtest*.txt
4019 call assert_equal(1, getqflist({'nr' : 0}).nr)
4020 call assert_equal(3, getqflist({'nr' : '$'}).nr)
4021 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
4022 au! BufRead Xtest2.txt
4023
4024 " Test 2:
4025 " When searching for a pattern using :vimgrep, if the quickfix list is
4026 " freed, then a error should be given.
4027 silent! %bwipe!
4028 call setqflist([], 'f')
4029 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
4030 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
4031 au! BufRead Xtest2.txt
4032
4033 " Test 3:
4034 " When searching for a pattern using :lvimgrep, if the location list is
4035 " freed, then the command should error out.
4036 silent! %bwipe!
4037 let g:save_winid = win_getid()
4038 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
4039 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
4040 au! BufRead Xtest2.txt
4041
4042 call delete('Xtest1.txt')
4043 call delete('Xtest2.txt')
4044 call setqflist([], 'f')
4045endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004046
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004047" Test for an autocmd changing the current directory when running vimgrep
4048func Xvimgrep_autocmd_cd(cchar)
4049 call s:setup_commands(a:cchar)
4050
4051 %bwipe
4052 let save_cwd = getcwd()
4053
4054 augroup QF_Test
4055 au!
4056 autocmd BufRead * silent cd %:p:h
4057 augroup END
4058
4059 10Xvimgrep /vim/ Xdir/**
4060 let l = g:Xgetlist()
4061 call assert_equal('f1.txt', bufname(l[0].bufnr))
4062 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4063
4064 augroup QF_Test
4065 au!
4066 augroup END
4067
4068 exe 'cd ' . save_cwd
4069endfunc
4070
4071func Test_vimgrep_autocmd_cd()
4072 call mkdir('Xdir/a', 'p')
4073 call mkdir('Xdir/b', 'p')
4074 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4075 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4076 call Xvimgrep_autocmd_cd('c')
4077 call Xvimgrep_autocmd_cd('l')
4078 %bwipe
4079 call delete('Xdir', 'rf')
4080endfunc
4081
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004082" The following test used to crash Vim
4083func Test_lhelpgrep_autocmd()
4084 lhelpgrep quickfix
4085 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4086 lhelpgrep buffer
4087 call assert_equal('help', &filetype)
4088 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4089 lhelpgrep tabpage
4090 call assert_equal('help', &filetype)
4091 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4092 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004093
4094 new | only
4095 augroup QF_Test
4096 au!
4097 au BufEnter * call setqflist([], 'f')
4098 augroup END
4099 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004100 " run the test with a help window already open
4101 help
4102 wincmd w
4103 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004104 augroup QF_Test
4105 au! BufEnter
4106 augroup END
4107
4108 new | only
4109 augroup QF_Test
4110 au!
4111 au BufEnter * call setqflist([], 'r')
4112 augroup END
4113 call assert_fails('helpgrep quickfix', 'E925:')
4114 augroup QF_Test
4115 au! BufEnter
4116 augroup END
4117
4118 new | only
4119 augroup QF_Test
4120 au!
4121 au BufEnter * call setloclist(0, [], 'r')
4122 augroup END
4123 call assert_fails('lhelpgrep quickfix', 'E926:')
4124 augroup QF_Test
4125 au! BufEnter
4126 augroup END
4127
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004128 new | only
4129endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004130
4131" Test for shortening/simplifying the file name when opening the
4132" quickfix window or when displaying the quickfix list
4133func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004134 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004135 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004136 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004137 let fname = getcwd() . '/test_quickfix.vim'
4138 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4139 call assert_equal(fname, bufname('test_quickfix.vim'))
4140 " Opening the quickfix window should simplify the file path
4141 cwindow
4142 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4143 cclose
4144 %bwipe
Dominique Pelle923dce22021-11-21 11:36:04 +00004145 " Create a quickfix list with an absolute path filename
Bram Moolenaara796d462018-05-01 14:30:36 +02004146 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4147 call assert_equal(fname, bufname('test_quickfix.vim'))
4148 " Displaying the quickfix list should simplify the file path
4149 silent! clist
4150 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004151 " Add a few entries for the same file with different paths and check whether
4152 " the buffer name is shortened
4153 %bwipe
4154 call setqflist([], 'f')
4155 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4156 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4157 \ {'filename' : fname, 'lnum' : 30}], ' ')
4158 copen
4159 call assert_equal(['test_quickfix.vim|10| ',
4160 \ 'test_quickfix.vim|20| ',
4161 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4162 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004163endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004164
4165" Quickfix title tests
4166" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4167" Otherwise due to indentation, the title is set with spaces at the beginning
4168" of the command.
4169func Test_qftitle()
4170 call writefile(["F1:1:Line1"], 'Xerr')
4171
4172 " :cexpr
4173 exe "cexpr readfile('Xerr')"
4174 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4175
4176 " :cgetexpr
4177 exe "cgetexpr readfile('Xerr')"
4178 call assert_equal(":cgetexpr readfile('Xerr')",
4179 \ getqflist({'title' : 1}).title)
4180
4181 " :caddexpr
4182 call setqflist([], 'f')
4183 exe "caddexpr readfile('Xerr')"
4184 call assert_equal(":caddexpr readfile('Xerr')",
4185 \ getqflist({'title' : 1}).title)
4186
4187 " :cbuffer
4188 new Xerr
4189 exe "cbuffer"
4190 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4191
4192 " :cgetbuffer
4193 edit Xerr
4194 exe "cgetbuffer"
4195 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4196
4197 " :caddbuffer
4198 call setqflist([], 'f')
4199 edit Xerr
4200 exe "caddbuffer"
4201 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4202
4203 " :cfile
4204 exe "cfile Xerr"
4205 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4206
4207 " :cgetfile
4208 exe "cgetfile Xerr"
4209 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4210
4211 " :caddfile
4212 call setqflist([], 'f')
4213 exe "caddfile Xerr"
4214 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4215
4216 " :grep
4217 set grepprg=internal
4218 exe "grep F1 Xerr"
4219 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4220
4221 " :grepadd
4222 call setqflist([], 'f')
4223 exe "grepadd F1 Xerr"
4224 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4225 set grepprg&vim
4226
4227 " :vimgrep
4228 exe "vimgrep F1 Xerr"
4229 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4230
4231 " :vimgrepadd
4232 call setqflist([], 'f')
4233 exe "vimgrepadd F1 Xerr"
4234 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4235
4236 call setqflist(['F1:10:L10'], ' ')
4237 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4238
4239 call setqflist([], 'f')
4240 call setqflist(['F1:10:L10'], 'a')
4241 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4242
4243 call setqflist([], 'f')
4244 call setqflist(['F1:10:L10'], 'r')
4245 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4246
4247 close
4248 call delete('Xerr')
4249
4250 call setqflist([], ' ', {'title' : 'Errors'})
4251 copen
4252 call assert_equal('Errors', w:quickfix_title)
4253 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4254 call assert_equal('Errors', w:quickfix_title)
4255 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004256
4257 " Switching to another quickfix list in one tab page should update the
4258 " quickfix window title and statusline in all the other tab pages also
4259 call setqflist([], 'f')
4260 %bw!
4261 cgetexpr ['file_one:1:1: error in the first quickfix list']
4262 call setqflist([], 'a', {'title': 'first quickfix list'})
4263 cgetexpr ['file_two:2:1: error in the second quickfix list']
4264 call setqflist([], 'a', {'title': 'second quickfix list'})
4265 copen
4266 wincmd t
4267 tabnew two
4268 copen
4269 wincmd t
4270 colder
4271 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4272 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4273 call assert_equal(1, tabpagewinnr(1))
4274 call assert_equal(1, tabpagewinnr(2))
4275 tabnew
4276 call setqflist([], 'a', {'title': 'new quickfix title'})
4277 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4278 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4279 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004280endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004281
4282func Test_lbuffer_with_bwipe()
4283 new
4284 new
4285 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004286 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004287 augroup END
4288 lbuffer
4289 augroup nasty
4290 au!
4291 augroup END
4292endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004293
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004294" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4295" running
4296func Xexpr_acmd_freelist(cchar)
4297 call s:setup_commands(a:cchar)
4298
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004299 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004300 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004301 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004302 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004303 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004304 augroup nasty
4305 au!
4306 augroup END
4307endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004308
4309func Test_cexpr_acmd_freelist()
4310 call Xexpr_acmd_freelist('c')
4311 call Xexpr_acmd_freelist('l')
4312endfunc
4313
4314" Test for commands that create a new quickfix/location list and jump to the
4315" first error automatically.
4316func Xjumpto_first_error_test(cchar)
4317 call s:setup_commands(a:cchar)
4318
4319 call s:create_test_file('Xtestfile1')
4320 call s:create_test_file('Xtestfile2')
4321 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4322
4323 " Test for cexpr/lexpr
4324 enew
4325 Xexpr l
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 cfile/lfile
4330 enew
4331 call writefile(l, 'Xerr')
4332 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004333 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004334 call assert_equal(2, line('.'))
4335
4336 " Test for cbuffer/lbuffer
4337 edit Xerr
4338 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004339 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004340 call assert_equal(2, line('.'))
4341
4342 call delete('Xerr')
4343 call delete('Xtestfile1')
4344 call delete('Xtestfile2')
4345endfunc
4346
4347func Test_jumpto_first_error()
4348 call Xjumpto_first_error_test('c')
4349 call Xjumpto_first_error_test('l')
4350endfunc
4351
4352" Test for a quickfix autocmd changing the quickfix/location list before
4353" jumping to the first error in the new list.
4354func Xautocmd_changelist(cchar)
4355 call s:setup_commands(a:cchar)
4356
4357 " Test for cfile/lfile
4358 call s:create_test_file('Xtestfile1')
4359 call s:create_test_file('Xtestfile2')
4360 Xexpr 'Xtestfile1:2:Line2'
4361 autocmd QuickFixCmdPost * Xolder
4362 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4363 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004364 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004365 call assert_equal(4, line('.'))
4366 autocmd! QuickFixCmdPost
4367
4368 " Test for cbuffer/lbuffer
4369 call g:Xsetlist([], 'f')
4370 Xexpr 'Xtestfile1:2:Line2'
4371 autocmd QuickFixCmdPost * Xolder
4372 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4373 edit Xerr
4374 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004375 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004376 call assert_equal(4, line('.'))
4377 autocmd! QuickFixCmdPost
4378
4379 " Test for cexpr/lexpr
4380 call g:Xsetlist([], 'f')
4381 Xexpr 'Xtestfile1:2:Line2'
4382 autocmd QuickFixCmdPost * Xolder
4383 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004384 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004385 call assert_equal(4, line('.'))
4386 autocmd! QuickFixCmdPost
4387
Bram Moolenaar851332e2018-07-03 19:16:00 +02004388 " The grepprg may not be set on non-Unix systems
4389 if has('unix')
4390 " Test for grep/lgrep
4391 call g:Xsetlist([], 'f')
4392 Xexpr 'Xtestfile1:2:Line2'
4393 autocmd QuickFixCmdPost * Xolder
4394 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004395 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004396 call assert_equal(5, line('.'))
4397 autocmd! QuickFixCmdPost
4398 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004399
4400 " Test for vimgrep/lvimgrep
4401 call g:Xsetlist([], 'f')
4402 Xexpr 'Xtestfile1:2:Line2'
4403 autocmd QuickFixCmdPost * Xolder
4404 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004405 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004406 call assert_equal(5, line('.'))
4407 autocmd! QuickFixCmdPost
4408
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004409 " Test for autocommands clearing the quickfix list before jumping to the
4410 " first error. This should not result in an error
4411 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4412 let v:errmsg = ''
4413 " Test for cfile/lfile
4414 Xfile Xerr
4415 call assert_true(v:errmsg !~# 'E42:')
4416 " Test for cbuffer/lbuffer
4417 edit Xerr
4418 Xbuffer
4419 call assert_true(v:errmsg !~# 'E42:')
4420 " Test for cexpr/lexpr
4421 Xexpr 'Xtestfile2:4:Line4'
4422 call assert_true(v:errmsg !~# 'E42:')
4423 " Test for grep/lgrep
4424 " The grepprg may not be set on non-Unix systems
4425 if has('unix')
4426 silent Xgrep Line5 Xtestfile2
4427 call assert_true(v:errmsg !~# 'E42:')
4428 endif
4429 " Test for vimgrep/lvimgrep
4430 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4431 autocmd! QuickFixCmdPost
4432
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004433 call delete('Xerr')
4434 call delete('Xtestfile1')
4435 call delete('Xtestfile2')
4436endfunc
4437
4438func Test_autocmd_changelist()
4439 call Xautocmd_changelist('c')
4440 call Xautocmd_changelist('l')
4441endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004442
4443" Tests for the ':filter /pat/ clist' command
4444func Test_filter_clist()
4445 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4446 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4447 \ split(execute('filter /Line 15/ clist'), "\n"))
4448 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4449 \ split(execute('filter /Xfile1/ clist'), "\n"))
4450 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4451
4452 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4453 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4454 call assert_equal([' 2 pqr:pat2: '],
4455 \ split(execute('filter /pqr/ clist'), "\n"))
4456 call assert_equal([' 1 abc:pat1: '],
4457 \ split(execute('filter /pat1/ clist'), "\n"))
4458endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004459
4460" Tests for the "CTRL-W <CR>" command.
4461func Xview_result_split_tests(cchar)
4462 call s:setup_commands(a:cchar)
4463
4464 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4465 call g:Xsetlist([])
4466 Xopen
4467 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004468 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004469 call assert_equal(l:win_count, winnr('$'))
4470 Xclose
4471endfunc
4472
4473func Test_view_result_split()
4474 call Xview_result_split_tests('c')
4475 call Xview_result_split_tests('l')
4476endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004477
4478" Test that :cc sets curswant
4479func Test_curswant()
4480 helpgrep quickfix
4481 normal! llll
4482 1cc
4483 call assert_equal(getcurpos()[4], virtcol('.'))
4484 cclose | helpclose
4485endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004486
4487" Test for opening a file from the quickfix window using CTRL-W <Enter>
4488" doesn't leave an empty buffer around.
4489func Test_splitview()
4490 call s:create_test_file('Xtestfile1')
4491 call s:create_test_file('Xtestfile2')
4492 new | only
4493 let last_bufnr = bufnr('Test_sv_1', 1)
4494 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4495 cgetexpr l
4496 copen
4497 let numbufs = len(getbufinfo())
4498 exe "normal \<C-W>\<CR>"
4499 copen
4500 exe "normal j\<C-W>\<CR>"
4501 " Make sure new empty buffers are not created
4502 call assert_equal(numbufs, len(getbufinfo()))
4503 " Creating a new buffer should use the next available buffer number
4504 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4505 bwipe Test_sv_1
4506 bwipe Test_sv_2
4507 new | only
4508
4509 " When split opening files from location list window, make sure that two
4510 " windows doesn't refer to the same location list
4511 lgetexpr l
4512 let locid = getloclist(0, {'id' : 0}).id
4513 lopen
4514 exe "normal \<C-W>\<CR>"
4515 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4516 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4517 new | only
4518
4519 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004520 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004521 lhelpgrep window
4522 let locid = getloclist(0, {'id' : 0}).id
4523 lwindow
4524 exe "normal j\<C-W>\<CR>"
4525 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4526 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4527 new | only
4528
Bram Moolenaar406cd902020-02-18 21:54:41 +01004529 " Using :split or :vsplit from a quickfix window should behave like a :new
4530 " or a :vnew command
4531 copen
4532 split
4533 call assert_equal(3, winnr('$'))
4534 let l = getwininfo()
4535 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4536 close
4537 copen
4538 vsplit
4539 let l = getwininfo()
4540 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4541 new | only
4542
Bram Moolenaarb2443732018-11-11 22:50:27 +01004543 call delete('Xtestfile1')
4544 call delete('Xtestfile2')
4545endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004546
4547" Test for parsing entries using visual screen column
4548func Test_viscol()
4549 enew
4550 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4551 edit Xfile1
4552
4553 " Use byte offset for column number
4554 set efm&
4555 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4556 call assert_equal([5, 8], [col('.'), virtcol('.')])
4557 cnext
4558 call assert_equal([9, 12], [col('.'), virtcol('.')])
4559 cnext
4560 call assert_equal([14, 20], [col('.'), virtcol('.')])
4561
4562 " Use screen column offset for column number
4563 set efm=%f:%l:%v:%m
4564 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4565 call assert_equal([5, 8], [col('.'), virtcol('.')])
4566 cnext
4567 call assert_equal([9, 12], [col('.'), virtcol('.')])
4568 cnext
4569 call assert_equal([14, 20], [col('.'), virtcol('.')])
4570 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4571 call assert_equal([5, 8], [col('.'), virtcol('.')])
4572 cnext
4573 call assert_equal([10, 16], [col('.'), virtcol('.')])
4574 cnext
4575 call assert_equal([14, 20], [col('.'), virtcol('.')])
4576
4577 enew
4578 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4579
4580 " Use byte offset for column number
4581 set efm&
4582 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4583 call assert_equal([8, 10], [col('.'), virtcol('.')])
4584 cnext
4585 call assert_equal([11, 17], [col('.'), virtcol('.')])
4586 cnext
4587 call assert_equal([16, 25], [col('.'), virtcol('.')])
4588
4589 " Use screen column offset for column number
4590 set efm=%f:%l:%v:%m
4591 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4592 call assert_equal([8, 10], [col('.'), virtcol('.')])
4593 cnext
4594 call assert_equal([11, 17], [col('.'), virtcol('.')])
4595 cnext
4596 call assert_equal([16, 25], [col('.'), virtcol('.')])
4597
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004598 " Use screen column number with a multi-line error message
4599 enew
4600 call writefile(["à test"], 'Xfile1')
4601 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4602 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4603 call assert_equal('Xfile1', @%)
4604 call assert_equal([0, 1, 4, 0], getpos('.'))
4605
4606 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4607 " does not break this
4608 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4609 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4610 call assert_equal('Xfile1', @%)
4611 call assert_equal([0, 1, 3, 0], getpos('.'))
4612
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004613 enew | only
4614 set efm&
4615 call delete('Xfile1')
4616endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004617
4618" Test for the quickfix window buffer
4619func Xqfbuf_test(cchar)
4620 call s:setup_commands(a:cchar)
4621
4622 " Quickfix buffer should be reused across closing and opening a quickfix
4623 " window
4624 Xexpr "F1:10:Line10"
4625 Xopen
4626 let qfbnum = bufnr('')
4627 Xclose
4628 " Even after the quickfix window is closed, the buffer should be loaded
4629 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004630 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004631 Xopen
4632 " Buffer should be reused when opening the window again
4633 call assert_equal(qfbnum, bufnr(''))
4634 Xclose
4635
Yegappan Lakshmanan56150da2021-12-09 09:27:06 +00004636 " When quickfix buffer is wiped out, getqflist() should return 0
4637 %bw!
4638 Xexpr ""
4639 Xopen
4640 bw!
4641 call assert_equal(0, g:Xgetlist({'qfbufnr': 0}).qfbufnr)
4642
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004643 if a:cchar == 'l'
4644 %bwipe
4645 " For a location list, when both the file window and the location list
4646 " window for the list are closed, then the buffer should be freed.
4647 new | only
4648 lexpr "F1:10:Line10"
4649 let wid = win_getid()
4650 lopen
4651 let qfbnum = bufnr('')
4652 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4653 close
4654 " When the location list window is closed, the buffer name should not
4655 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004656 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004657 call assert_true(bufloaded(qfbnum))
4658
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004659 " After deleting a location list buffer using ":bdelete", opening the
4660 " location list window should mark the buffer as a location list buffer.
4661 exe "bdelete " . qfbnum
4662 lopen
4663 call assert_equal("quickfix", &buftype)
4664 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4665 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4666 call assert_false(&swapfile)
4667 lclose
4668
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004669 " When the location list is cleared for the window, the buffer should be
4670 " removed
4671 call setloclist(0, [], 'f')
4672 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004673 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004674
4675 " When the location list is freed with the location list window open, the
4676 " location list buffer should not be lost. It should be reused when the
4677 " location list is again populated.
4678 lexpr "F1:10:Line10"
4679 lopen
4680 let wid = win_getid()
4681 let qfbnum = bufnr('')
4682 wincmd p
4683 call setloclist(0, [], 'f')
4684 lexpr "F1:10:Line10"
4685 lopen
4686 call assert_equal(wid, win_getid())
4687 call assert_equal(qfbnum, bufnr(''))
4688 lclose
4689
4690 " When the window with the location list is closed, the buffer should be
4691 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004692 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004693 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004694 endif
4695endfunc
4696
4697func Test_qfbuf()
4698 call Xqfbuf_test('c')
4699 call Xqfbuf_test('l')
4700endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004701
4702" If there is an autocmd to use only one window, then opening the location
4703" list window used to crash Vim.
4704func Test_winonly_autocmd()
4705 call s:create_test_file('Xtest1')
4706 " Autocmd to show only one Vim window at a time
4707 autocmd WinEnter * only
4708 new
4709 " Load the location list
4710 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4711 let loclistid = getloclist(0, {'id' : 0}).id
4712 " Open the location list window. Only this window will be shown and the file
4713 " window is closed.
4714 lopen
4715 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4716 " Jump to an entry in the location list and make sure that the cursor is
4717 " positioned correctly.
4718 ll 3
4719 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004720 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004721 call assert_equal(15, line('.'))
4722 " Cleanup
4723 autocmd! WinEnter
4724 new | only
4725 call delete('Xtest1')
4726endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004727
4728" Test to make sure that an empty quickfix buffer is not reused for loading
4729" a normal buffer.
4730func Test_empty_qfbuf()
4731 enew | only
4732 call writefile(["Test"], 'Xfile1')
4733 call setqflist([], 'f')
4734 copen | only
4735 let qfbuf = bufnr('')
4736 edit Xfile1
4737 call assert_notequal(qfbuf, bufnr(''))
4738 enew
4739 call delete('Xfile1')
4740endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004741
4742" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004743" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004744func Xtest_below(cchar)
4745 call s:setup_commands(a:cchar)
4746
4747 " No quickfix/location list
4748 call assert_fails('Xbelow', 'E42:')
4749 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004750 call assert_fails('Xbefore', 'E42:')
4751 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004752
4753 " Empty quickfix/location list
4754 call g:Xsetlist([])
4755 call assert_fails('Xbelow', 'E42:')
4756 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004757 call assert_fails('Xbefore', 'E42:')
4758 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004759
4760 call s:create_test_file('X1')
4761 call s:create_test_file('X2')
4762 call s:create_test_file('X3')
4763 call s:create_test_file('X4')
4764
4765 " Invalid entries
4766 edit X1
4767 call g:Xsetlist(["E1", "E2"])
4768 call assert_fails('Xbelow', 'E42:')
4769 call assert_fails('Xabove', 'E42:')
4770 call assert_fails('3Xbelow', 'E42:')
4771 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004772 call assert_fails('Xbefore', 'E42:')
4773 call assert_fails('Xafter', 'E42:')
4774 call assert_fails('3Xbefore', 'E42:')
4775 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004776
4777 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004778 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 +02004779 edit +7 X2
4780 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004781 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004782 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004783 normal 7G
4784 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004785 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004786 call assert_fails('Xbefore', 'E553:')
4787
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004788 normal 2j
4789 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004790 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004791 normal 7G
4792 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004793 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004794
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004795 " Last error in this file
4796 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004797 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004798 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004799 normal gg
4800 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004801 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004802 call assert_fails('Xafter', 'E553:')
4803
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004804 " First error in this file
4805 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004806 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004807 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004808 normal G
4809 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004810 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004811 call assert_fails('Xbefore', 'E553:')
4812
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004813 normal gg
4814 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004815 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004816 normal gg
4817 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004818 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004819
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004820 normal G
4821 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004822 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004823 normal G
4824 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004825 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004826
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004827 edit X4
4828 call assert_fails('Xabove', 'E42:')
4829 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004830 call assert_fails('Xbefore', 'E42:')
4831 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004832 if a:cchar == 'l'
4833 " If a buffer has location list entries from some other window but not
4834 " from the current window, then the commands should fail.
4835 edit X1 | split | call setloclist(0, [], 'f')
4836 call assert_fails('Xabove', 'E776:')
4837 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004838 call assert_fails('Xbefore', 'E776:')
4839 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004840 close
4841 endif
4842
4843 " Test for lines with multiple quickfix entries
4844 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4845 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4846 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4847 edit +1 X2
4848 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004849 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004850 normal 1G
4851 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004852 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004853
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004854 normal gg
4855 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004856 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004857 normal gg
4858 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004859 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004860
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004861 normal G
4862 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004863 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004864 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004865 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004866 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004867
4868 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004869 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004870 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004871 normal G
4872 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004873 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004874
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004875 normal 10G
4876 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004877 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004878 normal 10G$
4879 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004880 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004881
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004882 normal 10G
4883 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004884 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004885 normal 9G
4886 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004887 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004888
4889 " Invalid range
4890 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004891 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004892 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004893 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004894 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004895 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004896 endif
4897
4898 call delete('X1')
4899 call delete('X2')
4900 call delete('X3')
4901 call delete('X4')
4902endfunc
4903
4904func Test_cbelow()
4905 call Xtest_below('c')
4906 call Xtest_below('l')
4907endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004908
4909func Test_quickfix_count()
4910 let commands = [
4911 \ 'cNext',
4912 \ 'cNfile',
4913 \ 'cabove',
4914 \ 'cbelow',
4915 \ 'cfirst',
4916 \ 'clast',
4917 \ 'cnewer',
4918 \ 'cnext',
4919 \ 'cnfile',
4920 \ 'colder',
4921 \ 'cprevious',
4922 \ 'crewind',
4923 \
4924 \ 'lNext',
4925 \ 'lNfile',
4926 \ 'labove',
4927 \ 'lbelow',
4928 \ 'lfirst',
4929 \ 'llast',
4930 \ 'lnewer',
4931 \ 'lnext',
4932 \ 'lnfile',
4933 \ 'lolder',
4934 \ 'lprevious',
4935 \ 'lrewind',
4936 \ ]
4937 for cmd in commands
4938 call assert_fails('-1' .. cmd, 'E16:')
4939 call assert_fails('.' .. cmd, 'E16:')
4940 call assert_fails('%' .. cmd, 'E16:')
4941 call assert_fails('$' .. cmd, 'E16:')
4942 endfor
4943endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004944
4945" Test for aborting quickfix commands using QuickFixCmdPre
4946func Xtest_qfcmd_abort(cchar)
4947 call s:setup_commands(a:cchar)
4948
4949 call g:Xsetlist([], 'f')
4950
4951 " cexpr/lexpr
4952 let e = ''
4953 try
4954 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4955 catch /.*/
4956 let e = v:exception
4957 endtry
4958 call assert_equal('AbortCmd', e)
4959 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4960
4961 " cfile/lfile
4962 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4963 let e = ''
4964 try
4965 Xfile Xfile1
4966 catch /.*/
4967 let e = v:exception
4968 endtry
4969 call assert_equal('AbortCmd', e)
4970 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4971 call delete('Xfile1')
4972
4973 " cgetbuffer/lgetbuffer
4974 enew!
4975 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4976 let e = ''
4977 try
4978 Xgetbuffer
4979 catch /.*/
4980 let e = v:exception
4981 endtry
4982 call assert_equal('AbortCmd', e)
4983 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4984 enew!
4985
4986 " vimgrep/lvimgrep
4987 let e = ''
4988 try
4989 Xvimgrep /func/ test_quickfix.vim
4990 catch /.*/
4991 let e = v:exception
4992 endtry
4993 call assert_equal('AbortCmd', e)
4994 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4995
4996 " helpgrep/lhelpgrep
4997 let e = ''
4998 try
4999 Xhelpgrep quickfix
5000 catch /.*/
5001 let e = v:exception
5002 endtry
5003 call assert_equal('AbortCmd', e)
5004 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5005
5006 " grep/lgrep
5007 if has('unix')
5008 let e = ''
5009 try
5010 silent Xgrep func test_quickfix.vim
5011 catch /.*/
5012 let e = v:exception
5013 endtry
5014 call assert_equal('AbortCmd', e)
5015 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
5016 endif
5017endfunc
5018
5019func Test_qfcmd_abort()
5020 augroup QF_Test
5021 au!
5022 autocmd QuickFixCmdPre * throw "AbortCmd"
5023 augroup END
5024
5025 call Xtest_qfcmd_abort('c')
5026 call Xtest_qfcmd_abort('l')
5027
5028 augroup QF_Test
5029 au!
5030 augroup END
5031endfunc
5032
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005033" Test for using a file in one of the parent directories.
5034func Test_search_in_dirstack()
5035 call mkdir('Xtestdir/a/b/c', 'p')
5036 let save_cwd = getcwd()
5037 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
5038 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
5039 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
5040 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
5041
5042 let lines = "Entering dir Xtestdir\n" .
5043 \ "Entering dir a\n" .
5044 \ "Entering dir b\n" .
5045 \ "Xfile2:2:X2_L2\n" .
5046 \ "Leaving dir a\n" .
5047 \ "Xfile1:2:X1_L2\n" .
5048 \ "Xfile3:1:X3_L1\n" .
5049 \ "Entering dir c\n" .
5050 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005051 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005052 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005053 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005054 call assert_equal(11, getqflist({'size' : 0}).size)
5055 call assert_equal(4, getqflist({'idx' : 0}).idx)
5056 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005057 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005058 cnext
5059 call assert_equal(6, getqflist({'idx' : 0}).idx)
5060 call assert_equal('X1_L2', getline('.'))
5061 cnext
5062 call assert_equal(7, getqflist({'idx' : 0}).idx)
5063 call assert_equal(1, line('$'))
5064 call assert_equal('', getline(1))
5065 cnext
5066 call assert_equal(9, getqflist({'idx' : 0}).idx)
5067 call assert_equal(1, line('$'))
5068 call assert_equal('', getline(1))
5069
5070 set efm&
5071 exe 'cd ' . save_cwd
5072 call delete('Xtestdir', 'rf')
5073endfunc
5074
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005075" Test for :cquit
5076func Test_cquit()
5077 " Exit Vim with a non-zero value
5078 if RunVim([], ["cquit 7"], '')
5079 call assert_equal(7, v:shell_error)
5080 endif
5081
5082 if RunVim([], ["50cquit"], '')
5083 call assert_equal(50, v:shell_error)
5084 endif
5085
5086 " Exit Vim with default value
5087 if RunVim([], ["cquit"], '')
5088 call assert_equal(1, v:shell_error)
5089 endif
5090
5091 " Exit Vim with zero value
5092 if RunVim([], ["cquit 0"], '')
5093 call assert_equal(0, v:shell_error)
5094 endif
5095
5096 " Exit Vim with negative value
5097 call assert_fails('-3cquit', 'E16:')
5098endfunc
5099
Bram Moolenaar858ba062020-05-31 23:11:59 +02005100" Test for getting a specific item from a quickfix list
5101func Xtest_getqflist_by_idx(cchar)
5102 call s:setup_commands(a:cchar)
5103 " Empty list
5104 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5105 Xexpr ['F1:10:L10', 'F1:20:L20']
5106 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5107 call assert_equal(bufnr('F1'), l[0].bufnr)
5108 call assert_equal(20, l[0].lnum)
5109 call assert_equal('L20', l[0].text)
5110 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5111 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5112 %bwipe!
5113endfunc
5114
5115func Test_getqflist_by_idx()
5116 call Xtest_getqflist_by_idx('c')
5117 call Xtest_getqflist_by_idx('l')
5118endfunc
5119
5120" Test for the 'quickfixtextfunc' setting
5121func Tqfexpr(info)
5122 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005123 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005124 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005125 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005126 endif
5127
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005128 let l = []
5129 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5130 let e = qfl[idx]
5131 let s = ''
5132 if e.bufnr != 0
5133 let bname = bufname(e.bufnr)
5134 let s ..= fnamemodify(bname, ':.')
5135 endif
5136 let s ..= '-'
5137 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5138 let s ..= e.text
5139 call add(l, s)
5140 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005141
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005142 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005143endfunc
5144
5145func Xtest_qftextfunc(cchar)
5146 call s:setup_commands(a:cchar)
5147
5148 set efm=%f:%l:%c:%m
5149 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005150 call assert_equal('Tqfexpr', &quickfixtextfunc)
5151 call assert_equal('',
5152 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
thinca6864efa2021-06-19 20:45:20 +02005153 call g:Xsetlist([
5154 \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
5155 \ 'end_col': 7, 'text': 'green'},
5156 \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
5157 \ 'end_col': 8, 'text': 'blue'},
5158 \ ])
5159
Bram Moolenaar858ba062020-05-31 23:11:59 +02005160 Xwindow
5161 call assert_equal('F1-L10C2-green', getline(1))
5162 call assert_equal('F1-L20C4-blue', getline(2))
5163 Xclose
5164 set quickfixtextfunc&vim
5165 Xwindow
thinca6864efa2021-06-19 20:45:20 +02005166 call assert_equal('F1|10 col 2-7| green', getline(1))
5167 call assert_equal('F1|20-25 col 4-8| blue', getline(2))
Bram Moolenaar858ba062020-05-31 23:11:59 +02005168 Xclose
5169 set efm&
5170 set quickfixtextfunc&
5171
5172 " Test for per list 'quickfixtextfunc' setting
5173 func PerQfText(info)
5174 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005175 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005176 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005177 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005178 endif
5179 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005180 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005181 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005182 let l = []
5183 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5184 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5185 endfor
5186 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005187 endfunc
5188 set quickfixtextfunc=Tqfexpr
5189 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5190 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5191 Xwindow
5192 call assert_equal('Line 10, Col 2', getline(1))
5193 call assert_equal('Line 20, Col 4', getline(2))
5194 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005195 call assert_equal(function('PerQfText'),
5196 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005197 " Add entries to the list when the quickfix buffer is hidden
5198 Xaddexpr ['F1:30:6:red']
5199 Xwindow
5200 call assert_equal('Line 30, Col 6', getline(3))
5201 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005202 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005203 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005204 set quickfixtextfunc&
5205 delfunc PerQfText
5206
5207 " Non-existing function
5208 set quickfixtextfunc=Tabc
5209 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5210 call assert_fails("Xwindow", 'E117:')
5211 Xclose
5212 set quickfixtextfunc&
5213
5214 " set option to a non-function
5215 set quickfixtextfunc=[10,\ 20]
5216 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5217 call assert_fails("Xwindow", 'E117:')
5218 Xclose
5219 set quickfixtextfunc&
5220
5221 " set option to a function with different set of arguments
5222 func Xqftext(a, b, c)
5223 return a:a .. a:b .. a:c
5224 endfunc
5225 set quickfixtextfunc=Xqftext
5226 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5227 call assert_fails("Xwindow", 'E119:')
5228 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005229
5230 " set option to a function that returns a list with non-strings
5231 func Xqftext2(d)
5232 return ['one', [], 'two']
5233 endfunc
5234 set quickfixtextfunc=Xqftext2
5235 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5236 \ 'E730:')
5237 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005238 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5239 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005240 Xclose
5241
Bram Moolenaar858ba062020-05-31 23:11:59 +02005242 set quickfixtextfunc&
5243 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005244 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005245
5246 " set the global option to a lambda function
5247 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5248 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5249 Xwindow
5250 call assert_equal(['green', 'blue'], getline(1, '$'))
5251 Xclose
5252 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)
5253 set quickfixtextfunc&
5254
5255 " use a lambda function that returns an empty list
5256 set quickfixtextfunc={d\ ->\ []}
5257 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5258 Xwindow
5259 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5260 \ getline(1, '$'))
5261 Xclose
5262 set quickfixtextfunc&
5263
5264 " use a lambda function that returns a list with empty strings
5265 set quickfixtextfunc={d\ ->\ ['',\ '']}
5266 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5267 Xwindow
5268 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5269 \ getline(1, '$'))
5270 Xclose
5271 set quickfixtextfunc&
5272
5273 " set the per-quickfix list text function to a lambda function
5274 call g:Xsetlist([], ' ',
5275 \ {'quickfixtextfunc' :
5276 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5277 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5278 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5279 Xwindow
5280 call assert_equal('Line 10, Col 2', getline(1))
5281 call assert_equal('Line 20, Col 4', getline(2))
5282 Xclose
5283 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5284 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005285endfunc
5286
5287func Test_qftextfunc()
5288 call Xtest_qftextfunc('c')
5289 call Xtest_qftextfunc('l')
5290endfunc
5291
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005292func Test_qftextfunc_callback()
5293 let lines =<< trim END
5294 set efm=%f:%l:%c:%m
5295
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00005296 #" Test for using a function name
5297 LET &qftf = 'g:Tqfexpr'
5298 cexpr "F0:0:0:L0"
5299 copen
5300 call assert_equal('F0-L0C0-L0', getline(1))
5301 cclose
5302
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005303 #" Test for using a function()
5304 set qftf=function('g:Tqfexpr')
5305 cexpr "F1:1:1:L1"
5306 copen
5307 call assert_equal('F1-L1C1-L1', getline(1))
5308 cclose
5309
5310 #" Using a funcref variable to set 'quickfixtextfunc'
5311 VAR Fn = function('g:Tqfexpr')
5312 LET &qftf = Fn
5313 cexpr "F2:2:2:L2"
5314 copen
5315 call assert_equal('F2-L2C2-L2', getline(1))
5316 cclose
5317
5318 #" Using string(funcref_variable) to set 'quickfixtextfunc'
5319 LET Fn = function('g:Tqfexpr')
5320 LET &qftf = string(Fn)
5321 cexpr "F3:3:3:L3"
5322 copen
5323 call assert_equal('F3-L3C3-L3', getline(1))
5324 cclose
5325
5326 #" Test for using a funcref()
5327 set qftf=funcref('g:Tqfexpr')
5328 cexpr "F4:4:4:L4"
5329 copen
5330 call assert_equal('F4-L4C4-L4', getline(1))
5331 cclose
5332
5333 #" Using a funcref variable to set 'quickfixtextfunc'
5334 LET Fn = funcref('g:Tqfexpr')
5335 LET &qftf = Fn
5336 cexpr "F5:5:5:L5"
5337 copen
5338 call assert_equal('F5-L5C5-L5', getline(1))
5339 cclose
5340
5341 #" Using a string(funcref_variable) to set 'quickfixtextfunc'
5342 LET Fn = funcref('g:Tqfexpr')
5343 LET &qftf = string(Fn)
5344 cexpr "F5:5:5:L5"
5345 copen
5346 call assert_equal('F5-L5C5-L5', getline(1))
5347 cclose
5348
5349 #" Test for using a lambda function with set
5350 VAR optval = "LSTART a LMIDDLE Tqfexpr(a) LEND"
5351 LET optval = substitute(optval, ' ', '\\ ', 'g')
5352 exe "set qftf=" .. optval
5353 cexpr "F6:6:6:L6"
5354 copen
5355 call assert_equal('F6-L6C6-L6', getline(1))
5356 cclose
5357
5358 #" Set 'quickfixtextfunc' to a lambda expression
5359 LET &qftf = LSTART a LMIDDLE Tqfexpr(a) LEND
5360 cexpr "F7:7:7:L7"
5361 copen
5362 call assert_equal('F7-L7C7-L7', getline(1))
5363 cclose
5364
5365 #" Set 'quickfixtextfunc' to string(lambda_expression)
5366 LET &qftf = "LSTART a LMIDDLE Tqfexpr(a) LEND"
5367 cexpr "F8:8:8:L8"
5368 copen
5369 call assert_equal('F8-L8C8-L8', getline(1))
5370 cclose
5371
5372 #" Set 'quickfixtextfunc' to a variable with a lambda expression
5373 VAR Lambda = LSTART a LMIDDLE Tqfexpr(a) LEND
5374 LET &qftf = Lambda
5375 cexpr "F9:9:9:L9"
5376 copen
5377 call assert_equal('F9-L9C9-L9', getline(1))
5378 cclose
5379
5380 #" Set 'quickfixtextfunc' to a string(variable with a lambda expression)
5381 LET Lambda = LSTART a LMIDDLE Tqfexpr(a) LEND
5382 LET &qftf = string(Lambda)
5383 cexpr "F9:9:9:L9"
5384 copen
5385 call assert_equal('F9-L9C9-L9', getline(1))
5386 cclose
5387 END
5388 call CheckLegacyAndVim9Success(lines)
5389
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00005390 " Test for using a script-local function name
5391 func s:TqfFunc2(info)
5392 let g:TqfFunc2Args = [a:info.start_idx, a:info.end_idx]
5393 return ''
5394 endfunc
5395 let g:TqfFunc2Args = []
5396 set quickfixtextfunc=s:TqfFunc2
5397 cexpr "F10:10:10:L10"
5398 cclose
5399 call assert_equal([1, 1], g:TqfFunc2Args)
5400
5401 let &quickfixtextfunc = 's:TqfFunc2'
5402 cexpr "F11:11:11:L11"
5403 cclose
5404 call assert_equal([1, 1], g:TqfFunc2Args)
5405 delfunc s:TqfFunc2
5406
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00005407 " set 'quickfixtextfunc' to a partial with dict. This used to cause a crash.
5408 func SetQftfFunc()
5409 let params = {'qftf': function('g:DictQftfFunc')}
5410 let &quickfixtextfunc = params.qftf
5411 endfunc
5412 func g:DictQftfFunc(_) dict
5413 endfunc
5414 call SetQftfFunc()
5415 new
5416 call SetQftfFunc()
5417 bw
5418 call test_garbagecollect_now()
5419 new
5420 set qftf=
5421 wincmd w
5422 set qftf=
5423 :%bw!
5424
5425 " set per-quickfix list 'quickfixtextfunc' to a partial with dict. This used
5426 " to cause a crash.
5427 let &qftf = ''
5428 func SetLocalQftfFunc()
5429 let params = {'qftf': function('g:DictQftfFunc')}
5430 call setqflist([], 'a', {'quickfixtextfunc' : params.qftf})
5431 endfunc
5432 call SetLocalQftfFunc()
5433 call test_garbagecollect_now()
5434 call setqflist([], 'a', {'quickfixtextfunc' : ''})
5435 delfunc g:DictQftfFunc
5436 delfunc SetQftfFunc
5437 delfunc SetLocalQftfFunc
5438 set efm&
5439endfunc
5440
Yegappan Lakshmananad52f962021-06-19 18:22:53 +02005441" Test for updating a location list for some other window and check that
5442" 'qftextfunc' uses the correct location list.
5443func Test_qftextfunc_other_loclist()
5444 %bw!
5445 call setloclist(0, [], 'f')
5446
5447 " create a window and a location list for it and open the location list
5448 " window
5449 lexpr ['F1:10:12:one', 'F1:20:14:two']
5450 let w1_id = win_getid()
5451 call setloclist(0, [], ' ',
5452 \ {'lines': ['F1:10:12:one', 'F1:20:14:two'],
5453 \ 'quickfixtextfunc':
5454 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5455 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5456 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5457 lwindow
5458 let w2_id = win_getid()
5459
5460 " create another window and a location list for it and open the location
5461 " list window
5462 topleft new
5463 let w3_id = win_getid()
5464 call setloclist(0, [], ' ',
5465 \ {'lines': ['F2:30:32:eleven', 'F2:40:34:twelve'],
5466 \ 'quickfixtextfunc':
5467 \ {d -> map(getloclist(d.winid, {'id' : d.id,
5468 \ 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5469 \ "'Ligne ' .. v:val.lnum .. ', Colonne ' .. v:val.col")}})
5470 lwindow
5471 let w4_id = win_getid()
5472
5473 topleft new
5474 lexpr ['F3:50:52:green', 'F3:60:54:blue']
5475 let w5_id = win_getid()
5476
5477 " change the location list for some other window
5478 call setloclist(0, [], 'r', {'lines': ['F3:55:56:aaa', 'F3:57:58:bbb']})
5479 call setloclist(w1_id, [], 'r', {'lines': ['F1:62:63:bbb', 'F1:64:65:ccc']})
5480 call setloclist(w3_id, [], 'r', {'lines': ['F2:76:77:ddd', 'F2:78:79:eee']})
5481 call assert_equal(['Line 62, Col 63', 'Line 64, Col 65'],
5482 \ getbufline(winbufnr(w2_id), 1, '$'))
5483 call assert_equal(['Ligne 76, Colonne 77', 'Ligne 78, Colonne 79'],
5484 \ getbufline(winbufnr(w4_id), 1, '$'))
5485 call setloclist(w2_id, [], 'r', {'lines': ['F1:32:33:fff', 'F1:34:35:ggg']})
5486 call setloclist(w4_id, [], 'r', {'lines': ['F2:46:47:hhh', 'F2:48:49:jjj']})
5487 call assert_equal(['Line 32, Col 33', 'Line 34, Col 35'],
5488 \ getbufline(winbufnr(w2_id), 1, '$'))
5489 call assert_equal(['Ligne 46, Colonne 47', 'Ligne 48, Colonne 49'],
5490 \ getbufline(winbufnr(w4_id), 1, '$'))
5491
5492 call win_gotoid(w5_id)
5493 lwindow
5494 call assert_equal(['F3|55 col 56| aaa', 'F3|57 col 58| bbb'],
5495 \ getline(1, '$'))
5496 %bw!
5497endfunc
5498
Bram Moolenaarec98e932020-06-08 19:35:59 +02005499" Running :lhelpgrep command more than once in a help window, doesn't jump to
5500" the help topic
5501func Test_lhelpgrep_from_help_window()
5502 call mkdir('Xtestdir/doc', 'p')
5503 call writefile(['window'], 'Xtestdir/doc/a.txt')
5504 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5505 let save_rtp = &rtp
5506 let &rtp = 'Xtestdir'
5507 lhelpgrep window
5508 lhelpgrep buffer
5509 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5510 lhelpgrep window
5511 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5512 let &rtp = save_rtp
5513 call delete('Xtestdir', 'rf')
5514 new | only!
5515endfunc
5516
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005517" Test for the crash fixed by 7.3.715
5518func Test_setloclist_crash()
5519 %bw!
5520 let g:BufNum = bufnr()
5521 augroup QF_Test
5522 au!
5523 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5524 augroup END
5525
5526 try
5527 lvimgrep /.*/ *.mak
5528 catch /E926:/
5529 endtry
5530 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5531 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5532
5533 augroup QF_Test
5534 au!
5535 augroup END
5536 unlet g:BufNum
5537 %bw!
5538endfunc
5539
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005540" Test for adding an invalid entry with the quickfix window open and making
5541" sure that the window contents are not changed
5542func Test_add_invalid_entry_with_qf_window()
5543 call setqflist([], 'f')
5544 cexpr "Xfile1:10:aa"
5545 copen
5546 call setqflist(['bb'], 'a')
5547 call assert_equal(1, line('$'))
5548 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
shane.xb.qian0d5e1ec2021-06-20 16:31:00 +02005549 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())
5550
5551 call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r')
5552 call assert_equal(1 , line('$'))
5553 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5554 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())
5555
5556 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')
5557 call assert_equal(1 , line('$'))
5558 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5559 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())
5560
5561 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')
5562 call assert_equal(1 , line('$'))
5563 call assert_equal(['Xfile1|10| aa'] , getline(1 , '$'))
5564 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())
5565
5566 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')
5567 call assert_equal(1 , line('$'))
5568 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5569 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())
5570
5571 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')
5572 call assert_equal(1 , line('$'))
5573 call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$'))
5574 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())
5575
5576 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')
5577 call assert_equal(1 , line('$'))
5578 call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$'))
5579 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())
5580
5581 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')
5582 call assert_equal(1 , line('$'))
5583 call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$'))
5584 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 +01005585 cclose
5586endfunc
5587
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005588" Test for very weird problem: autocommand causes a failure, resulting opening
5589" the quickfix window to fail. This still splits the window, but otherwise
5590" should not mess up buffers.
5591func Test_quickfix_window_fails_to_open()
5592 CheckScreendump
5593
5594 let lines =<< trim END
5595 anything
5596 try
5597 anything
5598 endtry
5599 END
5600 call writefile(lines, 'XquickfixFails')
5601
5602 let lines =<< trim END
5603 split XquickfixFails
5604 silent vimgrep anything %
5605 normal o
5606 au BufLeave * ++once source XquickfixFails
5607 " This will trigger the autocommand, which causes an error, what follows
5608 " is aborted but the window was already split.
5609 silent! cwindow
5610 END
5611 call writefile(lines, 'XtestWinFails')
5612 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5613 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5614
5615 " clean up
5616 call term_sendkeys(buf, ":bwipe!\<CR>")
5617 call term_wait(buf)
5618 call StopVimInTerminal(buf)
5619 call delete('XtestWinFails')
5620 call delete('XquickfixFails')
5621endfunc
5622
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005623" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005624" is changed.
5625func Xqfbuf_update(cchar)
5626 call s:setup_commands(a:cchar)
5627
5628 Xexpr "F1:1:line1"
5629 Xopen
5630 call assert_equal(['F1|1| line1'], getline(1, '$'))
5631 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5632
5633 " Test setqflist() using the 'lines' key in 'what'
5634 " add a new entry
5635 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5636 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5637 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5638 " replace all the entries with a single entry
5639 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5640 call assert_equal(['F3|3| line3'], getline(1, '$'))
5641 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5642 " remove all the entries
5643 call g:Xsetlist([], 'r', {'lines' : []})
5644 call assert_equal([''], getline(1, '$'))
5645 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5646 " add a new list
5647 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5648 call assert_equal(['F4|4| line4'], getline(1, '$'))
5649 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5650
5651 " Test setqflist() using the 'items' key in 'what'
5652 " add a new entry
5653 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5654 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5655 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5656 " replace all the entries with a single entry
5657 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5658 call assert_equal(['F6|6| line6'], getline(1, '$'))
5659 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5660 " remove all the entries
5661 call g:Xsetlist([], 'r', {'items' : []})
5662 call assert_equal([''], getline(1, '$'))
5663 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5664 " add a new list
5665 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5666 call assert_equal(['F7|7| line7'], getline(1, '$'))
5667 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5668
5669 call g:Xsetlist([], ' ', {})
5670 call assert_equal([''], getline(1, '$'))
5671 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5672
5673 Xclose
5674endfunc
5675
5676func Test_qfbuf_update()
5677 call Xqfbuf_update('c')
5678 call Xqfbuf_update('l')
5679endfunc
5680
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005681func Test_vimgrep_noswapfile()
5682 set noswapfile
5683 call writefile(['one', 'two', 'three'], 'Xgreppie')
5684 vimgrep two Xgreppie
5685 call assert_equal('two', getline('.'))
5686
5687 call delete('Xgreppie')
5688 set swapfile
5689endfunc
5690
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005691" Test for the :vimgrep 'f' flag (fuzzy match)
5692func Xvimgrep_fuzzy_match(cchar)
5693 call s:setup_commands(a:cchar)
5694
5695 Xvimgrep /three one/f Xfile*
5696 let l = g:Xgetlist()
5697 call assert_equal(2, len(l))
5698 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5699 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5700 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5701 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5702
5703 Xvimgrep /the/f Xfile*
5704 let l = g:Xgetlist()
5705 call assert_equal(3, len(l))
5706 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5707 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5708 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5709 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5710 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5711 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5712
5713 Xvimgrep /aaa/fg Xfile*
5714 let l = g:Xgetlist()
5715 call assert_equal(4, len(l))
5716 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5717 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5718 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5719 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5720 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5721 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5722 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5723 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5724
5725 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5726endfunc
5727
5728func Test_vimgrep_fuzzy_match()
5729 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5730 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5731 call Xvimgrep_fuzzy_match('c')
5732 call Xvimgrep_fuzzy_match('l')
5733 call delete('Xfile1')
5734 call delete('Xfile2')
5735endfunc
5736
Wei-Chung Wen1557b162021-07-15 13:13:39 +02005737func Test_locationlist_open_in_newtab()
5738 call s:create_test_file('Xqftestfile1')
5739 call s:create_test_file('Xqftestfile2')
5740 call s:create_test_file('Xqftestfile3')
5741
5742 %bwipe!
5743
5744 lgetexpr ['Xqftestfile1:5:Line5',
5745 \ 'Xqftestfile2:10:Line10',
5746 \ 'Xqftestfile3:16:Line16']
5747
5748 silent! llast
5749 call assert_equal(1, tabpagenr('$'))
5750 call assert_equal('Xqftestfile3', bufname())
5751
5752 set switchbuf=newtab
5753
5754 silent! lfirst
5755 call assert_equal(2, tabpagenr('$'))
5756 call assert_equal('Xqftestfile1', bufname())
5757
5758 silent! lnext
5759 call assert_equal(3, tabpagenr('$'))
5760 call assert_equal('Xqftestfile2', bufname())
5761
5762 call delete('Xqftestfile1')
5763 call delete('Xqftestfile2')
5764 call delete('Xqftestfile3')
5765 set switchbuf&vim
5766
5767 %bwipe!
5768endfunc
5769
Yegappan Lakshmanan28d84212021-07-31 12:43:23 +02005770" Test for win_gettype() in quickfix and location list windows
5771func Test_win_gettype()
5772 copen
5773 call assert_equal("quickfix", win_gettype())
5774 let wid = win_getid()
5775 wincmd p
5776 call assert_equal("quickfix", win_gettype(wid))
5777 cclose
5778 lexpr ''
5779 lopen
5780 call assert_equal("loclist", win_gettype())
5781 let wid = win_getid()
5782 wincmd p
5783 call assert_equal("loclist", win_gettype(wid))
5784 lclose
5785endfunc
5786
Christian Brabandt0b226f62021-12-01 10:54:24 +00005787fun Test_vimgrep_nomatch()
5788 call XexprTests('c')
5789 call g:Xsetlist([{'lnum':10,'text':'Line1'}])
5790 copen
5791 if has("win32")
5792 call assert_fails('vimgrep foo *.zzz', 'E479:')
5793 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'}]
5794 else
5795 call assert_fails('vimgrep foo *.zzz', 'E480:')
5796 let expected = []
5797 endif
5798 call assert_equal(expected, getqflist())
5799 cclose
5800endfunc
5801
Yegappan Lakshmanan78a61062021-12-08 20:03:31 +00005802" Test for opening the quickfix window in two tab pages and then closing one
5803" of the quickfix windows. This should not make the quickfix buffer unlisted.
5804" (github issue #9300).
5805func Test_two_qf_windows()
5806 cexpr "F1:1:line1"
5807 copen
5808 tabnew
5809 copen
5810 call assert_true(&buflisted)
5811 cclose
5812 tabfirst
5813 call assert_true(&buflisted)
5814 let bnum = bufnr()
5815 cclose
5816 " if all the quickfix windows are closed, then buffer should be unlisted.
5817 call assert_false(buflisted(bnum))
5818 %bw!
5819
5820 " Repeat the test for a location list
5821 lexpr "F2:2:line2"
5822 lopen
5823 let bnum = bufnr()
5824 tabnew
5825 exe "buffer" bnum
5826 tabfirst
5827 lclose
5828 tablast
5829 call assert_true(buflisted(bnum))
5830 tabclose
5831 lopen
5832 call assert_true(buflisted(bnum))
5833 lclose
5834 call assert_false(buflisted(bnum))
5835 %bw!
5836endfunc
5837
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005838" vim: shiftwidth=2 sts=2 expandtab