blob: 8faf69a318a0dea221510701bd8de71b6539accc [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01005
Bram Moolenaare00fdf32019-09-15 19:09:42 +02006source screendump.vim
7
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01008set encoding=utf-8
9
Bram Moolenaar2b946c92016-11-12 18:14:44 +010010func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020011 if a:cchar == 'c'
12 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
13 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020014 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020015 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020016 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010017 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020018 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020019 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020020 command! -nargs=* Xclose <mods>cclose <args>
21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
22 command! -nargs=* Xgetfile <mods>cgetfile <args>
23 command! -nargs=* Xaddfile <mods>caddfile <args>
24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
27 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020028 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020030 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
31 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020032 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020033 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020034 command! -nargs=* Xexpr <mods>cexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010035 command! -count -nargs=* Xvimgrep <mods> <count>vimgrep <args>
36 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020037 command! -nargs=* Xgrep <mods> grep <args>
38 command! -nargs=* Xgrepadd <mods> grepadd <args>
39 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010040 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020041 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
42 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020043 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
44 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020045 let g:Xgetlist = function('getqflist')
46 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020047 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020048 else
49 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
50 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020051 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020052 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020053 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010054 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020055 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020056 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020057 command! -nargs=* Xclose <mods>lclose <args>
58 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
59 command! -nargs=* Xgetfile <mods>lgetfile <args>
60 command! -nargs=* Xaddfile <mods>laddfile <args>
61 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
62 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
63 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
64 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020065 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
66 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020067 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
68 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020069 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020070 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020071 command! -nargs=* Xexpr <mods>lexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010072 command! -count -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
73 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020074 command! -nargs=* Xgrep <mods> lgrep <args>
75 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
76 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010077 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020078 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
79 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020080 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
81 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020082 let g:Xgetlist = function('getloclist', [0])
83 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020084 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020085 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010086endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020087
Bram Moolenaarda59dd52016-01-05 21:59:58 +010088" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010089func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020090 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010091
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020092 if a:cchar == 'l'
93 call assert_fails('llist', 'E776:')
94 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020096 Xgetexpr []
97 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098 call assert_true(v:errmsg ==# 'E42: No Errors')
99
100 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200101 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100103 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100104
105 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100106 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100107 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
108 \ ' 4 Xtestfile2:2 col 2: Line2',
109 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
110
111 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100112 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100113 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
114 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100115 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100116
117 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100118 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100119 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
120 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
121
Bram Moolenaaree85df32017-03-19 14:19:50 +0100122 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
124
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
127
Bram Moolenaaree85df32017-03-19 14:19:50 +0100128 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100129 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
130 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100131
132 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100133 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100134 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
135 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100136
137 " Different types of errors
138 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
139 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
140 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
141 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
142 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
143 let l = split(execute('Xlist', ""), "\n")
144 call assert_equal([' 1:10 col 5 warning 11: Warning',
145 \ ' 2:20 col 10 error 22: Error',
146 \ ' 3:30 col 15 info 33: Info',
147 \ ' 4:40 col 20 x 44: Other',
148 \ ' 5:50 col 25 55: one'], l)
149
Bram Moolenaard76ce852018-05-01 15:02:04 +0200150 " Test for module names, one needs to explicitly set `'valid':v:true` so
151 call g:Xsetlist([
152 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
153 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
154 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
155 let l = split(execute('Xlist', ""), "\n")
156 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
157 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
158 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
159
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100160 " For help entries in the quickfix list, only the filename without directory
161 " should be displayed
162 Xhelpgrep setqflist()
163 let l = split(execute('Xlist 1', ''), "\n")
164 call assert_match('^ 1 [^\\/]\{-}:', l[0])
165
Bram Moolenaaree85df32017-03-19 14:19:50 +0100166 " Error cases
167 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100168endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100169
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100170func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100171 call XlistTests('c')
172 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100173endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100174
175" Tests for the :colder, :cnewer, :lolder and :lnewer commands
176" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100177" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100178func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200179 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100180
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200181 if a:cchar == 'l'
182 " No location list for the current window
183 call assert_fails('lolder', 'E776:')
184 call assert_fails('lnewer', 'E776:')
185 endif
186
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200187 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200188 call g:Xsetlist(list)
189
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100190 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200191 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100192 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
193
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200194 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100195 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
196
197 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200198 Xgetexpr ['Xtestfile1:1:3:Line1']
199 Xgetexpr ['Xtestfile2:2:2:Line2']
200 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100201
202 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200203 Xolder
204 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100205 call assert_equal('Line2', l[0].text)
206
207 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200208 Xnewer
209 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100210 call assert_equal('Line3', l[0].text)
211
212 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 Xolder 2
214 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100215 call assert_equal('Line1', l[0].text)
216
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200217 Xnewer 2
218 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100219 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100220endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100221
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100222func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223 call XageTests('c')
224 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100225endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100226
227" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
228" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100229func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100231
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200232 " Opening the location list window without any errors should fail
233 if a:cchar == 'l'
234 call assert_fails('lopen', 'E776:')
235 endif
236
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200238 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100239
240 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200241 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100242 call assert_true(winnr('$') == 1)
243
244 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200245 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
246 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100247
248 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200249 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100250 call assert_true(winnr('$') == 2 && winnr() == 2 &&
251 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200252 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
254 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200255 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100256 call assert_true(winnr('$') == 1)
257
258 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200259 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100260
261 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200262 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100263 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
264 \ && winheight('.') == 5)
265
266 " Opening the window again, should move the cursor to that window
267 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200268 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269 call assert_true(winnr('$') == 2 && winnr() == 2 &&
270 \ winheight('.') == 7 &&
271 \ getline('.') ==# '|| non-error 1')
272
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100273 " :cnext in quickfix window should move to the next entry
274 Xnext
275 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200278 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100279 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200280
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100281 " Specifying the width should adjust the width for a vertically split
282 " quickfix window.
283 vert Xopen
284 call assert_equal(10, winwidth(0))
285 vert Xopen 12
286 call assert_equal(12, winwidth(0))
287 Xclose
288
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200289 " Horizontally or vertically splitting the quickfix window should create a
290 " normal window/buffer
291 Xopen
292 wincmd s
293 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
294 call assert_equal(0, getwininfo(win_getid())[0].loclist)
295 call assert_notequal('quickfix', &buftype)
296 close
297 Xopen
298 wincmd v
299 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
300 call assert_equal(0, getwininfo(win_getid())[0].loclist)
301 call assert_notequal('quickfix', &buftype)
302 close
303 Xopen
304 Xclose
305
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200306 if a:cchar == 'c'
307 " Opening the quickfix window in multiple tab pages should reuse the
308 " quickfix buffer
309 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
310 \ 'Xtestfile3:3:1:Line3']
311 Xopen
312 let qfbufnum = bufnr('%')
313 tabnew
314 Xopen
315 call assert_equal(qfbufnum, bufnr('%'))
316 new | only | tabonly
317 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100318endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100319
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100320func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100321 call XwindowTests('c')
322 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100323endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100324
Bram Moolenaar36d50222019-05-02 20:17:40 +0200325func Test_copenHeight()
326 copen
327 wincmd H
328 let height = winheight(0)
329 copen 10
330 call assert_equal(height, winheight(0))
331 quit
332endfunc
333
Bram Moolenaar1142a312019-10-16 14:51:39 +0200334func Test_copenHeight_tabline()
335 set tabline=foo showtabline=2
336 copen
337 wincmd H
338 let height = winheight(0)
339 copen 10
340 call assert_equal(height, winheight(0))
341 quit
342 set tabline& showtabline&
343endfunc
344
345
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
347" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100348func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200349 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100350
351 call writefile(['Xtestfile1:700:10:Line 700',
352 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
353
354 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200355 Xfile Xqftestfile1
356 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100357 call assert_true(len(l) == 2 &&
358 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
359 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
360
Bram Moolenaar049cba92016-06-26 14:38:04 +0200361 " Test with a non existent file
362 call assert_fails('Xfile non_existent_file', 'E40')
363
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100364 " Run cfile/lfile from a modified buffer
365 enew!
366 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200367 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
369
370 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 Xaddfile Xqftestfile1
372 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373 call assert_true(len(l) == 3 &&
374 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
375
376 call writefile(['Xtestfile1:222:77:Line 222',
377 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
378
379 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200380 Xgetfile Xqftestfile1
381 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100382 call assert_true(len(l) == 2 &&
383 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
384 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
385
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100386 " Test for a file with a long line and without a newline at the end
387 let text = repeat('x', 1024)
388 let t = 'a.txt:18:' . text
389 call writefile([t], 'Xqftestfile1', 'b')
390 silent! Xfile Xqftestfile1
391 call assert_equal(text, g:Xgetlist()[0].text)
392
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100393 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100394endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100396func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100397 call XfileTests('c')
398 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100399endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100400
401" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
402" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100403func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200404 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100405
406 enew!
407 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
408 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200409 Xbuffer!
410 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411 call assert_true(len(l) == 2 &&
412 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
413 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
414
415 enew!
416 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
417 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200418 Xgetbuffer
419 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420 call assert_true(len(l) == 2 &&
421 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
422 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
423
424 enew!
425 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
426 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200427 Xaddbuffer
428 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100429 call assert_true(len(l) == 4 &&
430 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
431 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
432 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200433 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434
Bram Moolenaaree85df32017-03-19 14:19:50 +0100435 " Check for invalid buffer
436 call assert_fails('Xbuffer 199', 'E474:')
437
438 " Check for unloaded buffer
439 edit Xtestfile1
440 let bnr = bufnr('%')
441 enew!
442 call assert_fails('Xbuffer ' . bnr, 'E681:')
443
444 " Check for invalid range
445 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
446 " commands. So directly call the commands.
447 if (a:cchar == 'c')
448 call assert_fails('900,999cbuffer', 'E16:')
449 else
450 call assert_fails('900,999lbuffer', 'E16:')
451 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100452endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100453
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100454func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100455 call XbufferTests('c')
456 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100457endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100458
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100459func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200460 call s:setup_commands(a:cchar)
461
462 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100463endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200464
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100465func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200466 call XexprTests('c')
467 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100468endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200469
470" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100471func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200472 call s:setup_commands(a:cchar)
473
Bram Moolenaar74240d32017-12-10 15:26:15 +0100474 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200475 " Jumping to first or next location list entry without any error should
476 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100477 if a:cchar == 'c'
478 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100479 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100480 else
481 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100482 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200483 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100484 call assert_fails('Xnext', err)
485 call assert_fails('Xprev', err)
486 call assert_fails('Xnfile', err)
487 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100488 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200489
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100490 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100491 call assert_fails(cmd, 'E42:')
492
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200493 call s:create_test_file('Xqftestfile1')
494 call s:create_test_file('Xqftestfile2')
495
496 Xgetexpr ['Xqftestfile1:5:Line5',
497 \ 'Xqftestfile1:6:Line6',
498 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200499 \ 'Xqftestfile2:11:Line11',
500 \ 'RegularLine1',
501 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200502
503 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100504 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200505 call assert_fails('Xprev', 'E553')
506 call assert_fails('Xpfile', 'E553')
507 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200508 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200509 call assert_equal(10, line('.'))
510 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200511 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200512 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100513 5Xcc
514 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
515 2Xcc
516 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100517 if a:cchar == 'c'
518 cc
519 else
520 ll
521 endif
522 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100523 10Xcc
524 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200526 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200527 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528 call assert_equal(11, line('.'))
529 call assert_fails('Xnext', 'E553')
530 call assert_fails('Xnfile', 'E553')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100531 " To process the range using quickfix list entries, directly use the
532 " quickfix commands (don't use the user defined commands)
533 if a:cchar == 'c'
534 $cc
535 else
536 $ll
537 endif
538 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200539 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200540 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200541 call assert_equal(5, line('.'))
542
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200543 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200544 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200545 call assert_equal(11, line('.'))
546 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200547 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 call assert_equal(5, line('.'))
549
Bram Moolenaar74240d32017-12-10 15:26:15 +0100550 " Jumping to an error from the error window using cc command
551 Xgetexpr ['Xqftestfile1:5:Line5',
552 \ 'Xqftestfile1:6:Line6',
553 \ 'Xqftestfile2:10:Line10',
554 \ 'Xqftestfile2:11:Line11']
555 Xopen
556 10Xcc
557 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200558 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100559 Xopen
560 call cursor(2, 1)
561 if a:cchar == 'c'
562 .cc
563 else
564 .ll
565 endif
566 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200567 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100568
569 " Jumping to an error from the error window (when only the error window is
570 " present)
571 Xopen | only
572 Xlast 1
573 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200574 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100575
Bram Moolenaaree85df32017-03-19 14:19:50 +0100576 Xexpr ""
577 call assert_fails('Xnext', 'E42:')
578
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200579 call delete('Xqftestfile1')
580 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200581
582 " Should be able to use next/prev with invalid entries
583 Xexpr ""
584 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
585 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100586 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200587 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
588 Xlast
589 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
590 Xfirst
591 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
592 2Xnext
593 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100594endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200595
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100596func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200597 call Xtest_browse('c')
598 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100599endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200600
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100601func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200602 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100603 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100604
Bram Moolenaarce90e362019-09-08 18:58:44 +0200605 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100606 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100607
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200608 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100609 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100610
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200611 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100612 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100613
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200614 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100615 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100616
617endfunc
618
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100619func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200620 call s:setup_commands(a:cchar)
621 Xhelpgrep quickfix
622 Xopen
623 if a:cchar == 'c'
624 let title_text = ':helpgrep quickfix'
625 else
626 let title_text = ':lhelpgrep quickfix'
627 endif
628 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200629
630 " Jumping to a help topic should open the help window
631 only
632 Xnext
633 call assert_true(&buftype == 'help')
634 call assert_true(winnr('$') == 2)
635 " Jumping to the next match should reuse the help window
636 Xnext
637 call assert_true(&buftype == 'help')
638 call assert_true(winnr() == 1)
639 call assert_true(winnr('$') == 2)
640 " Jumping to the next match from the quickfix window should reuse the help
641 " window
642 Xopen
643 Xnext
644 call assert_true(&buftype == 'help')
645 call assert_true(winnr() == 1)
646 call assert_true(winnr('$') == 2)
647
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100648 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200649 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100650
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100651 " When the current window is vertically split, jumping to a help match
652 " should open the help window at the top.
653 only | enew
654 let w1 = win_getid()
655 vert new
656 let w2 = win_getid()
657 Xnext
658 let w3 = win_getid()
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100661 " See jump_to_help_window() for details
662 let w2_width = winwidth(w2)
663 if w2_width != &columns && w2_width < 80
664 call assert_equal(['col', [['leaf', w3],
665 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
666 else
667 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
668 \ ['leaf', w1]]] , winlayout())
669 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100670
671 new | only
672 set buftype=help
673 set modified
674 call assert_fails('Xnext', 'E37:')
675 set nomodified
676 new | only
677
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200678 if a:cchar == 'l'
679 " When a help window is present, running :lhelpgrep should reuse the
680 " help window and not the current window
681 new | only
682 call g:Xsetlist([], 'f')
683 help index.txt
684 wincmd w
685 lhelpgrep quickfix
686 call assert_equal(1, winnr())
687 call assert_notequal([], getloclist(1))
688 call assert_equal([], getloclist(2))
689 endif
690
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200691 new | only
692
Bram Moolenaaree85df32017-03-19 14:19:50 +0100693 " Search for non existing help string
694 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200695 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200696 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100697endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200698
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100699func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200700 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200701 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200702 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100703endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100704
Bram Moolenaar6920c722016-01-22 22:44:10 +0100705func Test_errortitle()
706 augroup QfBufWinEnter
707 au!
708 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
709 augroup END
710 copen
711 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'')'}]
712 call setqflist(a)
713 call assert_equal(':setqflist()', g:a)
714 augroup QfBufWinEnter
715 au!
716 augroup END
717 augroup! QfBufWinEnter
718endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100719
Bram Moolenaar5584df62016-03-18 21:00:51 +0100720func Test_vimgreptitle()
721 augroup QfBufWinEnter
722 au!
723 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
724 augroup END
725 try
726 vimgrep /pattern/j file
727 catch /E480/
728 endtry
729 copen
730 call assert_equal(': vimgrep /pattern/j file', g:a)
731 augroup QfBufWinEnter
732 au!
733 augroup END
734 augroup! QfBufWinEnter
735endfunc
736
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100737func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200738 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100739
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200740 Xgetexpr ['file:1:1:message']
741 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100742 if a:cchar == 'c'
743 call setqflist(l, 'r')
744 else
745 call setloclist(0, l, 'r')
746 endif
747
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200748 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100749 if a:cchar == 'c'
750 let title = ':setqflist()'
751 else
752 let title = ':setloclist()'
753 endif
754 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200755 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100756endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100757
758" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100759func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200760 call XqfTitleTests('c')
761 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100762endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100763
764" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100765func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100766 let save_efm = &efm
767 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
768 cgetexpr ['WWWW', 'EEEE', 'CCCC']
769 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
770 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
771 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
772 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
773 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
774 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
775 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
776 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
777 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100778endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100779
780" This will test for problems in quickfix:
781" A. incorrectly copying location lists which caused the location list to show
782" a different name than the file that was actually being displayed.
783" B. not reusing the window for which the location list window is opened but
784" instead creating new windows.
785" C. make sure that the location list window is not reused instead of the
786" window it belongs to.
787"
788" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100789func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100790 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
791 let word = substitute(base, '\v(.*)\..*', '\1', '')
792
793 setl modifiable
794 setl noreadonly
795 setl noswapfile
796 setl bufhidden=delete
797 %del _
798 " For problem 2:
799 " 'buftype' has to be set to reproduce the constant opening of new windows
800 setl buftype=nofile
801
802 call setline(1, word)
803
804 setl nomodified
805 setl nomodifiable
806 setl readonly
807 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100808endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100809
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100810func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200811 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100812
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200813 augroup testgroup
814 au!
815 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
816 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100817
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200818 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100819
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200820 let qflist = []
821 for word in words
822 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
823 " NOTE: problem 1:
824 " intentionally not setting 'lnum' so that the quickfix entries are not
825 " valid
826 eval qflist->setloclist(0, ' ')
827 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100828
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200829 " Test A
830 lrewind
831 enew
832 lopen
833 4lnext
834 vert split
835 wincmd L
836 lopen
837 wincmd p
838 lnext
839 let fileName = expand("%")
840 wincmd p
841 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
842 let fileName = substitute(fileName, '\\', '/', 'g')
843 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
844 call assert_equal("test://bar.txt", fileName)
845 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100846
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200847 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100848
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200849 " Test B:
850 lrewind
851 lopen
852 2
853 exe "normal \<CR>"
854 wincmd p
855 3
856 exe "normal \<CR>"
857 wincmd p
858 4
859 exe "normal \<CR>"
860 call assert_equal(2, winnr('$'))
861 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100862
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200863 " Test C:
864 lrewind
865 lopen
866 " Let's move the location list window to the top to check whether it (the
867 " first window found) will be reused when we try to open new windows:
868 wincmd K
869 2
870 exe "normal \<CR>"
871 wincmd p
872 3
873 exe "normal \<CR>"
874 wincmd p
875 4
876 exe "normal \<CR>"
877 1wincmd w
878 call assert_equal('quickfix', &buftype)
879 2wincmd w
880 let bufferName = expand("%")
881 let bufferName = substitute(bufferName, '\\', '/', 'g')
882 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100883
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200884 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100885
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200886 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100887endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100888
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100889func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200890 augroup testgroup
891 au!
892 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
893 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100894
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200895 func! R(n)
896 quit
897 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100898
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200899 new
900 let q = []
901 call add(q, {'filename': 'test_curwin.txt' })
902 call setloclist(0, q)
903 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100904
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200905 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100906endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100907
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100908func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200909 call writefile(['loclistfoo'], 'loclistfoo')
910 call writefile(['loclistbar'], 'loclistbar')
911 set switchbuf=usetab
912
913 edit loclistfoo
914 tabedit loclistbar
915 silent lgrep loclistfoo loclist*
916 call assert_equal(1, tabpagenr())
917
918 enew | only | tabonly
919 set switchbuf&vim
920 call delete('loclistfoo')
921 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100922endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200923
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100924" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100925func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200926 " The 'errorformat' setting is different on non-Unix systems.
927 " This test works only on Unix-like systems.
928 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100929
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200930 let l =<< trim [DATA]
931 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
932 "Xtestfile", line 6 col 19; this is an error
933 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
934 Xtestfile:9: parse error before `asd'
935 make: *** [vim] Error 1
936 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100937
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200938 2 returned
939 "Xtestfile", line 11 col 1; this is an error
940 "Xtestfile", line 12 col 2; this is another error
941 "Xtestfile", line 14:10; this is an error in column 10
942 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
943 "Xtestfile", linenr 16: yet another problem
944 Error in "Xtestfile" at line 17:
945 x should be a dot
946 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
947 ^
948 Error in "Xtestfile" at line 18:
949 x should be a dot
950 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
951 .............^
952 Error in "Xtestfile" at line 19:
953 x should be a dot
954 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
955 --------------^
956 Error in "Xtestfile" at line 20:
957 x should be a dot
958 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
959 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100960
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200961 Does anyone know what is the problem and how to correction it?
962 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
963 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
964 [DATA]
965
966 call writefile(l, 'Xerrorfile1')
967 call writefile(l[:-2], 'Xerrorfile2')
968
969 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200970 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
971 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
987 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
988 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
989 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
991[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200992 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100993
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200994 let save_efm = &efm
995 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
996 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100997
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200998 exe 'cf Xerrorfile2'
999 clast
1000 copen
1001 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1002 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001003
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001004 exe 'cf Xerrorfile1'
1005 call assert_equal([4, 12], [line('.'), col('.')])
1006 cn
1007 call assert_equal([6, 19], [line('.'), col('.')])
1008 cn
1009 call assert_equal([9, 2], [line('.'), col('.')])
1010 cn
1011 call assert_equal([10, 2], [line('.'), col('.')])
1012 cn
1013 call assert_equal([11, 1], [line('.'), col('.')])
1014 cn
1015 call assert_equal([12, 2], [line('.'), col('.')])
1016 cn
1017 call assert_equal([14, 10], [line('.'), col('.')])
1018 cn
1019 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1020 cn
1021 call assert_equal([16, 2], [line('.'), col('.')])
1022 cn
1023 call assert_equal([17, 6], [line('.'), col('.')])
1024 cn
1025 call assert_equal([18, 7], [line('.'), col('.')])
1026 cn
1027 call assert_equal([19, 8], [line('.'), col('.')])
1028 cn
1029 call assert_equal([20, 9], [line('.'), col('.')])
1030 clast
1031 cprev
1032 cprev
1033 wincmd w
1034 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1035 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001036
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001037 let &efm = save_efm
1038 call delete('Xerrorfile1')
1039 call delete('Xerrorfile2')
1040 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001041endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001042
Bram Moolenaarab47c612016-06-14 22:02:26 +02001043" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001044func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001045 call s:setup_commands(a:cchar)
1046
Bram Moolenaarab47c612016-06-14 22:02:26 +02001047 let save_efm=&efm
1048 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1049
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001050 let lines = ["Entering dir 'dir1/a'",
1051 \ 'habits2.txt:1:Nine Healthy Habits',
1052 \ "Entering dir 'b'",
1053 \ 'habits3.txt:2:0 Hours of television',
1054 \ 'habits2.txt:7:5 Small meals',
1055 \ "Entering dir 'dir1/c'",
1056 \ 'habits4.txt:3:1 Hour of exercise',
1057 \ "Leaving dir 'dir1/c'",
1058 \ "Leaving dir 'dir1/a'",
1059 \ 'habits1.txt:4:2 Liters of water',
1060 \ "Entering dir 'dir2'",
1061 \ 'habits5.txt:5:3 Cups of hot green tea',
1062 \ "Leaving dir 'dir2'"
1063 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001064
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001065 Xexpr ""
1066 for l in lines
1067 Xaddexpr l
1068 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001069
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001070 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001071
1072 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1073 call assert_equal(1, qf[1].lnum)
1074 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1075 call assert_equal(2, qf[3].lnum)
1076 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1077 call assert_equal(7, qf[4].lnum)
1078 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1079 call assert_equal(3, qf[6].lnum)
1080 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1081 call assert_equal(4, qf[9].lnum)
1082 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1083 call assert_equal(5, qf[11].lnum)
1084
1085 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001086endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001087
1088" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001089func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001090 " Create the directory stack and files
1091 call mkdir('dir1')
1092 call mkdir('dir1/a')
1093 call mkdir('dir1/a/b')
1094 call mkdir('dir1/c')
1095 call mkdir('dir2')
1096
1097 let lines = ["Nine Healthy Habits",
1098 \ "0 Hours of television",
1099 \ "1 Hour of exercise",
1100 \ "2 Liters of water",
1101 \ "3 Cups of hot green tea",
1102 \ "4 Short mental breaks",
1103 \ "5 Small meals",
1104 \ "6 AM wake up time",
1105 \ "7 Minutes of laughter",
1106 \ "8 Hours of sleep (at least)",
1107 \ "9 PM end of the day and off to bed"
1108 \ ]
1109 call writefile(lines, 'habits1.txt')
1110 call writefile(lines, 'dir1/a/habits2.txt')
1111 call writefile(lines, 'dir1/a/b/habits3.txt')
1112 call writefile(lines, 'dir1/c/habits4.txt')
1113 call writefile(lines, 'dir2/habits5.txt')
1114
1115 call s:dir_stack_tests('c')
1116 call s:dir_stack_tests('l')
1117
1118 call delete('dir1', 'rf')
1119 call delete('dir2', 'rf')
1120 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001121endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001122
Bram Moolenaar9b457942016-10-09 16:10:05 +02001123" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001124func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001125 call s:setup_commands(a:cchar)
1126
1127 let save_efm = &efm
1128
1129 let &efm =
1130 \ '%Eerror %m %l,' .
1131 \ '%-Wignored %m %l,' .
1132 \ '%+Cmore ignored %m %l,' .
1133 \ '%Zignored end'
1134 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1135 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1136 call assert_equal([['resync', 1, 4, 'E']], l)
1137
1138 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001139endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001140
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001141func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001142 call Xefm_ignore_continuations('c')
1143 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001144endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001145
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001146" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001147func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001148 call s:setup_commands(a:cchar)
1149
Bram Moolenaar049cba92016-06-26 14:38:04 +02001150 let save_efm = &efm
1151
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001152 set efm=%f:%l:%m,%f:%f:%l:%m
1153 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1154
1155 set efm=%f:%l:%m,%f:%l:%r:%m
1156 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1157
1158 set efm=%f:%l:%m,%O:%f:%l:%m
1159 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1160
1161 set efm=%f:%l:%m,%f:%l:%*[^a-z
1162 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1163
1164 set efm=%f:%l:%m,%f:%l:%*c
1165 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1166
1167 set efm=%f:%l:%m,%L%M%N
1168 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1169
1170 set efm=%f:%l:%m,%f:%l:%m:%R
1171 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1172
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001173 " Invalid regular expression
1174 set efm=%\\%%k
1175 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1176
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001177 set efm=
1178 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1179
1180 set efm=%DEntering\ dir\ abc,%f:%l:%m
1181 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1182
1183 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001184endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001185
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001186func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001187 call Xinvalid_efm_Tests('c')
1188 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001189endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001190
1191" TODO:
1192" Add tests for the following formats in 'errorformat'
1193" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001194func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001195 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001196
1197 " Test for %s format in efm
1198 set efm=%f:%s
1199 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001200 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001201 call assert_equal('^\VLine search text\$', l[0].pattern)
1202 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001203
Bram Moolenaaree85df32017-03-19 14:19:50 +01001204 let l = split(execute('clist', ''), "\n")
1205 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1206
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001207 " Test for a long line
1208 cexpr 'Xtestfile:' . repeat('a', 1026)
1209 let l = getqflist()
1210 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1211
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001212 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001213 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001214 [Xtestfile1]
1215 (1,17) error: ';' missing
1216 (21,2) warning: variable 'z' not defined
1217 (67,3) error: end of file found before string ended
1218 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001219
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001220 [Xtestfile2]
1221 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001222
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001223 [Xtestfile3]
1224 NEW compiler v1.1
1225 (2,2) warning: variable 'x' not defined
1226 (67,3) warning: 's' already defined
1227 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001228 [DATA]
1229
Bram Moolenaaree85df32017-03-19 14:19:50 +01001230 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001231 " To exercise the push/pop file functionality in quickfix, the test files
1232 " need to be created.
1233 call writefile(['Line1'], 'Xtestfile1')
1234 call writefile(['Line2'], 'Xtestfile2')
1235 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001236 cexpr ""
1237 for l in lines
1238 caddexpr l
1239 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001240 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001241 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001242 call assert_equal(21, l[2].lnum)
1243 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001244 call assert_equal('w', l[2].type)
1245 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001246 call delete('Xtestfile1')
1247 call delete('Xtestfile2')
1248 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001249
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001250 " Test for %P, %Q with non-existing files
1251 cexpr lines
1252 let l = getqflist()
1253 call assert_equal(14, len(l))
1254 call assert_equal('[Xtestfile1]', l[0].text)
1255 call assert_equal('[Xtestfile2]', l[6].text)
1256 call assert_equal('[Xtestfile3]', l[9].text)
1257
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001258 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001259 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001260 Error 275
1261 line 42
1262 column 3
1263 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001264 [DATA]
1265
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001266 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1267 cgetexpr lines
1268 let l = getqflist()
1269 call assert_equal(275, l[0].nr)
1270 call assert_equal(42, l[0].lnum)
1271 call assert_equal(3, l[0].col)
1272 call assert_equal('E', l[0].type)
1273 call assert_equal("\n' ' expected after '--'", l[0].text)
1274
1275 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001276 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001277 Error in line 147 of foo.c:
1278 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001279 [DATA]
1280
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001281 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1282 cgetexpr lines
1283 let l = getqflist()
1284 call assert_equal(147, l[0].lnum)
1285 call assert_equal('E', l[0].type)
1286 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001287
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001288 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001289 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001290 ==============================================================
1291 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1292 --------------------------------------------------------------
1293 Traceback (most recent call last):
1294 File "unittests/dbfacadeTest.py", line 89, in testFoo
1295 self.assertEquals(34, dtid)
1296 File "/usr/lib/python2.2/unittest.py", line 286, in
1297 failUnlessEqual
1298 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001299 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001300
1301 --------------------------------------------------------------
1302 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001303 [DATA]
1304
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001305 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001306 cgetexpr lines
1307 let l = getqflist()
1308 call assert_equal(8, len(l))
1309 call assert_equal(89, l[4].lnum)
1310 call assert_equal(1, l[4].valid)
1311 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001312 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001313
Bram Moolenaard76ce852018-05-01 15:02:04 +02001314 " Test for %o
1315 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001316 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1317 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001318 let l = getqflist()
1319 call assert_equal(1, len(l), string(l))
1320 call assert_equal('Language.PureScript.Types', l[0].module)
1321 copen
1322 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1323 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001324 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001325 cclose
1326 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001327 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001328
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001329 " Test for a long module name
1330 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1331 let l = getqflist()
1332 call assert_equal(repeat('m', 1024), l[0].module)
1333 call assert_equal(15, l[0].lnum)
1334 call assert_equal('message', l[0].text)
1335
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001336 " The following sequence of commands used to crash Vim
1337 set efm=%W%m
1338 cgetexpr ['msg1']
1339 let l = getqflist()
1340 call assert_equal(1, len(l), string(l))
1341 call assert_equal('msg1', l[0].text)
1342 set efm=%C%m
1343 lexpr 'msg2'
1344 let l = getloclist(0)
1345 call assert_equal(1, len(l), string(l))
1346 call assert_equal('msg2', l[0].text)
1347 lopen
1348 call setqflist([], 'r')
1349 caddbuf
1350 let l = getqflist()
1351 call assert_equal(1, len(l), string(l))
1352 call assert_equal('|| msg2', l[0].text)
1353
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001354 " When matching error lines, case should be ignored. Test for this.
1355 set noignorecase
1356 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1357 call assert_equal(10, l.items[0].lnum)
1358 call assert_equal('Line 20', l.items[0].text)
1359 set ignorecase&
1360
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001361 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001362 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001363endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001364
Bram Moolenaare9283662020-06-07 14:10:47 +02001365" Test for '%t' (error type) field in 'efm'
1366func Test_efm_error_type()
1367 let save_efm = &efm
1368
1369 " error type
1370 set efm=%f:%l:%t:%m
1371 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1372 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1373 let output = split(execute('clist'), "\n")
1374 call assert_equal([
1375 \ ' 1 Xfile1:10 error: msg1',
1376 \ ' 2 Xfile1:20 warning: msg2',
1377 \ ' 3 Xfile1:30 info: msg3',
1378 \ ' 4 Xfile1:40 note: msg4',
1379 \ ' 5 Xfile1:50 R: msg5'], output)
1380
1381 " error type and a error number
1382 set efm=%f:%l:%t:%n:%m
1383 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1384 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1385 let output = split(execute('clist'), "\n")
1386 call assert_equal([
1387 \ ' 1 Xfile1:10 error 2: msg1',
1388 \ ' 2 Xfile1:20 warning 4: msg2',
1389 \ ' 3 Xfile1:30 info 6: msg3',
1390 \ ' 4 Xfile1:40 note 8: msg4',
1391 \ ' 5 Xfile1:50 R 3: msg5'], output)
1392 let &efm = save_efm
1393endfunc
1394
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001395func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001396 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001397 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001398 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001399 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001400 colder
1401 cgetexpr []
1402 endfunc
1403 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001404 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001405 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001406 lolder
1407 lgetexpr []
1408 endfunc
1409 endif
1410
1411 augroup testgroup
1412 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001413 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001414 augroup END
1415
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001416 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001417 let words = [ "a", "b" ]
1418 let qflist = []
1419 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001420 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001421 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001422 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001423 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001424
1425 augroup! testgroup
1426endfunc
1427
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001428func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001429 call XquickfixChangedByAutocmd('c')
1430 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001431endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001432
1433func Test_caddbuffer_to_empty()
1434 helpgr quickfix
1435 call setqflist([], 'r')
1436 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001437 try
1438 cn
1439 catch
1440 " number of matches is unknown
1441 call assert_true(v:exception =~ 'E553:')
1442 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001443 quit!
1444endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001445
1446func Test_cgetexpr_works()
1447 " this must not crash Vim
1448 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001449 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001450endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001451
1452" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001453func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001454 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001455
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001456 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001457 \ {'bufnr': a:bnum, 'lnum': 2}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001458 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001459 call assert_equal(2, len(l))
1460 call assert_equal(2, l[1].lnum)
1461
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001462 Xnext
1463 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1464 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001465 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001466 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001467 call assert_equal(3, line('.'))
1468
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001469 " Appending entries to the list should not change the cursor position
1470 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001471 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001472 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001473 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001474 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1475 call assert_equal(1, line('.'))
1476 close
1477
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001478 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001479 \ {'bufnr': a:bnum, 'lnum': 4},
1480 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001481 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001482 call assert_equal(3, len(l))
1483 call assert_equal(5, l[2].lnum)
1484
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001485 call g:Xsetlist([])
1486 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001487 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001488
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001489 " Tests for setting the 'valid' flag
1490 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1491 Xwindow
1492 call assert_equal(1, winnr('$'))
1493 let l = g:Xgetlist()
1494 call g:Xsetlist(l)
1495 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001496 " Adding a non-valid entry should not mark the list as having valid entries
1497 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1498 Xwindow
1499 call assert_equal(1, winnr('$'))
1500
1501 " :cnext/:cprev should still work even with invalid entries in the list
1502 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1503 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1504 call g:Xsetlist(l)
1505 Xnext
1506 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1507 Xprev
1508 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1509 " :cnext/:cprev should still work after appending invalid entries to an
1510 " empty list
1511 call g:Xsetlist([])
1512 call g:Xsetlist(l, 'a')
1513 Xnext
1514 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1515 Xprev
1516 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1517
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001518 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1519 Xwindow
1520 call assert_equal(2, winnr('$'))
1521 Xclose
1522 let save_efm = &efm
1523 set efm=%m
1524 Xgetexpr 'TestMessage'
1525 let l = g:Xgetlist()
1526 call g:Xsetlist(l)
1527 call assert_equal(1, g:Xgetlist()[0].valid)
1528 let &efm = save_efm
1529
Bram Moolenaaree85df32017-03-19 14:19:50 +01001530 " Error cases:
1531 " Refer to a non-existing buffer and pass a non-dictionary type
1532 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1533 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1534 call g:Xsetlist([[1, 2,3]])
1535 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001536 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001537endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001538
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001539func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001540 new Xtestfile | only
1541 let bnum = bufnr('%')
1542 call setline(1, range(1,5))
1543
1544 call SetXlistTests('c', bnum)
1545 call SetXlistTests('l', bnum)
1546
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001547 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001548 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001549endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001550
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001551func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001552 call s:setup_commands(a:cchar)
1553
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001554 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001555 let @/ = 'Test_'
1556 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001557 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001558 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 Xvimgrep empty test_quickfix.vim
1560 call assert_true(len(g:Xgetlist()) > 0)
1561 Xvimgrep matches test_quickfix.vim
1562 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001563 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001564 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001565 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001566 call g:Xsetlist([], 'r')
1567 call assert_true(len(g:Xgetlist()) == 0)
1568 Xolder
1569 call assert_equal(testlen, len(g:Xgetlist()))
1570 Xnewer
1571 Xnewer
1572 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001573endfunc
1574
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001575func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001576 call Xlist_empty_middle('c')
1577 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001578endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001579
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001580func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001581 call s:setup_commands(a:cchar)
1582
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001583 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001584 Xvimgrep one test_quickfix.vim
1585 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001586 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001587 Xvimgrep two test_quickfix.vim
1588 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001589 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001590 Xvimgrep three test_quickfix.vim
1591 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001592 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001593 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001594 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001595 call g:Xsetlist([], 'r')
1596 call assert_true(len(g:Xgetlist()) == 0)
1597 Xnewer
1598 call assert_equal(twolen, len(g:Xgetlist()))
1599 Xnewer
1600 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001601endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001602
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001603func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001604 call Xlist_empty_older('c')
1605 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001606endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001607
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001608func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001609 call s:setup_commands(a:cchar)
1610
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001611 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1612 \ {'filename': 'fnameB', 'text': 'B'}]
1613 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1614 \ {'filename': 'fnameD', 'text': 'D'},
1615 \ {'filename': 'fnameE', 'text': 'E'}]
1616
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001617 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001618 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001619 silent! Xnewer 99
1620 call g:Xsetlist(list1)
1621 call g:Xsetlist(list2)
1622 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001623 call assert_equal(3, len(li))
1624 call assert_equal('C', li[0]['text'])
1625 call assert_equal('D', li[1]['text'])
1626 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001627 silent! Xolder
1628 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001629 call assert_equal(2, len(li))
1630 call assert_equal('A', li[0]['text'])
1631 call assert_equal('B', li[1]['text'])
1632
1633 " {action} is specified ' '.
1634 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001635 silent! Xnewer 99
1636 call g:Xsetlist(list1)
1637 call g:Xsetlist(list2, ' ')
1638 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001639 call assert_equal(3, len(li))
1640 call assert_equal('C', li[0]['text'])
1641 call assert_equal('D', li[1]['text'])
1642 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001643 silent! Xolder
1644 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001645 call assert_equal(2, len(li))
1646 call assert_equal('A', li[0]['text'])
1647 call assert_equal('B', li[1]['text'])
1648
1649 " {action} is specified 'a'.
1650 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001651 silent! Xnewer 99
1652 call g:Xsetlist(list1)
1653 call g:Xsetlist(list2, 'a')
1654 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001655 call assert_equal(5, len(li))
1656 call assert_equal('A', li[0]['text'])
1657 call assert_equal('B', li[1]['text'])
1658 call assert_equal('C', li[2]['text'])
1659 call assert_equal('D', li[3]['text'])
1660 call assert_equal('E', li[4]['text'])
1661
1662 " {action} is specified 'r'.
1663 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001664 silent! Xnewer 99
1665 call g:Xsetlist(list1)
1666 call g:Xsetlist(list2, 'r')
1667 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001668 call assert_equal(3, len(li))
1669 call assert_equal('C', li[0]['text'])
1670 call assert_equal('D', li[1]['text'])
1671 call assert_equal('E', li[2]['text'])
1672
1673 " Test for wrong value.
1674 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001675 call assert_fails("call g:Xsetlist(0)", 'E714:')
1676 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1677 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1678 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1679 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001680endfunc
1681
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001682func Test_setqflist_invalid_nr()
1683 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001684 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001685endfunc
1686
Bram Moolenaar99234f22020-02-10 22:56:54 +01001687func Test_setqflist_user_sets_buftype()
1688 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1689 set buftype=quickfix
1690 call setqflist([], 'a')
1691 enew
1692endfunc
1693
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001694func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001695 call XquickfixSetListWithAct('c')
1696 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001697endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001698
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001699func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001700 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001701
Bram Moolenaar049cba92016-06-26 14:38:04 +02001702 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001703 call assert_equal(1, l[0].lnum)
1704 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001705 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001706 call assert_equal(2, l[1].lnum)
1707 call assert_equal(1, l[1].col)
1708 call assert_equal(4070, len(l[1].text))
1709 call assert_equal(3, l[2].lnum)
1710 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001711 call assert_equal(4070, len(l[2].text))
1712 call assert_equal(4, l[3].lnum)
1713 call assert_equal(1, l[3].col)
1714 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001715
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001716 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001717endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001718
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001719func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001720 call s:setup_commands(a:cchar)
1721
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001722 let testfile = 'samples/quickfix.txt'
1723
1724 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001725 exe 'Xgetfile' testfile
1726 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001727
1728 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001729 Xexpr readfile(testfile)
1730 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001731
1732 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001733 Xexpr join(readfile(testfile), "\n")
1734 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001735
1736 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001737 exe 'edit' testfile
1738 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001739 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001740endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001741
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001742func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001743 call s:long_lines_tests('c')
1744 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001745endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001746
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001747func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001748 let l = []
1749 for i in range(1, 20)
1750 call add(l, 'Line' . i)
1751 endfor
1752 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001753endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001754
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001755func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001756 call s:create_test_file('Xqftestfile1')
1757 call s:create_test_file('Xqftestfile2')
1758 call s:create_test_file('Xqftestfile3')
1759
1760 new | only
1761 edit Xqftestfile1
1762 let file1_winid = win_getid()
1763 new Xqftestfile2
1764 let file2_winid = win_getid()
1765 cgetexpr ['Xqftestfile1:5:Line5',
1766 \ 'Xqftestfile1:6:Line6',
1767 \ 'Xqftestfile2:10:Line10',
1768 \ 'Xqftestfile2:11:Line11',
1769 \ 'Xqftestfile3:15:Line15',
1770 \ 'Xqftestfile3:16:Line16']
1771
1772 new
1773 let winid = win_getid()
1774 cfirst | cnext
1775 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001776 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001777 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001778 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001779 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001780
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001781 " Test for 'switchbuf' set to search for files in windows in the current
1782 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001783 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001784 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001785 cfirst | cnext
1786 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001787 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001788 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001789 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001790 call assert_equal(file2_winid, win_getid())
1791
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001792 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1793 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001794 enew | only
1795 set switchbuf=usetab
1796 tabedit Xqftestfile1
1797 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001798 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001799 tabfirst
1800 cfirst | cnext
1801 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001802 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001803 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001804 6cnext
1805 call assert_equal(4, tabpagenr())
1806 2cpfile
1807 call assert_equal(2, tabpagenr())
1808 2cnfile
1809 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001810 tabfirst | tabonly | enew
1811
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001812 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001813 set switchbuf=split
1814 cfirst | cnext
1815 call assert_equal(1, winnr('$'))
1816 cnext | cnext
1817 call assert_equal(2, winnr('$'))
1818 cnext | cnext
1819 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001820
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001821 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001822 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001823 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001824 cfirst | cnext
1825 call assert_equal(1, tabpagenr('$'))
1826 cnext | cnext
1827 call assert_equal(2, tabpagenr('$'))
1828 cnext | cnext
1829 call assert_equal(3, tabpagenr('$'))
1830 tabfirst | enew | tabonly | only
1831
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001832 set switchbuf=uselast
1833 split
1834 let last_winid = win_getid()
1835 copen
1836 exe "normal 1G\<CR>"
1837 call assert_equal(last_winid, win_getid())
1838 enew | only
1839
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001840 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1841 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001842 set switchbuf=
1843 edit Xqftestfile1
1844 let file1_winid = win_getid()
1845 new Xqftestfile2
1846 let file2_winid = win_getid()
1847 copen
1848 exe "normal 1G\<CR>"
1849 call assert_equal(file1_winid, win_getid())
1850 copen
1851 exe "normal 3G\<CR>"
1852 call assert_equal(file2_winid, win_getid())
1853 copen | only
1854 exe "normal 5G\<CR>"
1855 call assert_equal(2, winnr('$'))
1856 call assert_equal(1, bufwinnr('Xqftestfile3'))
1857
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001858 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001859 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001860 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001861 set switchbuf=usetab
1862 tabedit Xqftestfile1
1863 tabedit Xqftestfile2
1864 tabedit Xqftestfile3
1865 tabfirst
1866 copen | only
1867 clast
1868 call assert_equal(4, tabpagenr())
1869 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001870
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001871 " Jumping to a file that is not present in any of the tabpages and the
1872 " current tabpage doesn't have any usable windows, should open it in a new
1873 " window in the current tabpage.
1874 copen | only
1875 cfirst
1876 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001877 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001878
1879 " If opening a file changes 'switchbuf', then the new value should be
1880 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001881 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001882 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1883 enew | only
1884 set switchbuf&vim
1885 cexpr "Xqftestfile1:1:10"
1886 call assert_equal('split', &switchbuf)
1887 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1888 enew | only
1889 set switchbuf=useopen
1890 cexpr "Xqftestfile1:1:10"
1891 call assert_equal('usetab', &switchbuf)
1892 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1893 enew | only
1894 set switchbuf=useopen
1895 cexpr "Xqftestfile1:1:10"
1896 call assert_equal('', &switchbuf)
1897
Bram Moolenaar049cba92016-06-26 14:38:04 +02001898 call delete('Xqftestfile1')
1899 call delete('Xqftestfile2')
1900 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001901 set switchbuf&vim
1902
1903 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001904endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001905
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001906func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001907 call s:setup_commands(a:cchar)
1908
1909 enew | only
1910
Bram Moolenaarc1542742016-07-20 21:44:37 +02001911 let fname = 'Xqftestfile' . a:cchar
1912 call s:create_test_file(fname)
1913 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02001914
Bram Moolenaarc1542742016-07-20 21:44:37 +02001915 Xgetexpr [fname . ':5:Line5',
1916 \ fname . ':10:Line10',
1917 \ fname . ':15:Line15',
1918 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02001919
1920 6,14delete
1921 call append(6, ['Buffer', 'Window'])
1922
1923 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001924 call assert_equal(5, l[0].lnum)
1925 call assert_equal(6, l[2].lnum)
1926 call assert_equal(13, l[3].lnum)
1927
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001928 " If a file doesn't have any quickfix entries, then deleting lines in the
1929 " file should not update the quickfix list
1930 call g:Xsetlist([], 'f')
1931 1,2delete
1932 call assert_equal([], g:Xgetlist())
1933
Bram Moolenaar049cba92016-06-26 14:38:04 +02001934 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02001935 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001936endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001937
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001938func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02001939 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001940 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02001941 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001942 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001943endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001944
1945" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001946func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001947 call s:setup_commands(a:cchar)
1948
1949 " The following lines are used for the grep test. Don't remove.
1950 " Grep_Test_Text: Match 1
1951 " Grep_Test_Text: Match 2
1952 " GrepAdd_Test_Text: Match 1
1953 " GrepAdd_Test_Text: Match 2
1954 enew! | only
1955 set makeef&vim
1956 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001957 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001958 Xopen
1959 call assert_true(w:quickfix_title =~ '^:grep')
1960 Xclose
1961 enew
1962 set makeef=Temp_File_##
1963 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001964 call assert_true(len(g:Xgetlist()) == 9)
1965
1966 " Try with 'grepprg' set to 'internal'
1967 set grepprg=internal
1968 silent Xgrep Grep_Test_Text: test_quickfix.vim
1969 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1970 call assert_true(len(g:Xgetlist()) == 9)
1971 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001972
1973 call writefile(['Vim'], 'XtestTempFile')
1974 set makeef=XtestTempFile
1975 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001976 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001977 call assert_false(filereadable('XtestTempFile'))
1978 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001979endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001980
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001981func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001982 " The grepprg may not be set on non-Unix systems
1983 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02001984
1985 call s:test_xgrep('c')
1986 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001987endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001988
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001989func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001990 " Use one 'errorformat' for two windows. Add an expression to each of them,
1991 " make sure they each keep their own state.
1992 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1993 call mkdir('Xone/a', 'p')
1994 call mkdir('Xtwo/a', 'p')
1995 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1996 call writefile(lines, 'Xone/a/one.txt')
1997 call writefile(lines, 'Xtwo/a/two.txt')
1998
1999 new one
2000 let one_id = win_getid()
2001 lexpr ""
2002 new two
2003 let two_id = win_getid()
2004 lexpr ""
2005
2006 laddexpr "Entering dir 'Xtwo/a'"
2007 call win_gotoid(one_id)
2008 laddexpr "Entering dir 'Xone/a'"
2009 call win_gotoid(two_id)
2010 laddexpr 'two.txt:5:two two two'
2011 call win_gotoid(one_id)
2012 laddexpr 'one.txt:3:one one one'
2013
2014 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002015 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2016 call assert_equal(3, loc_one[1].lnum)
2017
2018 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002019 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2020 call assert_equal(5, loc_two[1].lnum)
2021
2022 call win_gotoid(one_id)
2023 bwipe!
2024 call win_gotoid(two_id)
2025 bwipe!
2026 call delete('Xone', 'rf')
2027 call delete('Xtwo', 'rf')
2028endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002029
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002030func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002031 call s:setup_commands(a:cchar)
2032
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002033 " Calling lbottom without any errors should fail
2034 if a:cchar == 'l'
2035 call assert_fails('lbottom', 'E776:')
2036 endif
2037
Bram Moolenaar875feea2017-06-11 16:07:51 +02002038 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002039 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002040 let wid = win_getid()
2041 call assert_equal(1, line('.'))
2042 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002043 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002044 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002045 call win_gotoid(wid)
2046 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002047 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002048endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002049
2050" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002051func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002052 call XbottomTests('c')
2053 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002054endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002055
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002056func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002057 call s:setup_commands(a:cchar)
2058
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002059 " clear all lists after the first one, then replace the first one.
2060 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002061 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002062 let entry = {'filename': 'foo', 'lnum': 42}
2063 call g:Xsetlist([entry], 'r')
2064 call g:Xsetlist([entry, entry])
2065 call g:Xsetlist([entry, entry, entry])
2066 let res = split(execute(a:cchar . 'hist'), "\n")
2067 call assert_equal(3, len(res))
2068 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2069 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2070 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2071 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002072
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002073 " Test for changing the quickfix lists
2074 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2075 exe '1' . a:cchar . 'hist'
2076 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2077 exe '3' . a:cchar . 'hist'
2078 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2079 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2080 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2081
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002082 call g:Xsetlist([], 'f')
2083 let l = split(execute(a:cchar . 'hist'), "\n")
2084 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002085 if a:cchar == 'c'
2086 call assert_fails('4chist', 'E16:')
2087 else
2088 call assert_fails('4lhist', 'E776:')
2089 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002090
2091 " An empty list should still show the stack history
2092 call g:Xsetlist([])
2093 let res = split(execute(a:cchar . 'hist'), "\n")
2094 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2095
2096 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002097endfunc
2098
2099func Test_history()
2100 call HistoryTest('c')
2101 call HistoryTest('l')
2102endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002103
2104func Test_duplicate_buf()
2105 " make sure we can get the highest buffer number
2106 edit DoesNotExist
2107 edit DoesNotExist2
2108 let last_buffer = bufnr("$")
2109
2110 " make sure only one buffer is created
2111 call writefile(['this one', 'that one'], 'Xgrepthis')
2112 vimgrep one Xgrepthis
2113 vimgrep one Xgrepthis
2114 call assert_equal(last_buffer + 1, bufnr("$"))
2115
2116 call delete('Xgrepthis')
2117endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002118
2119" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002120func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002121 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002122
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002123 " Error cases
2124 call assert_fails('call g:Xgetlist(99)', 'E715:')
2125 call assert_fails('call g:Xsetlist(99)', 'E714:')
2126 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002127
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002128 " Set and get the title
2129 call g:Xsetlist([])
2130 Xopen
2131 wincmd p
2132 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2133 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2134 call assert_equal(0, s)
2135 let d = g:Xgetlist({"title":1})
2136 call assert_equal('Sample', d.title)
2137 " Try setting title to a non-string value
2138 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2139 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2140
2141 Xopen
2142 call assert_equal('Sample', w:quickfix_title)
2143 Xclose
2144
2145 " Tests for action argument
2146 silent! Xolder 999
2147 let qfnr = g:Xgetlist({'all':1}).nr
2148 call g:Xsetlist([], 'r', {'title' : 'N1'})
2149 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2150 call g:Xsetlist([], ' ', {'title' : 'N2'})
2151 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2152
2153 let res = g:Xgetlist({'nr': 0})
2154 call assert_equal(qfnr + 1, res.nr)
2155 call assert_equal(['nr'], keys(res))
2156
2157 call g:Xsetlist([], ' ', {'title' : 'N3'})
2158 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2159
2160 " Changing the title of an earlier quickfix list
2161 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2162 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2163
2164 " Changing the title of an invalid quickfix list
2165 call assert_equal(-1, g:Xsetlist([], ' ',
2166 \ {'title' : 'SomeTitle', 'nr' : 99}))
2167 call assert_equal(-1, g:Xsetlist([], ' ',
2168 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2169
2170 if a:cchar == 'c'
2171 copen
2172 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2173 cclose
2174 endif
2175
2176 " Invalid arguments
2177 call assert_fails('call g:Xgetlist([])', 'E715')
2178 call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
2179 let s = g:Xsetlist([], 'a', {'abc':1})
2180 call assert_equal(-1, s)
2181
2182 call assert_equal({}, g:Xgetlist({'abc':1}))
2183 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2184 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2185
2186 if a:cchar == 'l'
2187 call assert_equal({}, getloclist(99, {'title': 1}))
2188 endif
2189
2190 " Context related tests
2191 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2192 call assert_equal(0, s)
2193 call test_garbagecollect_now()
2194 let d = g:Xgetlist({'context':1})
2195 call assert_equal([1,2,3], d.context)
2196 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2197 let d = g:Xgetlist({'context':1})
2198 call assert_equal({'color':'green'}, d.context)
2199 call g:Xsetlist([], 'a', {'context':"Context info"})
2200 let d = g:Xgetlist({'context':1})
2201 call assert_equal("Context info", d.context)
2202 call g:Xsetlist([], 'a', {'context':246})
2203 let d = g:Xgetlist({'context':1})
2204 call assert_equal(246, d.context)
2205 " set other Vim data types as context
2206 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2207 if has('channel')
2208 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2209 endif
2210 if has('job')
2211 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2212 endif
2213 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2214 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2215 call g:Xsetlist([], 'a', {'context' : ''})
2216 call test_garbagecollect_now()
2217 if a:cchar == 'l'
2218 " Test for copying context across two different location lists
2219 new | only
2220 let w1_id = win_getid()
2221 let l = [1]
2222 call setloclist(0, [], 'a', {'context':l})
2223 new
2224 let w2_id = win_getid()
2225 call add(l, 2)
2226 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2227 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2228 unlet! l
2229 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2230 only
2231 call setloclist(0, [], 'f')
2232 call assert_equal('', getloclist(0, {'context':1}).context)
2233 endif
2234
2235 " Test for changing the context of previous quickfix lists
2236 call g:Xsetlist([], 'f')
2237 Xexpr "One"
2238 Xexpr "Two"
2239 Xexpr "Three"
2240 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2241 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2242 " Also, check for setting the context using quickfix list number zero.
2243 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2244 call test_garbagecollect_now()
2245 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2246 call assert_equal([1], l.context)
2247 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2248 call assert_equal([2], l.context)
2249 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2250 call assert_equal([3], l.context)
2251
2252 " Test for changing the context through reference and for garbage
2253 " collection of quickfix context
2254 let l = ["red"]
2255 call g:Xsetlist([], ' ', {'context' : l})
2256 call add(l, "blue")
2257 let x = g:Xgetlist({'context' : 1})
2258 call add(x.context, "green")
2259 call assert_equal(["red", "blue", "green"], l)
2260 call assert_equal(["red", "blue", "green"], x.context)
2261 unlet l
2262 call test_garbagecollect_now()
2263 let m = g:Xgetlist({'context' : 1})
2264 call assert_equal(["red", "blue", "green"], m.context)
2265
2266 " Test for setting/getting items
2267 Xexpr ""
2268 let qfprev = g:Xgetlist({'nr':0})
2269 let s = g:Xsetlist([], ' ', {'title':'Green',
2270 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2271 call assert_equal(0, s)
2272 let qfcur = g:Xgetlist({'nr':0})
2273 call assert_true(qfcur.nr == qfprev.nr + 1)
2274 let l = g:Xgetlist({'items':1})
2275 call assert_equal('F1', bufname(l.items[0].bufnr))
2276 call assert_equal(10, l.items[0].lnum)
2277 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2278 \ {'filename':'F2', 'lnum':30}]})
2279 let l = g:Xgetlist({'items':1})
2280 call assert_equal('F2', bufname(l.items[2].bufnr))
2281 call assert_equal(30, l.items[2].lnum)
2282 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2283 let l = g:Xgetlist({'items':1})
2284 call assert_equal('F3', bufname(l.items[0].bufnr))
2285 call assert_equal(40, l.items[0].lnum)
2286 call g:Xsetlist([], 'r', {'items' : []})
2287 let l = g:Xgetlist({'items':1})
2288 call assert_equal(0, len(l.items))
2289
2290 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2291 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2292 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2293 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2294
2295 " Test for getting id of window associated with a location list window
2296 if a:cchar == 'l'
2297 only
2298 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2299 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002300 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002301 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2302 wincmd w
2303 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2304 only
2305 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002306
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002307 " The following used to crash Vim with address sanitizer
2308 call g:Xsetlist([], 'f')
2309 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2310 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002311
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002312 " Try setting the items using a string
2313 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002314
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002315 " Save and restore the quickfix stack
2316 call g:Xsetlist([], 'f')
2317 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2318 Xexpr "File1:10:Line1"
2319 Xexpr "File2:20:Line2"
2320 Xexpr "File3:30:Line3"
2321 let last_qf = g:Xgetlist({'nr':'$'}).nr
2322 call assert_equal(3, last_qf)
2323 let qstack = []
2324 for i in range(1, last_qf)
2325 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2326 endfor
2327 call g:Xsetlist([], 'f')
2328 for i in range(len(qstack))
2329 call g:Xsetlist([], ' ', qstack[i])
2330 endfor
2331 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2332 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2333 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2334 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2335 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002336
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002337 " Swap two quickfix lists
2338 Xexpr "File1:10:Line10"
2339 Xexpr "File2:20:Line20"
2340 Xexpr "File3:30:Line30"
2341 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2342 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2343 let l1=g:Xgetlist({'nr':1,'all':1})
2344 let l2=g:Xgetlist({'nr':2,'all':1})
2345 let save_id = l1.id
2346 let l1.id=l2.id
2347 let l2.id=save_id
2348 call g:Xsetlist([], 'r', l1)
2349 call g:Xsetlist([], 'r', l2)
2350 let newl1=g:Xgetlist({'nr':1,'all':1})
2351 let newl2=g:Xgetlist({'nr':2,'all':1})
2352 call assert_equal('Fruits', newl1.title)
2353 call assert_equal(['Fruits'], newl1.context)
2354 call assert_equal('Line20', newl1.items[0].text)
2355 call assert_equal('Colors', newl2.title)
2356 call assert_equal(['Colors'], newl2.context)
2357 call assert_equal('Line10', newl2.items[0].text)
2358 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002359
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002360 " Cannot specify both a non-empty list argument and a dict argument
2361 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002362endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002363
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002364func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002365 call Xproperty_tests('c')
2366 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002367endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002368
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002369" Test for setting the current index in the location/quickfix list
2370func Xtest_setqfidx(cchar)
2371 call s:setup_commands(a:cchar)
2372
2373 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2374 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2375 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2376
2377 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2378 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2379 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2380 Xolder 2
2381 Xopen
2382 call assert_equal(3, line('.'))
2383 Xnewer
2384 call assert_equal(2, line('.'))
2385 Xnewer
2386 call assert_equal(2, line('.'))
2387 " Update the current index with the quickfix window open
2388 wincmd w
2389 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2390 Xopen
2391 call assert_equal(3, line('.'))
2392 Xclose
2393
2394 " Set the current index to the last entry
2395 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2396 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2397 " A large value should set the index to the last index
2398 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2400 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2401 " Invalid index values
2402 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2403 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2404 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2405 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2406 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2407 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2408 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2409
2410 call g:Xsetlist([], 'f')
2411 new | only
2412endfunc
2413
2414func Test_setqfidx()
2415 call Xtest_setqfidx('c')
2416 call Xtest_setqfidx('l')
2417endfunc
2418
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002419" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002420func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002421 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002422endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002423
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002424func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002425 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2426 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2427
2428 let g:acmds = []
2429 cexpr "F1:10:Line 10"
2430 caddexpr "F1:20:Line 20"
2431 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002432 cexpr ""
2433 caddexpr ""
2434 cgetexpr ""
2435 silent! cexpr non_existing_func()
2436 silent! caddexpr non_existing_func()
2437 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002438 let l = ['precexpr',
2439 \ 'postcexpr',
2440 \ 'precaddexpr',
2441 \ 'postcaddexpr',
2442 \ 'precgetexpr',
2443 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002444 \ 'precexpr',
2445 \ 'postcexpr',
2446 \ 'precaddexpr',
2447 \ 'postcaddexpr',
2448 \ 'precgetexpr',
2449 \ 'postcgetexpr',
2450 \ 'precexpr',
2451 \ 'precaddexpr',
2452 \ 'precgetexpr']
2453 call assert_equal(l, g:acmds)
2454
2455 let g:acmds = []
2456 enew! | call append(0, "F2:10:Line 10")
2457 cbuffer!
2458 enew! | call append(0, "F2:20:Line 20")
2459 cgetbuffer
2460 enew! | call append(0, "F2:30:Line 30")
2461 caddbuffer
2462 new
2463 let bnum = bufnr('%')
2464 bunload
2465 exe 'silent! cbuffer! ' . bnum
2466 exe 'silent! cgetbuffer ' . bnum
2467 exe 'silent! caddbuffer ' . bnum
2468 enew!
2469 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002470 \ 'postcbuffer',
2471 \ 'precgetbuffer',
2472 \ 'postcgetbuffer',
2473 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002474 \ 'postcaddbuffer',
2475 \ 'precbuffer',
2476 \ 'precgetbuffer',
2477 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002478 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002479
2480 call writefile(['Xtest:1:Line1'], 'Xtest')
2481 call writefile([], 'Xempty')
2482 let g:acmds = []
2483 cfile Xtest
2484 caddfile Xtest
2485 cgetfile Xtest
2486 cfile Xempty
2487 caddfile Xempty
2488 cgetfile Xempty
2489 silent! cfile do_not_exist
2490 silent! caddfile do_not_exist
2491 silent! cgetfile do_not_exist
2492 let l = ['precfile',
2493 \ 'postcfile',
2494 \ 'precaddfile',
2495 \ 'postcaddfile',
2496 \ 'precgetfile',
2497 \ 'postcgetfile',
2498 \ 'precfile',
2499 \ 'postcfile',
2500 \ 'precaddfile',
2501 \ 'postcaddfile',
2502 \ 'precgetfile',
2503 \ 'postcgetfile',
2504 \ 'precfile',
2505 \ 'postcfile',
2506 \ 'precaddfile',
2507 \ 'postcaddfile',
2508 \ 'precgetfile',
2509 \ 'postcgetfile']
2510 call assert_equal(l, g:acmds)
2511
2512 let g:acmds = []
2513 helpgrep quickfix
2514 silent! helpgrep non_existing_help_topic
2515 vimgrep test Xtest
2516 vimgrepadd test Xtest
2517 silent! vimgrep non_existing_test Xtest
2518 silent! vimgrepadd non_existing_test Xtest
2519 set makeprg=
2520 silent! make
2521 set makeprg&
2522 let l = ['prehelpgrep',
2523 \ 'posthelpgrep',
2524 \ 'prehelpgrep',
2525 \ 'posthelpgrep',
2526 \ 'previmgrep',
2527 \ 'postvimgrep',
2528 \ 'previmgrepadd',
2529 \ 'postvimgrepadd',
2530 \ 'previmgrep',
2531 \ 'postvimgrep',
2532 \ 'previmgrepadd',
2533 \ 'postvimgrepadd',
2534 \ 'premake',
2535 \ 'postmake']
2536 call assert_equal(l, g:acmds)
2537
2538 if has('unix')
2539 " Run this test only on Unix-like systems. The grepprg may not be set on
2540 " non-Unix systems.
2541 " The following lines are used for the grep test. Don't remove.
2542 " Grep_Autocmd_Text: Match 1
2543 " GrepAdd_Autocmd_Text: Match 2
2544 let g:acmds = []
2545 silent grep Grep_Autocmd_Text test_quickfix.vim
2546 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2547 silent grep abc123def Xtest
2548 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002549 set grepprg=internal
2550 silent grep Grep_Autocmd_Text test_quickfix.vim
2551 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2552 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2553 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2554 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002555 let l = ['pregrep',
2556 \ 'postgrep',
2557 \ 'pregrepadd',
2558 \ 'postgrepadd',
2559 \ 'pregrep',
2560 \ 'postgrep',
2561 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002562 \ 'postgrepadd',
2563 \ 'pregrep',
2564 \ 'postgrep',
2565 \ 'pregrepadd',
2566 \ 'postgrepadd',
2567 \ 'prelgrep',
2568 \ 'postlgrep',
2569 \ 'prelgrepadd',
2570 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002571 call assert_equal(l, g:acmds)
2572 endif
2573
2574 call delete('Xtest')
2575 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002576 au! QuickFixCmdPre
2577 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002578endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002579
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002580func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002581 set efm=%m
2582 lgetexpr '?'
2583
2584 try
2585 call DoesNotExit()
2586 catch
2587 lgetexpr '1'
2588 finally
2589 lgetexpr '1'
2590 endtry
2591
2592 call assert_equal('1', getloclist(0)[0].text)
2593
2594 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002595endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002596
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002597func Test_caddbuffer_wrong()
2598 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002599 let save_efm = &efm
2600 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2601 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2602 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002603 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002604 bwipe!
2605endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002606
2607func Test_caddexpr_wrong()
2608 " This used to cause a memory access in freed memory.
2609 cbuffer
2610 cbuffer
2611 copen
2612 let save_efm = &efm
2613 set efm=%
2614 call assert_fails('caddexpr ""', 'E376:')
2615 let &efm = save_efm
2616endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002617
2618func Test_dirstack_cleanup()
2619 " This used to cause a memory access in freed memory.
2620 let save_efm = &efm
2621 lexpr '0'
2622 lopen
2623 fun X(c)
2624 let save_efm=&efm
2625 set efm=%D%f
2626 if a:c == 'c'
2627 caddexpr '::'
2628 else
2629 laddexpr ':0:0'
2630 endif
2631 let &efm=save_efm
2632 endfun
2633 call X('c')
2634 call X('l')
2635 call setqflist([], 'r')
2636 caddbuffer
2637 let &efm = save_efm
2638endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002639
2640" Tests for jumping to entries from the location list window and quickfix
2641" window
2642func Test_cwindow_jump()
2643 set efm=%f%%%l%%%m
2644 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2645 lopen | only
2646 lfirst
2647 call assert_true(winnr('$') == 2)
2648 call assert_true(winnr() == 1)
2649 " Location list for the new window should be set
2650 call assert_true(getloclist(0)[2].text == 'Line 30')
2651
2652 " Open a scratch buffer
2653 " Open a new window and create a location list
2654 " Open the location list window and close the other window
2655 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002656 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002657 " should not be used.
2658 enew | only
2659 set buftype=nofile
2660 below new
2661 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2662 lopen
2663 2wincmd c
2664 lnext
2665 call assert_true(winnr('$') == 3)
2666 call assert_true(winnr() == 2)
2667
2668 " Open two windows with two different location lists
2669 " Open the location list window and close the previous window
2670 " Jump to an entry in the location list window
2671 " Should open the file in the first window and not set the location list.
2672 enew | only
2673 lgetexpr ["F1%5%Line 5"]
2674 below new
2675 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2676 lopen
2677 2wincmd c
2678 lnext
2679 call assert_true(winnr() == 1)
2680 call assert_true(getloclist(0)[0].text == 'Line 5')
2681
2682 enew | only
2683 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2684 copen
2685 cnext
2686 call assert_true(winnr('$') == 2)
2687 call assert_true(winnr() == 1)
2688
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002689 " open the quickfix buffer in two windows and jump to an entry. Should open
2690 " the file in the first quickfix window.
2691 enew | only
2692 copen
2693 let bnum = bufnr('')
2694 exe 'sbuffer ' . bnum
2695 wincmd b
2696 cfirst
2697 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002698 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002699 enew | only
2700 exe 'sb' bnum
2701 exe 'botright sb' bnum
2702 wincmd t
2703 clast
2704 call assert_equal(2, winnr())
2705 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2706 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2707
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002708 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002709 " window by wrapping around the window list.
2710 enew | only
2711 call setloclist(0, [], 'f')
2712 new | new
2713 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2714 lopen
2715 1close
2716 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2717 lnext
2718 call assert_equal(3, winnr())
2719 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2720
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002721 enew | only
2722 set efm&vim
2723endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002724
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002725func Test_cwindow_highlight()
2726 CheckScreendump
2727
2728 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002729 call setline(1, ['some', 'text', 'with', 'matches'])
2730 write XCwindow
2731 vimgrep e XCwindow
2732 redraw
2733 cwindow 4
2734 END
2735 call writefile(lines, 'XtestCwindow')
2736 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2737 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2738
2739 call term_sendkeys(buf, ":cnext\<CR>")
2740 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2741
2742 " clean up
2743 call StopVimInTerminal(buf)
2744 call delete('XtestCwindow')
2745 call delete('XCwindow')
2746endfunc
2747
Bram Moolenaaree85df32017-03-19 14:19:50 +01002748func XvimgrepTests(cchar)
2749 call s:setup_commands(a:cchar)
2750
2751 call writefile(['Editor:VIM vim',
2752 \ 'Editor:Emacs EmAcS',
2753 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2754 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2755
2756 " Error cases
2757 call assert_fails('Xvimgrep /abc *', 'E682:')
2758
2759 let @/=''
2760 call assert_fails('Xvimgrep // *', 'E35:')
2761
2762 call assert_fails('Xvimgrep abc', 'E683:')
2763 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2764 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2765
2766 Xexpr ""
2767 Xvimgrepadd Notepad Xtestfile1
2768 Xvimgrepadd MacOS Xtestfile2
2769 let l = g:Xgetlist()
2770 call assert_equal(2, len(l))
2771 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2772
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002773 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002774 let l = g:Xgetlist()
2775 call assert_equal(2, len(l))
2776 call assert_equal(8, l[0].col)
2777 call assert_equal(12, l[1].col)
2778
2779 1Xvimgrep ?Editor? Xtestfile*
2780 let l = g:Xgetlist()
2781 call assert_equal(1, len(l))
2782 call assert_equal('Editor:VIM vim', l[0].text)
2783
2784 edit +3 Xtestfile2
2785 Xvimgrep +\cemacs+j Xtestfile1
2786 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002787 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002788 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2789
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002790 " Test for unloading a buffer after vimgrep searched the buffer
2791 %bwipe
2792 Xvimgrep /Editor/j Xtestfile*
2793 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2794 call assert_equal([], getbufinfo('Xtestfile2'))
2795
Bram Moolenaaree85df32017-03-19 14:19:50 +01002796 call delete('Xtestfile1')
2797 call delete('Xtestfile2')
2798endfunc
2799
2800" Tests for the :vimgrep command
2801func Test_vimgrep()
2802 call XvimgrepTests('c')
2803 call XvimgrepTests('l')
2804endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002805
Bram Moolenaar1c299432018-10-28 14:36:09 +01002806" Test for incsearch highlighting of the :vimgrep pattern
2807" This test used to cause "E315: ml_get: invalid lnum" errors.
2808func Test_vimgrep_incsearch()
2809 enew
2810 set incsearch
2811 call test_override("char_avail", 1)
2812
2813 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2814 let l = getqflist()
2815 call assert_equal(2, len(l))
2816
2817 call test_override("ALL", 0)
2818 set noincsearch
2819endfunc
2820
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002821" Test vimgrep with the last search pattern not set
2822func Test_vimgrep_with_no_last_search_pat()
2823 let lines =<< trim [SCRIPT]
2824 call assert_fails('vimgrep // *', 'E35:')
2825 call writefile(v:errors, 'Xresult')
2826 qall!
2827 [SCRIPT]
2828 call writefile(lines, 'Xscript')
2829 if RunVim([], [], '--clean -S Xscript')
2830 call assert_equal([], readfile('Xresult'))
2831 endif
2832 call delete('Xscript')
2833 call delete('Xresult')
2834endfunc
2835
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002836" Test vimgrep without swap file
2837func Test_vimgrep_without_swap_file()
2838 let lines =<< trim [SCRIPT]
2839 vimgrep grep test_c*
2840 call writefile(['done'], 'Xresult')
2841 qall!
2842 [SCRIPT]
2843 call writefile(lines, 'Xscript')
2844 if RunVim([], [], '--clean -n -S Xscript Xscript')
2845 call assert_equal(['done'], readfile('Xresult'))
2846 endif
2847 call delete('Xscript')
2848 call delete('Xresult')
2849endfunc
2850
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002851func Test_vimgrep_existing_swapfile()
2852 call writefile(['match apple with apple'], 'Xapple')
2853 call writefile(['swapfile'], '.Xapple.swp')
2854 let g:foundSwap = 0
2855 let g:ignoreSwapExists = 1
2856 augroup grep
2857 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2858 augroup END
2859 vimgrep apple Xapple
2860 call assert_equal(1, g:foundSwap)
2861 call assert_match('.Xapple.swo', swapname(''))
2862
2863 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002864 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002865 augroup grep
2866 au! SwapExists
2867 augroup END
2868 unlet g:ignoreSwapExists
2869endfunc
2870
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002871func XfreeTests(cchar)
2872 call s:setup_commands(a:cchar)
2873
2874 enew | only
2875
2876 " Deleting the quickfix stack should work even When the current list is
2877 " somewhere in the middle of the stack
2878 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2879 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2880 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2881 Xolder
2882 call g:Xsetlist([], 'f')
2883 call assert_equal(0, len(g:Xgetlist()))
2884
2885 " After deleting the stack, adding a new list should create a stack with a
2886 " single list.
2887 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2888 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2889
2890 " Deleting the stack from a quickfix window should update/clear the
2891 " quickfix/location list window.
2892 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2893 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2894 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2895 Xolder
2896 Xwindow
2897 call g:Xsetlist([], 'f')
2898 call assert_equal(2, winnr('$'))
2899 call assert_equal(1, line('$'))
2900 Xclose
2901
2902 " Deleting the stack from a non-quickfix window should update/clear the
2903 " quickfix/location list window.
2904 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2905 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2906 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2907 Xolder
2908 Xwindow
2909 wincmd p
2910 call g:Xsetlist([], 'f')
2911 call assert_equal(0, len(g:Xgetlist()))
2912 wincmd p
2913 call assert_equal(2, winnr('$'))
2914 call assert_equal(1, line('$'))
2915
2916 " After deleting the location list stack, if the location list window is
2917 " opened, then a new location list should be created. So opening the
2918 " location list window again should not create a new window.
2919 if a:cchar == 'l'
2920 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2921 wincmd p
2922 lopen
2923 call assert_equal(2, winnr('$'))
2924 endif
2925 Xclose
2926endfunc
2927
Bram Moolenaar74240d32017-12-10 15:26:15 +01002928" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002929func Test_qf_free()
2930 call XfreeTests('c')
2931 call XfreeTests('l')
2932endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002933
2934" Test for buffer overflow when parsing lines and adding new entries to
2935" the quickfix list.
2936func Test_bufoverflow()
2937 set efm=%f:%l:%m
2938 cgetexpr ['File1:100:' . repeat('x', 1025)]
2939
2940 set efm=%+GCompiler:\ %.%#,%f:%l:%m
2941 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2942
2943 set efm=%DEntering\ directory\ %f,%f:%l:%m
2944 cgetexpr ['Entering directory ' . repeat('a', 1006),
2945 \ 'File1:10:Hello World']
2946 set efm&vim
2947endfunc
2948
Bram Moolenaar875feea2017-06-11 16:07:51 +02002949" Tests for getting the quickfix stack size
2950func XsizeTests(cchar)
2951 call s:setup_commands(a:cchar)
2952
2953 call g:Xsetlist([], 'f')
2954 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01002955 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2956 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02002957
2958 Xexpr "File1:10:Line1"
2959 Xexpr "File2:20:Line2"
2960 Xexpr "File3:30:Line3"
2961 Xolder | Xolder
2962 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2963 call g:Xsetlist([], 'f')
2964
2965 Xexpr "File1:10:Line1"
2966 Xexpr "File2:20:Line2"
2967 Xexpr "File3:30:Line3"
2968 Xolder | Xolder
2969 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2970 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2971endfunc
2972
2973func Test_Qf_Size()
2974 call XsizeTests('c')
2975 call XsizeTests('l')
2976endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02002977
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002978func Test_cclose_from_copen()
2979 augroup QF_Test
2980 au!
2981 au FileType qf :call assert_fails(':cclose', 'E788')
2982 augroup END
2983 copen
2984 augroup QF_Test
2985 au!
2986 augroup END
2987 augroup! QF_Test
2988endfunc
2989
Bram Moolenaar18141832017-06-25 21:17:25 +02002990func Test_cclose_in_autocmd()
2991 " Problem is only triggered if "starting" is zero, so that the OptionsSet
2992 " event will be triggered.
2993 call test_override('starting', 1)
2994 augroup QF_Test
2995 au!
2996 au FileType qf :call assert_fails(':cclose', 'E788')
2997 augroup END
2998 copen
2999 augroup QF_Test
3000 au!
3001 augroup END
3002 augroup! QF_Test
3003 call test_override('starting', 0)
3004endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003005
Bram Moolenaar379fb762018-08-30 15:58:28 +02003006" Check that ":file" without an argument is possible even when "curbuf_lock"
3007" is set.
3008func Test_file_from_copen()
3009 " Works without argument.
3010 augroup QF_Test
3011 au!
3012 au FileType qf file
3013 augroup END
3014 copen
3015
3016 augroup QF_Test
3017 au!
3018 augroup END
3019 cclose
3020
3021 " Fails with argument.
3022 augroup QF_Test
3023 au!
3024 au FileType qf call assert_fails(':file foo', 'E788')
3025 augroup END
3026 copen
3027 augroup QF_Test
3028 au!
3029 augroup END
3030 cclose
3031
3032 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003033endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003034
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003035func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003036 augroup QF_Test
3037 au!
3038 au FileType qf resize 5
3039 augroup END
3040 try
3041 " This should succeed without any exception. No other buffers are
3042 " involved in the autocmd.
3043 copen
3044 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003045 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003046 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003047 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003048 augroup! QF_Test
3049 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003050endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003051
3052" Tests for the quickfix buffer b:changedtick variable
3053func Xchangedtick_tests(cchar)
3054 call s:setup_commands(a:cchar)
3055
3056 new | only
3057
3058 Xexpr "" | Xexpr "" | Xexpr ""
3059
3060 Xopen
3061 Xolder
3062 Xolder
3063 Xaddexpr "F1:10:Line10"
3064 Xaddexpr "F2:20:Line20"
3065 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3066 call g:Xsetlist([], 'f')
3067 call assert_equal(8, getbufvar('%', 'changedtick'))
3068 Xclose
3069endfunc
3070
3071func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003072 call Xchangedtick_tests('c')
3073 call Xchangedtick_tests('l')
3074endfunc
3075
3076" Tests for parsing an expression using setqflist()
3077func Xsetexpr_tests(cchar)
3078 call s:setup_commands(a:cchar)
3079
3080 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003081 call g:Xsetlist([], ' ', {'lines' : t})
3082 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003083
3084 let l = g:Xgetlist()
3085 call assert_equal(3, len(l))
3086 call assert_equal(20, l[1].lnum)
3087 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003088 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003089 let l = g:Xgetlist()
3090 call assert_equal(1, len(l))
3091 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003092 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3093 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003094
3095 call g:Xsetlist([], 'f')
3096 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003097 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3098 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3099 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3100 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003101 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3102 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003103
3104 " Adding entries using a custom efm
3105 set efm&
3106 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3107 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3108 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3109 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3110 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3111 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3112 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3113 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003114endfunc
3115
3116func Test_setexpr()
3117 call Xsetexpr_tests('c')
3118 call Xsetexpr_tests('l')
3119endfunc
3120
3121" Tests for per quickfix/location list directory stack
3122func Xmultidirstack_tests(cchar)
3123 call s:setup_commands(a:cchar)
3124
3125 call g:Xsetlist([], 'f')
3126 Xexpr "" | Xexpr ""
3127
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003128 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3129 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3130 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3131 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003132
3133 let l1 = g:Xgetlist({'nr':1, 'items':1})
3134 let l2 = g:Xgetlist({'nr':2, 'items':1})
3135 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3136 call assert_equal(3, l1.items[1].lnum)
3137 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3138 call assert_equal(5, l2.items[1].lnum)
3139endfunc
3140
3141func Test_multidirstack()
3142 call mkdir('Xone/a', 'p')
3143 call mkdir('Xtwo/a', 'p')
3144 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3145 call writefile(lines, 'Xone/a/one.txt')
3146 call writefile(lines, 'Xtwo/a/two.txt')
3147 let save_efm = &efm
3148 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3149
3150 call Xmultidirstack_tests('c')
3151 call Xmultidirstack_tests('l')
3152
3153 let &efm = save_efm
3154 call delete('Xone', 'rf')
3155 call delete('Xtwo', 'rf')
3156endfunc
3157
3158" Tests for per quickfix/location list file stack
3159func Xmultifilestack_tests(cchar)
3160 call s:setup_commands(a:cchar)
3161
3162 call g:Xsetlist([], 'f')
3163 Xexpr "" | Xexpr ""
3164
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003165 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3166 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3167 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3168 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003169
3170 let l1 = g:Xgetlist({'nr':1, 'items':1})
3171 let l2 = g:Xgetlist({'nr':2, 'items':1})
3172 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3173 call assert_equal(3, l1.items[1].lnum)
3174 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3175 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003176
3177 " Test for start of a new error line in the same line where a previous
3178 " error line ends with a file stack.
3179 let efm_val = 'Error\ l%l\ in\ %f,'
3180 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3181 let l = g:Xgetlist({'lines' : [
3182 \ '(one.txt',
3183 \ 'Error l4 in one.txt',
3184 \ ') (two.txt',
3185 \ 'Error l6 in two.txt',
3186 \ ')',
3187 \ 'Error l8 in one.txt'
3188 \ ], 'efm' : efm_val})
3189 call assert_equal(3, len(l.items))
3190 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3191 call assert_equal(4, l.items[0].lnum)
3192 call assert_equal('one.txt', l.items[0].text)
3193 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3194 call assert_equal(6, l.items[1].lnum)
3195 call assert_equal('two.txt', l.items[1].text)
3196 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3197 call assert_equal(8, l.items[2].lnum)
3198 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003199endfunc
3200
3201func Test_multifilestack()
3202 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3203 call writefile(lines, 'one.txt')
3204 call writefile(lines, 'two.txt')
3205 let save_efm = &efm
3206 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3207
3208 call Xmultifilestack_tests('c')
3209 call Xmultifilestack_tests('l')
3210
3211 let &efm = save_efm
3212 call delete('one.txt')
3213 call delete('two.txt')
3214endfunc
3215
3216" Tests for per buffer 'efm' setting
3217func Test_perbuf_efm()
3218 call writefile(["File1-10-Line10"], 'one.txt')
3219 call writefile(["File2#20#Line20"], 'two.txt')
3220 set efm=%f#%l#%m
3221 new | only
3222 new
3223 setlocal efm=%f-%l-%m
3224 cfile one.txt
3225 wincmd w
3226 caddfile two.txt
3227
3228 let l = getqflist()
3229 call assert_equal(10, l[0].lnum)
3230 call assert_equal('Line20', l[1].text)
3231
3232 set efm&
3233 new | only
3234 call delete('one.txt')
3235 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003236endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003237
3238" Open multiple help windows using ":lhelpgrep
3239" This test used to crash Vim
3240func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003241 new | only
3242 lhelpgrep window
3243 lopen
3244 e#
3245 lhelpgrep buffer
3246 call assert_equal(3, winnr('$'))
3247 call assert_true(len(getloclist(1)) != 0)
3248 call assert_true(len(getloclist(2)) != 0)
3249 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003250endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003251
3252" Tests for adding new quickfix lists using setqflist()
3253func XaddQf_tests(cchar)
3254 call s:setup_commands(a:cchar)
3255
3256 " Create a new list using ' ' for action
3257 call g:Xsetlist([], 'f')
3258 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3259 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3260 call assert_equal(1, l.nr)
3261 call assert_equal('Test1', l.title)
3262
3263 " Create a new list using ' ' for action and '$' for 'nr'
3264 call g:Xsetlist([], 'f')
3265 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3266 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3267 call assert_equal(1, l.nr)
3268 call assert_equal('Test2', l.title)
3269
3270 " Create a new list using 'a' for action
3271 call g:Xsetlist([], 'f')
3272 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3273 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3274 call assert_equal(1, l.nr)
3275 call assert_equal('Test3', l.title)
3276
3277 " Create a new list using 'a' for action and '$' for 'nr'
3278 call g:Xsetlist([], 'f')
3279 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3280 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3281 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3282 call assert_equal(1, l.nr)
3283 call assert_equal('Test4', l.title)
3284
3285 " Adding a quickfix list should remove all the lists following the current
3286 " list.
3287 Xexpr "" | Xexpr "" | Xexpr ""
3288 silent! 10Xolder
3289 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3290 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3291 call assert_equal(2, l.nr)
3292 call assert_equal('Test5', l.title)
3293
3294 " Add a quickfix list using '$' as the list number.
3295 let lastqf = g:Xgetlist({'nr':'$'}).nr
3296 silent! 99Xolder
3297 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3298 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3299 call assert_equal(lastqf + 1, l.nr)
3300 call assert_equal('Test6', l.title)
3301
3302 " Add a quickfix list using 'nr' set to one more than the quickfix
3303 " list size.
3304 let lastqf = g:Xgetlist({'nr':'$'}).nr
3305 silent! 99Xolder
3306 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3307 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3308 call assert_equal(lastqf + 1, l.nr)
3309 call assert_equal('Test7', l.title)
3310
3311 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3312 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3313 silent! 99Xolder
3314 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3315 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3316 call assert_equal(10, l.nr)
3317 call assert_equal('Test8', l.title)
3318
3319 " Add a quickfix list using 'nr' set to a value greater than 10
3320 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3321
3322 " Try adding a quickfix list with 'nr' set to a value greater than the
3323 " quickfix list size but less than 10.
3324 call g:Xsetlist([], 'f')
3325 Xexpr "" | Xexpr "" | Xexpr ""
3326 silent! 99Xolder
3327 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3328
3329 " Add a quickfix list using 'nr' set to a some string or list
3330 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3331endfunc
3332
3333func Test_add_qf()
3334 call XaddQf_tests('c')
3335 call XaddQf_tests('l')
3336endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003337
3338" Test for getting the quickfix list items from some text without modifying
3339" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003340func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003341 call s:setup_commands(a:cchar)
3342 call g:Xsetlist([], 'f')
3343
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003344 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003345 call assert_equal(2, len(l))
3346 call assert_equal(30, l[1].lnum)
3347
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003348 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3349 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3350 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3351 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003352
Bram Moolenaar36538222017-09-02 19:51:44 +02003353 " Parse text using a custom efm
3354 set efm&
3355 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3356 call assert_equal('Line30', l[0].text)
3357 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3358 call assert_equal('File3:30:Line30', l[0].text)
3359 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3360 call assert_equal({}, l)
3361 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3362 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3363
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003364 " Make sure that the quickfix stack is not modified
3365 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3366endfunc
3367
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003368func Test_get_list_from_lines()
3369 call XgetListFromLines('c')
3370 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003371endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003372
3373" Tests for the quickfix list id
3374func Xqfid_tests(cchar)
3375 call s:setup_commands(a:cchar)
3376
3377 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003378 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003379 Xexpr ''
3380 let start_id = g:Xgetlist({'id' : 0}).id
3381 Xexpr '' | Xexpr ''
3382 Xolder
3383 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3384 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3385 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003386 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003387 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003388 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3389 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003390
3391 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3392 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003393 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003394 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3395 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3396 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3397
3398 let qfid = g:Xgetlist({'id':0, 'nr':0})
3399 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003400 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003401endfunc
3402
3403func Test_qf_id()
3404 call Xqfid_tests('c')
3405 call Xqfid_tests('l')
3406endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003407
3408func Xqfjump_tests(cchar)
3409 call s:setup_commands(a:cchar)
3410
3411 call writefile(["Line1\tFoo", "Line2"], 'F1')
3412 call writefile(["Line1\tBar", "Line2"], 'F2')
3413 call writefile(["Line1\tBaz", "Line2"], 'F3')
3414
3415 call g:Xsetlist([], 'f')
3416
3417 " Tests for
3418 " Jumping to a line using a pattern
3419 " Jumping to a column greater than the last column in a line
3420 " Jumping to a line greater than the last line in the file
3421 let l = []
3422 for i in range(1, 7)
3423 call add(l, {})
3424 endfor
3425 let l[0].filename='F1'
3426 let l[0].pattern='Line1'
3427 let l[1].filename='F2'
3428 let l[1].pattern='Line1'
3429 let l[2].filename='F3'
3430 let l[2].pattern='Line1'
3431 let l[3].filename='F3'
3432 let l[3].lnum=1
3433 let l[3].col=9
3434 let l[3].vcol=1
3435 let l[4].filename='F3'
3436 let l[4].lnum=99
3437 let l[5].filename='F3'
3438 let l[5].lnum=1
3439 let l[5].col=99
3440 let l[5].vcol=1
3441 let l[6].filename='F3'
3442 let l[6].pattern='abcxyz'
3443
3444 call g:Xsetlist([], ' ', {'items' : l})
3445 Xopen | only
3446 2Xnext
3447 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003448 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003449 Xnext
3450 call assert_equal(7, col('.'))
3451 Xnext
3452 call assert_equal(2, line('.'))
3453 Xnext
3454 call assert_equal(9, col('.'))
3455 2
3456 Xnext
3457 call assert_equal(2, line('.'))
3458
3459 if a:cchar == 'l'
3460 " When jumping to a location list entry in the location list window and
3461 " no usable windows are available, then a new window should be opened.
3462 enew! | new | only
3463 call g:Xsetlist([], 'f')
3464 setlocal buftype=nofile
3465 new
3466 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']})
3467 Xopen
3468 let winid = win_getid()
3469 wincmd p
3470 close
3471 call win_gotoid(winid)
3472 Xnext
3473 call assert_equal(3, winnr('$'))
3474 call assert_equal(1, winnr())
3475 call assert_equal(2, line('.'))
3476
3477 " When jumping to an entry in the location list window and the window
3478 " associated with the location list is not present and a window containing
3479 " the file is already present, then that window should be used.
3480 close
3481 belowright new
3482 call g:Xsetlist([], 'f')
3483 edit F3
3484 call win_gotoid(winid)
3485 Xlast
3486 call assert_equal(3, winnr())
3487 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3488 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3489 endif
3490
3491 " Cleanup
3492 enew!
3493 new | only
3494
3495 call delete('F1')
3496 call delete('F2')
3497 call delete('F3')
3498endfunc
3499
3500func Test_qfjump()
3501 call Xqfjump_tests('c')
3502 call Xqfjump_tests('l')
3503endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003504
3505" Tests for the getqflist() and getloclist() functions when the list is not
3506" present or is empty
3507func Xgetlist_empty_tests(cchar)
3508 call s:setup_commands(a:cchar)
3509
3510 " Empty quickfix stack
3511 call g:Xsetlist([], 'f')
3512 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3513 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3514 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3515 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3516 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3517 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3518 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3519 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003520 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003521 if a:cchar == 'c'
3522 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003523 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003524 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3525 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003526 else
3527 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3528 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003529 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003530 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003531 \ g:Xgetlist({'all' : 0}))
3532 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003533
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003534 " Quickfix window with empty stack
3535 silent! Xopen
3536 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003537 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003538 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3539 Xclose
3540
Bram Moolenaara6d48492017-12-12 22:45:31 +01003541 " Empty quickfix list
3542 Xexpr ""
3543 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3544 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3545 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3546 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3547 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3548 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3549 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3550 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003551 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003552
3553 let qfid = g:Xgetlist({'id' : 0}).id
3554 call g:Xsetlist([], 'f')
3555
3556 " Non-existing quickfix identifier
3557 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3558 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3559 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3560 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3561 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3562 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3563 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3564 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003565 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003566 if a:cchar == 'c'
3567 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3568 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003569 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003570 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3571 else
3572 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3573 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003574 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3575 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003576 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3577 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003578
3579 " Non-existing quickfix list number
3580 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3581 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3582 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3583 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3584 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3585 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3586 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3587 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003588 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003589 if a:cchar == 'c'
3590 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3591 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003592 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3593 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003594 else
3595 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3596 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003597 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3598 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003599 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003600endfunc
3601
3602func Test_getqflist()
3603 call Xgetlist_empty_tests('c')
3604 call Xgetlist_empty_tests('l')
3605endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003606
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003607func Test_getqflist_invalid_nr()
3608 " The following commands used to crash Vim
3609 cexpr ""
3610 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3611
3612 " Cleanup
3613 call setqflist([], 'r')
3614endfunc
3615
Bram Moolenaarb254af32017-12-18 19:48:58 +01003616" Tests for the quickfix/location list changedtick
3617func Xqftick_tests(cchar)
3618 call s:setup_commands(a:cchar)
3619
3620 call g:Xsetlist([], 'f')
3621
3622 Xexpr "F1:10:Line10"
3623 let qfid = g:Xgetlist({'id' : 0}).id
3624 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3625 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3626 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3627 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3628 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3629 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3630 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3631 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3632 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3633
3634 enew!
3635 call append(0, ["F5:50:L50", "F6:60:L60"])
3636 Xaddbuffer
3637 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3638 enew!
3639
3640 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3641 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3642 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3643 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3644 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3645 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3646 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3647 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3648 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3649 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3650 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3651
3652 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3653 Xfile Xone
3654 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3655 Xaddfile Xone
3656 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3657
3658 " Test case for updating a non-current quickfix list
3659 call g:Xsetlist([], 'f')
3660 Xexpr "F1:1:L1"
3661 Xexpr "F2:2:L2"
3662 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3663 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3664 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3665
3666 call delete("Xone")
3667endfunc
3668
3669func Test_qf_tick()
3670 call Xqftick_tests('c')
3671 call Xqftick_tests('l')
3672endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003673
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003674" Test helpgrep with lang specifier
3675func Xtest_helpgrep_with_lang_specifier(cchar)
3676 call s:setup_commands(a:cchar)
3677 Xhelpgrep Vim@en
3678 call assert_equal('help', &filetype)
3679 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3680 new | only
3681endfunc
3682
3683func Test_helpgrep_with_lang_specifier()
3684 call Xtest_helpgrep_with_lang_specifier('c')
3685 call Xtest_helpgrep_with_lang_specifier('l')
3686endfunc
3687
Bram Moolenaar12237442017-12-19 12:38:52 +01003688" The following test used to crash Vim.
3689" Open the location list window and close the regular window associated with
3690" the location list. When the garbage collection runs now, it incorrectly
3691" marks the location list context as not in use and frees the context.
3692func Test_ll_window_ctx()
3693 call setloclist(0, [], 'f')
3694 call setloclist(0, [], 'a', {'context' : []})
3695 lopen | only
3696 call test_garbagecollect_now()
3697 echo getloclist(0, {'context' : 1}).context
3698 enew | only
3699endfunc
3700
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003701" The following test used to crash vim
3702func Test_lfile_crash()
3703 sp Xtest
3704 au QuickFixCmdPre * bw
3705 call assert_fails('lfile', 'E40')
3706 au! QuickFixCmdPre
3707endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003708
3709" The following test used to crash vim
3710func Test_lbuffer_crash()
3711 sv Xtest
3712 augroup QF_Test
3713 au!
3714 au * * bw
3715 augroup END
3716 lbuffer
3717 augroup QF_Test
3718 au!
3719 augroup END
3720endfunc
3721
3722" The following test used to crash vim
3723func Test_lexpr_crash()
3724 augroup QF_Test
3725 au!
3726 au * * call setloclist(0, [], 'f')
3727 augroup END
3728 lexpr ""
3729 augroup QF_Test
3730 au!
3731 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003732
Bram Moolenaar3c097222017-12-21 20:54:49 +01003733 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003734 augroup QF_Test
3735 au!
3736 au BufNew * call setloclist(0, [], 'f')
3737 augroup END
3738 lexpr 'x:1:x'
3739 augroup QF_Test
3740 au!
3741 augroup END
3742
3743 enew | only
3744 lexpr ''
3745 lopen
3746 augroup QF_Test
3747 au!
3748 au FileType * call setloclist(0, [], 'f')
3749 augroup END
3750 lexpr ''
3751 augroup QF_Test
3752 au!
3753 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003754endfunc
3755
3756" The following test used to crash Vim
3757func Test_lvimgrep_crash()
3758 sv Xtest
3759 augroup QF_Test
3760 au!
3761 au * * call setloclist(0, [], 'f')
3762 augroup END
3763 lvimgrep quickfix test_quickfix.vim
3764 augroup QF_Test
3765 au!
3766 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003767
3768 new | only
3769 augroup QF_Test
3770 au!
3771 au BufEnter * call setloclist(0, [], 'r')
3772 augroup END
3773 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3774 augroup QF_Test
3775 au!
3776 augroup END
3777
Bram Moolenaar3c097222017-12-21 20:54:49 +01003778 enew | only
3779endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003780
Bram Moolenaar2573af32020-03-14 17:21:34 +01003781func Test_lvimgrep_crash2()
3782 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003783 call assert_fails('lvimgrep x x', 'E471:')
3784 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003785
3786 au! BufNewFile
3787endfunc
3788
Bram Moolenaarde046542017-12-26 13:53:11 +01003789" Test for the position of the quickfix and location list window
3790func Test_qfwin_pos()
3791 " Open two windows
3792 new | only
3793 new
3794 cexpr ['F1:10:L10']
3795 copen
3796 " Quickfix window should be the bottom most window
3797 call assert_equal(3, winnr())
3798 close
3799 " Open at the very top
3800 wincmd t
3801 topleft copen
3802 call assert_equal(1, winnr())
3803 close
3804 " open left of the current window
3805 wincmd t
3806 below new
3807 leftabove copen
3808 call assert_equal(2, winnr())
3809 close
3810 " open right of the current window
3811 rightbelow copen
3812 call assert_equal(3, winnr())
3813 close
3814endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003815
3816" Tests for quickfix/location lists changed by autocommands when
3817" :vimgrep/:lvimgrep commands are running.
3818func Test_vimgrep_autocmd()
3819 call setqflist([], 'f')
3820 call writefile(['stars'], 'Xtest1.txt')
3821 call writefile(['stars'], 'Xtest2.txt')
3822
3823 " Test 1:
3824 " When searching for a pattern using :vimgrep, if the quickfix list is
3825 " changed by an autocmd, the results should be added to the correct quickfix
3826 " list.
3827 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3828 silent vimgrep stars Xtest*.txt
3829 call assert_equal(1, getqflist({'nr' : 0}).nr)
3830 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3831 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3832 au! BufRead Xtest2.txt
3833
3834 " Test 2:
3835 " When searching for a pattern using :vimgrep, if the quickfix list is
3836 " freed, then a error should be given.
3837 silent! %bwipe!
3838 call setqflist([], 'f')
3839 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3840 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3841 au! BufRead Xtest2.txt
3842
3843 " Test 3:
3844 " When searching for a pattern using :lvimgrep, if the location list is
3845 " freed, then the command should error out.
3846 silent! %bwipe!
3847 let g:save_winid = win_getid()
3848 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3849 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3850 au! BufRead Xtest2.txt
3851
3852 call delete('Xtest1.txt')
3853 call delete('Xtest2.txt')
3854 call setqflist([], 'f')
3855endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003856
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003857" Test for an autocmd changing the current directory when running vimgrep
3858func Xvimgrep_autocmd_cd(cchar)
3859 call s:setup_commands(a:cchar)
3860
3861 %bwipe
3862 let save_cwd = getcwd()
3863
3864 augroup QF_Test
3865 au!
3866 autocmd BufRead * silent cd %:p:h
3867 augroup END
3868
3869 10Xvimgrep /vim/ Xdir/**
3870 let l = g:Xgetlist()
3871 call assert_equal('f1.txt', bufname(l[0].bufnr))
3872 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
3873
3874 augroup QF_Test
3875 au!
3876 augroup END
3877
3878 exe 'cd ' . save_cwd
3879endfunc
3880
3881func Test_vimgrep_autocmd_cd()
3882 call mkdir('Xdir/a', 'p')
3883 call mkdir('Xdir/b', 'p')
3884 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
3885 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
3886 call Xvimgrep_autocmd_cd('c')
3887 call Xvimgrep_autocmd_cd('l')
3888 %bwipe
3889 call delete('Xdir', 'rf')
3890endfunc
3891
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003892" The following test used to crash Vim
3893func Test_lhelpgrep_autocmd()
3894 lhelpgrep quickfix
3895 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3896 lhelpgrep buffer
3897 call assert_equal('help', &filetype)
3898 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3899 lhelpgrep tabpage
3900 call assert_equal('help', &filetype)
3901 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3902 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003903
3904 new | only
3905 augroup QF_Test
3906 au!
3907 au BufEnter * call setqflist([], 'f')
3908 augroup END
3909 call assert_fails('helpgrep quickfix', 'E925:')
3910 augroup QF_Test
3911 au! BufEnter
3912 augroup END
3913
3914 new | only
3915 augroup QF_Test
3916 au!
3917 au BufEnter * call setqflist([], 'r')
3918 augroup END
3919 call assert_fails('helpgrep quickfix', 'E925:')
3920 augroup QF_Test
3921 au! BufEnter
3922 augroup END
3923
3924 new | only
3925 augroup QF_Test
3926 au!
3927 au BufEnter * call setloclist(0, [], 'r')
3928 augroup END
3929 call assert_fails('lhelpgrep quickfix', 'E926:')
3930 augroup QF_Test
3931 au! BufEnter
3932 augroup END
3933
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003934 new | only
3935endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02003936
3937" Test for shortening/simplifying the file name when opening the
3938" quickfix window or when displaying the quickfix list
3939func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003940 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02003941 %bwipe
3942 " Create a quickfix list with a absolute path filename
3943 let fname = getcwd() . '/test_quickfix.vim'
3944 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3945 call assert_equal(fname, bufname('test_quickfix.vim'))
3946 " Opening the quickfix window should simplify the file path
3947 cwindow
3948 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3949 cclose
3950 %bwipe
3951 " Create a quickfix list with a absolute path filename
3952 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3953 call assert_equal(fname, bufname('test_quickfix.vim'))
3954 " Displaying the quickfix list should simplify the file path
3955 silent! clist
3956 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3957endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02003958
3959" Quickfix title tests
3960" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3961" Otherwise due to indentation, the title is set with spaces at the beginning
3962" of the command.
3963func Test_qftitle()
3964 call writefile(["F1:1:Line1"], 'Xerr')
3965
3966 " :cexpr
3967 exe "cexpr readfile('Xerr')"
3968 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3969
3970 " :cgetexpr
3971 exe "cgetexpr readfile('Xerr')"
3972 call assert_equal(":cgetexpr readfile('Xerr')",
3973 \ getqflist({'title' : 1}).title)
3974
3975 " :caddexpr
3976 call setqflist([], 'f')
3977 exe "caddexpr readfile('Xerr')"
3978 call assert_equal(":caddexpr readfile('Xerr')",
3979 \ getqflist({'title' : 1}).title)
3980
3981 " :cbuffer
3982 new Xerr
3983 exe "cbuffer"
3984 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3985
3986 " :cgetbuffer
3987 edit Xerr
3988 exe "cgetbuffer"
3989 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3990
3991 " :caddbuffer
3992 call setqflist([], 'f')
3993 edit Xerr
3994 exe "caddbuffer"
3995 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3996
3997 " :cfile
3998 exe "cfile Xerr"
3999 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4000
4001 " :cgetfile
4002 exe "cgetfile Xerr"
4003 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4004
4005 " :caddfile
4006 call setqflist([], 'f')
4007 exe "caddfile Xerr"
4008 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4009
4010 " :grep
4011 set grepprg=internal
4012 exe "grep F1 Xerr"
4013 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4014
4015 " :grepadd
4016 call setqflist([], 'f')
4017 exe "grepadd F1 Xerr"
4018 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4019 set grepprg&vim
4020
4021 " :vimgrep
4022 exe "vimgrep F1 Xerr"
4023 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4024
4025 " :vimgrepadd
4026 call setqflist([], 'f')
4027 exe "vimgrepadd F1 Xerr"
4028 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4029
4030 call setqflist(['F1:10:L10'], ' ')
4031 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4032
4033 call setqflist([], 'f')
4034 call setqflist(['F1:10:L10'], 'a')
4035 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4036
4037 call setqflist([], 'f')
4038 call setqflist(['F1:10:L10'], 'r')
4039 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4040
4041 close
4042 call delete('Xerr')
4043
4044 call setqflist([], ' ', {'title' : 'Errors'})
4045 copen
4046 call assert_equal('Errors', w:quickfix_title)
4047 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4048 call assert_equal('Errors', w:quickfix_title)
4049 cclose
4050endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004051
4052func Test_lbuffer_with_bwipe()
4053 new
4054 new
4055 augroup nasty
4056 au * * bwipe
4057 augroup END
4058 lbuffer
4059 augroup nasty
4060 au!
4061 augroup END
4062endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004063
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004064" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4065" running
4066func Xexpr_acmd_freelist(cchar)
4067 call s:setup_commands(a:cchar)
4068
Bram Moolenaar0366c012018-06-18 20:52:13 +02004069 " This was using freed memory.
4070 augroup nasty
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004071 au * * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004072 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004073 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004074 augroup nasty
4075 au!
4076 augroup END
4077endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004078
4079func Test_cexpr_acmd_freelist()
4080 call Xexpr_acmd_freelist('c')
4081 call Xexpr_acmd_freelist('l')
4082endfunc
4083
4084" Test for commands that create a new quickfix/location list and jump to the
4085" first error automatically.
4086func Xjumpto_first_error_test(cchar)
4087 call s:setup_commands(a:cchar)
4088
4089 call s:create_test_file('Xtestfile1')
4090 call s:create_test_file('Xtestfile2')
4091 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4092
4093 " Test for cexpr/lexpr
4094 enew
4095 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004096 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004097 call assert_equal(2, line('.'))
4098
4099 " Test for cfile/lfile
4100 enew
4101 call writefile(l, 'Xerr')
4102 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004103 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004104 call assert_equal(2, line('.'))
4105
4106 " Test for cbuffer/lbuffer
4107 edit Xerr
4108 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004109 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004110 call assert_equal(2, line('.'))
4111
4112 call delete('Xerr')
4113 call delete('Xtestfile1')
4114 call delete('Xtestfile2')
4115endfunc
4116
4117func Test_jumpto_first_error()
4118 call Xjumpto_first_error_test('c')
4119 call Xjumpto_first_error_test('l')
4120endfunc
4121
4122" Test for a quickfix autocmd changing the quickfix/location list before
4123" jumping to the first error in the new list.
4124func Xautocmd_changelist(cchar)
4125 call s:setup_commands(a:cchar)
4126
4127 " Test for cfile/lfile
4128 call s:create_test_file('Xtestfile1')
4129 call s:create_test_file('Xtestfile2')
4130 Xexpr 'Xtestfile1:2:Line2'
4131 autocmd QuickFixCmdPost * Xolder
4132 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4133 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004134 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004135 call assert_equal(4, line('.'))
4136 autocmd! QuickFixCmdPost
4137
4138 " Test for cbuffer/lbuffer
4139 call g:Xsetlist([], 'f')
4140 Xexpr 'Xtestfile1:2:Line2'
4141 autocmd QuickFixCmdPost * Xolder
4142 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4143 edit Xerr
4144 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004145 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004146 call assert_equal(4, line('.'))
4147 autocmd! QuickFixCmdPost
4148
4149 " Test for cexpr/lexpr
4150 call g:Xsetlist([], 'f')
4151 Xexpr 'Xtestfile1:2:Line2'
4152 autocmd QuickFixCmdPost * Xolder
4153 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004154 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004155 call assert_equal(4, line('.'))
4156 autocmd! QuickFixCmdPost
4157
Bram Moolenaar851332e2018-07-03 19:16:00 +02004158 " The grepprg may not be set on non-Unix systems
4159 if has('unix')
4160 " Test for grep/lgrep
4161 call g:Xsetlist([], 'f')
4162 Xexpr 'Xtestfile1:2:Line2'
4163 autocmd QuickFixCmdPost * Xolder
4164 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004165 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004166 call assert_equal(5, line('.'))
4167 autocmd! QuickFixCmdPost
4168 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004169
4170 " Test for vimgrep/lvimgrep
4171 call g:Xsetlist([], 'f')
4172 Xexpr 'Xtestfile1:2:Line2'
4173 autocmd QuickFixCmdPost * Xolder
4174 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004175 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004176 call assert_equal(5, line('.'))
4177 autocmd! QuickFixCmdPost
4178
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004179 " Test for autocommands clearing the quickfix list before jumping to the
4180 " first error. This should not result in an error
4181 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4182 let v:errmsg = ''
4183 " Test for cfile/lfile
4184 Xfile Xerr
4185 call assert_true(v:errmsg !~# 'E42:')
4186 " Test for cbuffer/lbuffer
4187 edit Xerr
4188 Xbuffer
4189 call assert_true(v:errmsg !~# 'E42:')
4190 " Test for cexpr/lexpr
4191 Xexpr 'Xtestfile2:4:Line4'
4192 call assert_true(v:errmsg !~# 'E42:')
4193 " Test for grep/lgrep
4194 " The grepprg may not be set on non-Unix systems
4195 if has('unix')
4196 silent Xgrep Line5 Xtestfile2
4197 call assert_true(v:errmsg !~# 'E42:')
4198 endif
4199 " Test for vimgrep/lvimgrep
4200 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4201 autocmd! QuickFixCmdPost
4202
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004203 call delete('Xerr')
4204 call delete('Xtestfile1')
4205 call delete('Xtestfile2')
4206endfunc
4207
4208func Test_autocmd_changelist()
4209 call Xautocmd_changelist('c')
4210 call Xautocmd_changelist('l')
4211endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004212
4213" Tests for the ':filter /pat/ clist' command
4214func Test_filter_clist()
4215 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4216 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4217 \ split(execute('filter /Line 15/ clist'), "\n"))
4218 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4219 \ split(execute('filter /Xfile1/ clist'), "\n"))
4220 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4221
4222 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4223 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4224 call assert_equal([' 2 pqr:pat2: '],
4225 \ split(execute('filter /pqr/ clist'), "\n"))
4226 call assert_equal([' 1 abc:pat1: '],
4227 \ split(execute('filter /pat1/ clist'), "\n"))
4228endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004229
4230" Tests for the "CTRL-W <CR>" command.
4231func Xview_result_split_tests(cchar)
4232 call s:setup_commands(a:cchar)
4233
4234 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4235 call g:Xsetlist([])
4236 Xopen
4237 let l:win_count = winnr('$')
4238 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
4239 call assert_equal(l:win_count, winnr('$'))
4240 Xclose
4241endfunc
4242
4243func Test_view_result_split()
4244 call Xview_result_split_tests('c')
4245 call Xview_result_split_tests('l')
4246endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004247
4248" Test that :cc sets curswant
4249func Test_curswant()
4250 helpgrep quickfix
4251 normal! llll
4252 1cc
4253 call assert_equal(getcurpos()[4], virtcol('.'))
4254 cclose | helpclose
4255endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004256
4257" Test for opening a file from the quickfix window using CTRL-W <Enter>
4258" doesn't leave an empty buffer around.
4259func Test_splitview()
4260 call s:create_test_file('Xtestfile1')
4261 call s:create_test_file('Xtestfile2')
4262 new | only
4263 let last_bufnr = bufnr('Test_sv_1', 1)
4264 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4265 cgetexpr l
4266 copen
4267 let numbufs = len(getbufinfo())
4268 exe "normal \<C-W>\<CR>"
4269 copen
4270 exe "normal j\<C-W>\<CR>"
4271 " Make sure new empty buffers are not created
4272 call assert_equal(numbufs, len(getbufinfo()))
4273 " Creating a new buffer should use the next available buffer number
4274 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4275 bwipe Test_sv_1
4276 bwipe Test_sv_2
4277 new | only
4278
4279 " When split opening files from location list window, make sure that two
4280 " windows doesn't refer to the same location list
4281 lgetexpr l
4282 let locid = getloclist(0, {'id' : 0}).id
4283 lopen
4284 exe "normal \<C-W>\<CR>"
4285 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4286 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4287 new | only
4288
4289 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004290 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004291 lhelpgrep window
4292 let locid = getloclist(0, {'id' : 0}).id
4293 lwindow
4294 exe "normal j\<C-W>\<CR>"
4295 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4296 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4297 new | only
4298
Bram Moolenaar406cd902020-02-18 21:54:41 +01004299 " Using :split or :vsplit from a quickfix window should behave like a :new
4300 " or a :vnew command
4301 copen
4302 split
4303 call assert_equal(3, winnr('$'))
4304 let l = getwininfo()
4305 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4306 close
4307 copen
4308 vsplit
4309 let l = getwininfo()
4310 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4311 new | only
4312
Bram Moolenaarb2443732018-11-11 22:50:27 +01004313 call delete('Xtestfile1')
4314 call delete('Xtestfile2')
4315endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004316
4317" Test for parsing entries using visual screen column
4318func Test_viscol()
4319 enew
4320 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4321 edit Xfile1
4322
4323 " Use byte offset for column number
4324 set efm&
4325 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4326 call assert_equal([5, 8], [col('.'), virtcol('.')])
4327 cnext
4328 call assert_equal([9, 12], [col('.'), virtcol('.')])
4329 cnext
4330 call assert_equal([14, 20], [col('.'), virtcol('.')])
4331
4332 " Use screen column offset for column number
4333 set efm=%f:%l:%v:%m
4334 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4335 call assert_equal([5, 8], [col('.'), virtcol('.')])
4336 cnext
4337 call assert_equal([9, 12], [col('.'), virtcol('.')])
4338 cnext
4339 call assert_equal([14, 20], [col('.'), virtcol('.')])
4340 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4341 call assert_equal([5, 8], [col('.'), virtcol('.')])
4342 cnext
4343 call assert_equal([10, 16], [col('.'), virtcol('.')])
4344 cnext
4345 call assert_equal([14, 20], [col('.'), virtcol('.')])
4346
4347 enew
4348 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4349
4350 " Use byte offset for column number
4351 set efm&
4352 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4353 call assert_equal([8, 10], [col('.'), virtcol('.')])
4354 cnext
4355 call assert_equal([11, 17], [col('.'), virtcol('.')])
4356 cnext
4357 call assert_equal([16, 25], [col('.'), virtcol('.')])
4358
4359 " Use screen column offset for column number
4360 set efm=%f:%l:%v:%m
4361 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4362 call assert_equal([8, 10], [col('.'), virtcol('.')])
4363 cnext
4364 call assert_equal([11, 17], [col('.'), virtcol('.')])
4365 cnext
4366 call assert_equal([16, 25], [col('.'), virtcol('.')])
4367
4368 enew | only
4369 set efm&
4370 call delete('Xfile1')
4371endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004372
4373" Test for the quickfix window buffer
4374func Xqfbuf_test(cchar)
4375 call s:setup_commands(a:cchar)
4376
4377 " Quickfix buffer should be reused across closing and opening a quickfix
4378 " window
4379 Xexpr "F1:10:Line10"
4380 Xopen
4381 let qfbnum = bufnr('')
4382 Xclose
4383 " Even after the quickfix window is closed, the buffer should be loaded
4384 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004385 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004386 Xopen
4387 " Buffer should be reused when opening the window again
4388 call assert_equal(qfbnum, bufnr(''))
4389 Xclose
4390
4391 if a:cchar == 'l'
4392 %bwipe
4393 " For a location list, when both the file window and the location list
4394 " window for the list are closed, then the buffer should be freed.
4395 new | only
4396 lexpr "F1:10:Line10"
4397 let wid = win_getid()
4398 lopen
4399 let qfbnum = bufnr('')
4400 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4401 close
4402 " When the location list window is closed, the buffer name should not
4403 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004404 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004405 call assert_true(bufloaded(qfbnum))
4406
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004407 " After deleting a location list buffer using ":bdelete", opening the
4408 " location list window should mark the buffer as a location list buffer.
4409 exe "bdelete " . qfbnum
4410 lopen
4411 call assert_equal("quickfix", &buftype)
4412 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4413 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4414 call assert_false(&swapfile)
4415 lclose
4416
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004417 " When the location list is cleared for the window, the buffer should be
4418 " removed
4419 call setloclist(0, [], 'f')
4420 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004421 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004422
4423 " When the location list is freed with the location list window open, the
4424 " location list buffer should not be lost. It should be reused when the
4425 " location list is again populated.
4426 lexpr "F1:10:Line10"
4427 lopen
4428 let wid = win_getid()
4429 let qfbnum = bufnr('')
4430 wincmd p
4431 call setloclist(0, [], 'f')
4432 lexpr "F1:10:Line10"
4433 lopen
4434 call assert_equal(wid, win_getid())
4435 call assert_equal(qfbnum, bufnr(''))
4436 lclose
4437
4438 " When the window with the location list is closed, the buffer should be
4439 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004440 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004441 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004442 endif
4443endfunc
4444
4445func Test_qfbuf()
4446 call Xqfbuf_test('c')
4447 call Xqfbuf_test('l')
4448endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004449
4450" If there is an autocmd to use only one window, then opening the location
4451" list window used to crash Vim.
4452func Test_winonly_autocmd()
4453 call s:create_test_file('Xtest1')
4454 " Autocmd to show only one Vim window at a time
4455 autocmd WinEnter * only
4456 new
4457 " Load the location list
4458 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4459 let loclistid = getloclist(0, {'id' : 0}).id
4460 " Open the location list window. Only this window will be shown and the file
4461 " window is closed.
4462 lopen
4463 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4464 " Jump to an entry in the location list and make sure that the cursor is
4465 " positioned correctly.
4466 ll 3
4467 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004468 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004469 call assert_equal(15, line('.'))
4470 " Cleanup
4471 autocmd! WinEnter
4472 new | only
4473 call delete('Xtest1')
4474endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004475
4476" Test to make sure that an empty quickfix buffer is not reused for loading
4477" a normal buffer.
4478func Test_empty_qfbuf()
4479 enew | only
4480 call writefile(["Test"], 'Xfile1')
4481 call setqflist([], 'f')
4482 copen | only
4483 let qfbuf = bufnr('')
4484 edit Xfile1
4485 call assert_notequal(qfbuf, bufnr(''))
4486 enew
4487 call delete('Xfile1')
4488endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004489
4490" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004491" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004492func Xtest_below(cchar)
4493 call s:setup_commands(a:cchar)
4494
4495 " No quickfix/location list
4496 call assert_fails('Xbelow', 'E42:')
4497 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004498 call assert_fails('Xbefore', 'E42:')
4499 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004500
4501 " Empty quickfix/location list
4502 call g:Xsetlist([])
4503 call assert_fails('Xbelow', 'E42:')
4504 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004505 call assert_fails('Xbefore', 'E42:')
4506 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004507
4508 call s:create_test_file('X1')
4509 call s:create_test_file('X2')
4510 call s:create_test_file('X3')
4511 call s:create_test_file('X4')
4512
4513 " Invalid entries
4514 edit X1
4515 call g:Xsetlist(["E1", "E2"])
4516 call assert_fails('Xbelow', 'E42:')
4517 call assert_fails('Xabove', 'E42:')
4518 call assert_fails('3Xbelow', 'E42:')
4519 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004520 call assert_fails('Xbefore', 'E42:')
4521 call assert_fails('Xafter', 'E42:')
4522 call assert_fails('3Xbefore', 'E42:')
4523 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004524
4525 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004526 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 +02004527 edit +7 X2
4528 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004529 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004530 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004531 normal 7G
4532 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004533 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004534 call assert_fails('Xbefore', 'E553:')
4535
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004536 normal 2j
4537 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004538 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004539 normal 7G
4540 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004541 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004542
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004543 " Last error in this file
4544 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004545 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004546 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004547 normal gg
4548 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004549 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004550 call assert_fails('Xafter', 'E553:')
4551
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004552 " First error in this file
4553 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004554 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004555 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004556 normal G
4557 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004558 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004559 call assert_fails('Xbefore', 'E553:')
4560
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004561 normal gg
4562 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004563 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004564 normal gg
4565 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004566 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004567
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004568 normal G
4569 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004570 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004571 normal G
4572 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004573 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004574
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004575 edit X4
4576 call assert_fails('Xabove', 'E42:')
4577 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004578 call assert_fails('Xbefore', 'E42:')
4579 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004580 if a:cchar == 'l'
4581 " If a buffer has location list entries from some other window but not
4582 " from the current window, then the commands should fail.
4583 edit X1 | split | call setloclist(0, [], 'f')
4584 call assert_fails('Xabove', 'E776:')
4585 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004586 call assert_fails('Xbefore', 'E776:')
4587 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004588 close
4589 endif
4590
4591 " Test for lines with multiple quickfix entries
4592 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4593 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4594 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4595 edit +1 X2
4596 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004597 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004598 normal 1G
4599 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004600 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004601
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004602 normal gg
4603 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004604 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004605 normal gg
4606 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004607 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004608
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004609 normal G
4610 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004611 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004612 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004613 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004614 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004615
4616 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004617 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004618 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004619 normal G
4620 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004621 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004622
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004623 normal 10G
4624 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004625 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004626 normal 10G$
4627 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004628 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004629
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004630 normal 10G
4631 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004632 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004633 normal 9G
4634 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004635 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004636
4637 " Invalid range
4638 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004639 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004640 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004641 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004642 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004643 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004644 endif
4645
4646 call delete('X1')
4647 call delete('X2')
4648 call delete('X3')
4649 call delete('X4')
4650endfunc
4651
4652func Test_cbelow()
4653 call Xtest_below('c')
4654 call Xtest_below('l')
4655endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004656
4657func Test_quickfix_count()
4658 let commands = [
4659 \ 'cNext',
4660 \ 'cNfile',
4661 \ 'cabove',
4662 \ 'cbelow',
4663 \ 'cfirst',
4664 \ 'clast',
4665 \ 'cnewer',
4666 \ 'cnext',
4667 \ 'cnfile',
4668 \ 'colder',
4669 \ 'cprevious',
4670 \ 'crewind',
4671 \
4672 \ 'lNext',
4673 \ 'lNfile',
4674 \ 'labove',
4675 \ 'lbelow',
4676 \ 'lfirst',
4677 \ 'llast',
4678 \ 'lnewer',
4679 \ 'lnext',
4680 \ 'lnfile',
4681 \ 'lolder',
4682 \ 'lprevious',
4683 \ 'lrewind',
4684 \ ]
4685 for cmd in commands
4686 call assert_fails('-1' .. cmd, 'E16:')
4687 call assert_fails('.' .. cmd, 'E16:')
4688 call assert_fails('%' .. cmd, 'E16:')
4689 call assert_fails('$' .. cmd, 'E16:')
4690 endfor
4691endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004692
4693" Test for aborting quickfix commands using QuickFixCmdPre
4694func Xtest_qfcmd_abort(cchar)
4695 call s:setup_commands(a:cchar)
4696
4697 call g:Xsetlist([], 'f')
4698
4699 " cexpr/lexpr
4700 let e = ''
4701 try
4702 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4703 catch /.*/
4704 let e = v:exception
4705 endtry
4706 call assert_equal('AbortCmd', e)
4707 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4708
4709 " cfile/lfile
4710 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4711 let e = ''
4712 try
4713 Xfile Xfile1
4714 catch /.*/
4715 let e = v:exception
4716 endtry
4717 call assert_equal('AbortCmd', e)
4718 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4719 call delete('Xfile1')
4720
4721 " cgetbuffer/lgetbuffer
4722 enew!
4723 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4724 let e = ''
4725 try
4726 Xgetbuffer
4727 catch /.*/
4728 let e = v:exception
4729 endtry
4730 call assert_equal('AbortCmd', e)
4731 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4732 enew!
4733
4734 " vimgrep/lvimgrep
4735 let e = ''
4736 try
4737 Xvimgrep /func/ test_quickfix.vim
4738 catch /.*/
4739 let e = v:exception
4740 endtry
4741 call assert_equal('AbortCmd', e)
4742 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4743
4744 " helpgrep/lhelpgrep
4745 let e = ''
4746 try
4747 Xhelpgrep quickfix
4748 catch /.*/
4749 let e = v:exception
4750 endtry
4751 call assert_equal('AbortCmd', e)
4752 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4753
4754 " grep/lgrep
4755 if has('unix')
4756 let e = ''
4757 try
4758 silent Xgrep func test_quickfix.vim
4759 catch /.*/
4760 let e = v:exception
4761 endtry
4762 call assert_equal('AbortCmd', e)
4763 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4764 endif
4765endfunc
4766
4767func Test_qfcmd_abort()
4768 augroup QF_Test
4769 au!
4770 autocmd QuickFixCmdPre * throw "AbortCmd"
4771 augroup END
4772
4773 call Xtest_qfcmd_abort('c')
4774 call Xtest_qfcmd_abort('l')
4775
4776 augroup QF_Test
4777 au!
4778 augroup END
4779endfunc
4780
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004781" Test for using a file in one of the parent directories.
4782func Test_search_in_dirstack()
4783 call mkdir('Xtestdir/a/b/c', 'p')
4784 let save_cwd = getcwd()
4785 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4786 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4787 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4788 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4789
4790 let lines = "Entering dir Xtestdir\n" .
4791 \ "Entering dir a\n" .
4792 \ "Entering dir b\n" .
4793 \ "Xfile2:2:X2_L2\n" .
4794 \ "Leaving dir a\n" .
4795 \ "Xfile1:2:X1_L2\n" .
4796 \ "Xfile3:1:X3_L1\n" .
4797 \ "Entering dir c\n" .
4798 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004799 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004800 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004801 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004802 call assert_equal(11, getqflist({'size' : 0}).size)
4803 call assert_equal(4, getqflist({'idx' : 0}).idx)
4804 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004805 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004806 cnext
4807 call assert_equal(6, getqflist({'idx' : 0}).idx)
4808 call assert_equal('X1_L2', getline('.'))
4809 cnext
4810 call assert_equal(7, getqflist({'idx' : 0}).idx)
4811 call assert_equal(1, line('$'))
4812 call assert_equal('', getline(1))
4813 cnext
4814 call assert_equal(9, getqflist({'idx' : 0}).idx)
4815 call assert_equal(1, line('$'))
4816 call assert_equal('', getline(1))
4817
4818 set efm&
4819 exe 'cd ' . save_cwd
4820 call delete('Xtestdir', 'rf')
4821endfunc
4822
Bram Moolenaar1860bde2020-01-06 21:47:21 +01004823" Test for :cquit
4824func Test_cquit()
4825 " Exit Vim with a non-zero value
4826 if RunVim([], ["cquit 7"], '')
4827 call assert_equal(7, v:shell_error)
4828 endif
4829
4830 if RunVim([], ["50cquit"], '')
4831 call assert_equal(50, v:shell_error)
4832 endif
4833
4834 " Exit Vim with default value
4835 if RunVim([], ["cquit"], '')
4836 call assert_equal(1, v:shell_error)
4837 endif
4838
4839 " Exit Vim with zero value
4840 if RunVim([], ["cquit 0"], '')
4841 call assert_equal(0, v:shell_error)
4842 endif
4843
4844 " Exit Vim with negative value
4845 call assert_fails('-3cquit', 'E16:')
4846endfunc
4847
Bram Moolenaar858ba062020-05-31 23:11:59 +02004848" Test for getting a specific item from a quickfix list
4849func Xtest_getqflist_by_idx(cchar)
4850 call s:setup_commands(a:cchar)
4851 " Empty list
4852 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
4853 Xexpr ['F1:10:L10', 'F1:20:L20']
4854 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
4855 call assert_equal(bufnr('F1'), l[0].bufnr)
4856 call assert_equal(20, l[0].lnum)
4857 call assert_equal('L20', l[0].text)
4858 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
4859 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
4860 %bwipe!
4861endfunc
4862
4863func Test_getqflist_by_idx()
4864 call Xtest_getqflist_by_idx('c')
4865 call Xtest_getqflist_by_idx('l')
4866endfunc
4867
4868" Test for the 'quickfixtextfunc' setting
4869func Tqfexpr(info)
4870 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004871 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004872 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004873 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004874 endif
4875
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004876 let l = []
4877 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4878 let e = qfl[idx]
4879 let s = ''
4880 if e.bufnr != 0
4881 let bname = bufname(e.bufnr)
4882 let s ..= fnamemodify(bname, ':.')
4883 endif
4884 let s ..= '-'
4885 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
4886 let s ..= e.text
4887 call add(l, s)
4888 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02004889
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004890 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004891endfunc
4892
4893func Xtest_qftextfunc(cchar)
4894 call s:setup_commands(a:cchar)
4895
4896 set efm=%f:%l:%c:%m
4897 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02004898 call assert_equal('Tqfexpr', &quickfixtextfunc)
4899 call assert_equal('',
4900 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02004901 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4902 Xwindow
4903 call assert_equal('F1-L10C2-green', getline(1))
4904 call assert_equal('F1-L20C4-blue', getline(2))
4905 Xclose
4906 set quickfixtextfunc&vim
4907 Xwindow
4908 call assert_equal('F1|10 col 2| green', getline(1))
4909 call assert_equal('F1|20 col 4| blue', getline(2))
4910 Xclose
4911 set efm&
4912 set quickfixtextfunc&
4913
4914 " Test for per list 'quickfixtextfunc' setting
4915 func PerQfText(info)
4916 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004917 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004918 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004919 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004920 endif
4921 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004922 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02004923 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004924 let l = []
4925 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4926 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
4927 endfor
4928 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004929 endfunc
4930 set quickfixtextfunc=Tqfexpr
4931 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
4932 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
4933 Xwindow
4934 call assert_equal('Line 10, Col 2', getline(1))
4935 call assert_equal('Line 20, Col 4', getline(2))
4936 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02004937 call assert_equal(function('PerQfText'),
4938 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02004939 " Add entries to the list when the quickfix buffer is hidden
4940 Xaddexpr ['F1:30:6:red']
4941 Xwindow
4942 call assert_equal('Line 30, Col 6', getline(3))
4943 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02004944 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02004945 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02004946 set quickfixtextfunc&
4947 delfunc PerQfText
4948
4949 " Non-existing function
4950 set quickfixtextfunc=Tabc
4951 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4952 call assert_fails("Xwindow", 'E117:')
4953 Xclose
4954 set quickfixtextfunc&
4955
4956 " set option to a non-function
4957 set quickfixtextfunc=[10,\ 20]
4958 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4959 call assert_fails("Xwindow", 'E117:')
4960 Xclose
4961 set quickfixtextfunc&
4962
4963 " set option to a function with different set of arguments
4964 func Xqftext(a, b, c)
4965 return a:a .. a:b .. a:c
4966 endfunc
4967 set quickfixtextfunc=Xqftext
4968 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
4969 call assert_fails("Xwindow", 'E119:')
4970 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004971
4972 " set option to a function that returns a list with non-strings
4973 func Xqftext2(d)
4974 return ['one', [], 'two']
4975 endfunc
4976 set quickfixtextfunc=Xqftext2
4977 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
4978 \ 'E730:')
4979 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02004980 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
4981 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004982 Xclose
4983
Bram Moolenaar858ba062020-05-31 23:11:59 +02004984 set quickfixtextfunc&
4985 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004986 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02004987
4988 " set the global option to a lambda function
4989 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
4990 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4991 Xwindow
4992 call assert_equal(['green', 'blue'], getline(1, '$'))
4993 Xclose
4994 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)
4995 set quickfixtextfunc&
4996
4997 " use a lambda function that returns an empty list
4998 set quickfixtextfunc={d\ ->\ []}
4999 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5000 Xwindow
5001 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5002 \ getline(1, '$'))
5003 Xclose
5004 set quickfixtextfunc&
5005
5006 " use a lambda function that returns a list with empty strings
5007 set quickfixtextfunc={d\ ->\ ['',\ '']}
5008 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5009 Xwindow
5010 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5011 \ getline(1, '$'))
5012 Xclose
5013 set quickfixtextfunc&
5014
5015 " set the per-quickfix list text function to a lambda function
5016 call g:Xsetlist([], ' ',
5017 \ {'quickfixtextfunc' :
5018 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5019 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5020 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5021 Xwindow
5022 call assert_equal('Line 10, Col 2', getline(1))
5023 call assert_equal('Line 20, Col 4', getline(2))
5024 Xclose
5025 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5026 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005027endfunc
5028
5029func Test_qftextfunc()
5030 call Xtest_qftextfunc('c')
5031 call Xtest_qftextfunc('l')
5032endfunc
5033
Bram Moolenaarec98e932020-06-08 19:35:59 +02005034" Running :lhelpgrep command more than once in a help window, doesn't jump to
5035" the help topic
5036func Test_lhelpgrep_from_help_window()
5037 call mkdir('Xtestdir/doc', 'p')
5038 call writefile(['window'], 'Xtestdir/doc/a.txt')
5039 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5040 let save_rtp = &rtp
5041 let &rtp = 'Xtestdir'
5042 lhelpgrep window
5043 lhelpgrep buffer
5044 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5045 lhelpgrep window
5046 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5047 let &rtp = save_rtp
5048 call delete('Xtestdir', 'rf')
5049 new | only!
5050endfunc
5051
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005052" Test for the crash fixed by 7.3.715
5053func Test_setloclist_crash()
5054 %bw!
5055 let g:BufNum = bufnr()
5056 augroup QF_Test
5057 au!
5058 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5059 augroup END
5060
5061 try
5062 lvimgrep /.*/ *.mak
5063 catch /E926:/
5064 endtry
5065 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5066 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5067
5068 augroup QF_Test
5069 au!
5070 augroup END
5071 unlet g:BufNum
5072 %bw!
5073endfunc
5074
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005075" vim: shiftwidth=2 sts=2 expandtab