blob: 608a9553b8c80a611e83409adde2994c784d9325 [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
696 call assert_fails('Xhelpgrep \@<!', 'E480:')
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 Moolenaar1ff2b642016-03-17 22:07:02 +0100811 enew
812
813 augroup testgroup
814 au!
815 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
816 augroup END
817
818 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
819
820 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
Bram Moolenaaraad222c2019-09-06 22:46:09 +0200826 eval qflist->setloclist(0, ' ')
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100827 endfor
828
829 " Test A
830 lrewind
831 enew
832 lopen
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200833 4lnext
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100834 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)
846
847 wincmd n | only
848
849 " 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
862
863 " 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)
883
884 wincmd n | only
885
886 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 Moolenaar0899d692016-03-19 13:35:03 +0100890 augroup testgroup
891 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +0200892 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
Bram Moolenaar0899d692016-03-19 13:35:03 +0100893 augroup END
894
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100895 func! R(n)
Bram Moolenaar0899d692016-03-19 13:35:03 +0100896 quit
897 endfunc
898
899 new
900 let q = []
Bram Moolenaard106e5b2016-04-21 19:38:07 +0200901 call add(q, {'filename': 'test_curwin.txt' })
Bram Moolenaar0899d692016-03-19 13:35:03 +0100902 call setloclist(0, q)
903 call assert_fails('lrewind', 'E924:')
904
905 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 Moolenaar7eba3d22016-03-19 22:54:09 +0100926 if !has('unix')
927 " The 'errorformat' setting is different on non-Unix systems.
928 " This test works only on Unix-like systems.
929 return
930 endif
931
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200932 let l =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200933 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
934 "Xtestfile", line 6 col 19; this is an error
935 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
936 Xtestfile:9: parse error before `asd'
937 make: *** [vim] Error 1
938 in file "Xtestfile" linenr 10: there is an error
939
940 2 returned
941 "Xtestfile", line 11 col 1; this is an error
942 "Xtestfile", line 12 col 2; this is another error
943 "Xtestfile", line 14:10; this is an error in column 10
944 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
945 "Xtestfile", linenr 16: yet another problem
946 Error in "Xtestfile" at line 17:
947 x should be a dot
948 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
949 ^
950 Error in "Xtestfile" at line 18:
951 x should be a dot
952 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
953 .............^
954 Error in "Xtestfile" at line 19:
955 x should be a dot
956 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
957 --------------^
958 Error in "Xtestfile" at line 20:
959 x should be a dot
960 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
961 ^
962
963 Does anyone know what is the problem and how to correction it?
964 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
965 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200966 [DATA]
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100967
968 call writefile(l, 'Xerrorfile1')
969 call writefile(l[:-2], 'Xerrorfile2')
970
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200971 let m =<< [DATA]
972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
987 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
988 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
989 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
991 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
992 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
993[DATA]
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100994 call writefile(m, 'Xtestfile')
995
996 let save_efm = &efm
997 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
998 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
999
1000 exe 'cf Xerrorfile2'
1001 clast
1002 copen
1003 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1004 wincmd p
1005
1006 exe 'cf Xerrorfile1'
1007 call assert_equal([4, 12], [line('.'), col('.')])
1008 cn
1009 call assert_equal([6, 19], [line('.'), col('.')])
1010 cn
1011 call assert_equal([9, 2], [line('.'), col('.')])
1012 cn
1013 call assert_equal([10, 2], [line('.'), col('.')])
1014 cn
1015 call assert_equal([11, 1], [line('.'), col('.')])
1016 cn
1017 call assert_equal([12, 2], [line('.'), col('.')])
1018 cn
1019 call assert_equal([14, 10], [line('.'), col('.')])
1020 cn
1021 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1022 cn
1023 call assert_equal([16, 2], [line('.'), col('.')])
1024 cn
1025 call assert_equal([17, 6], [line('.'), col('.')])
1026 cn
1027 call assert_equal([18, 7], [line('.'), col('.')])
1028 cn
1029 call assert_equal([19, 8], [line('.'), col('.')])
1030 cn
1031 call assert_equal([20, 9], [line('.'), col('.')])
1032 clast
1033 cprev
1034 cprev
1035 wincmd w
1036 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1037 wincmd p
1038
1039 let &efm = save_efm
1040 call delete('Xerrorfile1')
1041 call delete('Xerrorfile2')
1042 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001043endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001044
Bram Moolenaarab47c612016-06-14 22:02:26 +02001045" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001046func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001047 call s:setup_commands(a:cchar)
1048
Bram Moolenaarab47c612016-06-14 22:02:26 +02001049 let save_efm=&efm
1050 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1051
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001052 let lines = ["Entering dir 'dir1/a'",
1053 \ 'habits2.txt:1:Nine Healthy Habits',
1054 \ "Entering dir 'b'",
1055 \ 'habits3.txt:2:0 Hours of television',
1056 \ 'habits2.txt:7:5 Small meals',
1057 \ "Entering dir 'dir1/c'",
1058 \ 'habits4.txt:3:1 Hour of exercise',
1059 \ "Leaving dir 'dir1/c'",
1060 \ "Leaving dir 'dir1/a'",
1061 \ 'habits1.txt:4:2 Liters of water',
1062 \ "Entering dir 'dir2'",
1063 \ 'habits5.txt:5:3 Cups of hot green tea',
1064 \ "Leaving dir 'dir2'"
1065 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001066
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001067 Xexpr ""
1068 for l in lines
1069 Xaddexpr l
1070 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001071
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001072 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001073
1074 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1075 call assert_equal(1, qf[1].lnum)
1076 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1077 call assert_equal(2, qf[3].lnum)
1078 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1079 call assert_equal(7, qf[4].lnum)
1080 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1081 call assert_equal(3, qf[6].lnum)
1082 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1083 call assert_equal(4, qf[9].lnum)
1084 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1085 call assert_equal(5, qf[11].lnum)
1086
1087 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001088endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001089
1090" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001091func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001092 " Create the directory stack and files
1093 call mkdir('dir1')
1094 call mkdir('dir1/a')
1095 call mkdir('dir1/a/b')
1096 call mkdir('dir1/c')
1097 call mkdir('dir2')
1098
1099 let lines = ["Nine Healthy Habits",
1100 \ "0 Hours of television",
1101 \ "1 Hour of exercise",
1102 \ "2 Liters of water",
1103 \ "3 Cups of hot green tea",
1104 \ "4 Short mental breaks",
1105 \ "5 Small meals",
1106 \ "6 AM wake up time",
1107 \ "7 Minutes of laughter",
1108 \ "8 Hours of sleep (at least)",
1109 \ "9 PM end of the day and off to bed"
1110 \ ]
1111 call writefile(lines, 'habits1.txt')
1112 call writefile(lines, 'dir1/a/habits2.txt')
1113 call writefile(lines, 'dir1/a/b/habits3.txt')
1114 call writefile(lines, 'dir1/c/habits4.txt')
1115 call writefile(lines, 'dir2/habits5.txt')
1116
1117 call s:dir_stack_tests('c')
1118 call s:dir_stack_tests('l')
1119
1120 call delete('dir1', 'rf')
1121 call delete('dir2', 'rf')
1122 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001123endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001124
Bram Moolenaar9b457942016-10-09 16:10:05 +02001125" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001126func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001127 call s:setup_commands(a:cchar)
1128
1129 let save_efm = &efm
1130
1131 let &efm =
1132 \ '%Eerror %m %l,' .
1133 \ '%-Wignored %m %l,' .
1134 \ '%+Cmore ignored %m %l,' .
1135 \ '%Zignored end'
1136 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1137 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1138 call assert_equal([['resync', 1, 4, 'E']], l)
1139
1140 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001141endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001142
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001143func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001144 call Xefm_ignore_continuations('c')
1145 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001146endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001147
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001148" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001149func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001150 call s:setup_commands(a:cchar)
1151
Bram Moolenaar049cba92016-06-26 14:38:04 +02001152 let save_efm = &efm
1153
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001154 set efm=%f:%l:%m,%f:%f:%l:%m
1155 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1156
1157 set efm=%f:%l:%m,%f:%l:%r:%m
1158 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1159
1160 set efm=%f:%l:%m,%O:%f:%l:%m
1161 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1162
1163 set efm=%f:%l:%m,%f:%l:%*[^a-z
1164 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1165
1166 set efm=%f:%l:%m,%f:%l:%*c
1167 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1168
1169 set efm=%f:%l:%m,%L%M%N
1170 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1171
1172 set efm=%f:%l:%m,%f:%l:%m:%R
1173 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1174
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001175 " Invalid regular expression
1176 set efm=%\\%%k
1177 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1178
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001179 set efm=
1180 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1181
1182 set efm=%DEntering\ dir\ abc,%f:%l:%m
1183 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1184
1185 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001186endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001187
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001188func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001189 call Xinvalid_efm_Tests('c')
1190 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001191endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001192
1193" TODO:
1194" Add tests for the following formats in 'errorformat'
1195" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001196func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001197 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001198
1199 " Test for %s format in efm
1200 set efm=%f:%s
1201 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001202 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001203 call assert_equal('^\VLine search text\$', l[0].pattern)
1204 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001205
Bram Moolenaaree85df32017-03-19 14:19:50 +01001206 let l = split(execute('clist', ''), "\n")
1207 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1208
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001209 " Test for a long line
1210 cexpr 'Xtestfile:' . repeat('a', 1026)
1211 let l = getqflist()
1212 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1213
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001214 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001215 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001216 [Xtestfile1]
1217 (1,17) error: ';' missing
1218 (21,2) warning: variable 'z' not defined
1219 (67,3) error: end of file found before string ended
1220 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001221
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001222 [Xtestfile2]
1223 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001224
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001225 [Xtestfile3]
1226 NEW compiler v1.1
1227 (2,2) warning: variable 'x' not defined
1228 (67,3) warning: 's' already defined
1229 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001230 [DATA]
1231
Bram Moolenaaree85df32017-03-19 14:19:50 +01001232 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001233 " To exercise the push/pop file functionality in quickfix, the test files
1234 " need to be created.
1235 call writefile(['Line1'], 'Xtestfile1')
1236 call writefile(['Line2'], 'Xtestfile2')
1237 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001238 cexpr ""
1239 for l in lines
1240 caddexpr l
1241 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001242 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001243 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001244 call assert_equal(21, l[2].lnum)
1245 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001246 call assert_equal('w', l[2].type)
1247 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001248 call delete('Xtestfile1')
1249 call delete('Xtestfile2')
1250 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001251
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001252 " Test for %P, %Q with non-existing files
1253 cexpr lines
1254 let l = getqflist()
1255 call assert_equal(14, len(l))
1256 call assert_equal('[Xtestfile1]', l[0].text)
1257 call assert_equal('[Xtestfile2]', l[6].text)
1258 call assert_equal('[Xtestfile3]', l[9].text)
1259
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001260 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001261 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001262 Error 275
1263 line 42
1264 column 3
1265 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001266 [DATA]
1267
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001268 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1269 cgetexpr lines
1270 let l = getqflist()
1271 call assert_equal(275, l[0].nr)
1272 call assert_equal(42, l[0].lnum)
1273 call assert_equal(3, l[0].col)
1274 call assert_equal('E', l[0].type)
1275 call assert_equal("\n' ' expected after '--'", l[0].text)
1276
1277 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001278 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001279 Error in line 147 of foo.c:
1280 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001281 [DATA]
1282
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001283 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1284 cgetexpr lines
1285 let l = getqflist()
1286 call assert_equal(147, l[0].lnum)
1287 call assert_equal('E', l[0].type)
1288 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001289
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001290 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001291 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001292 ==============================================================
1293 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1294 --------------------------------------------------------------
1295 Traceback (most recent call last):
1296 File "unittests/dbfacadeTest.py", line 89, in testFoo
1297 self.assertEquals(34, dtid)
1298 File "/usr/lib/python2.2/unittest.py", line 286, in
1299 failUnlessEqual
1300 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001301 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001302
1303 --------------------------------------------------------------
1304 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001305 [DATA]
1306
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001307 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001308 cgetexpr lines
1309 let l = getqflist()
1310 call assert_equal(8, len(l))
1311 call assert_equal(89, l[4].lnum)
1312 call assert_equal(1, l[4].valid)
1313 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001314 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001315
Bram Moolenaard76ce852018-05-01 15:02:04 +02001316 " Test for %o
1317 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001318 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1319 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001320 let l = getqflist()
1321 call assert_equal(1, len(l), string(l))
1322 call assert_equal('Language.PureScript.Types', l[0].module)
1323 copen
1324 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1325 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001326 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001327 cclose
1328 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001329 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001330
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001331 " Test for a long module name
1332 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1333 let l = getqflist()
1334 call assert_equal(repeat('m', 1024), l[0].module)
1335 call assert_equal(15, l[0].lnum)
1336 call assert_equal('message', l[0].text)
1337
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001338 " The following sequence of commands used to crash Vim
1339 set efm=%W%m
1340 cgetexpr ['msg1']
1341 let l = getqflist()
1342 call assert_equal(1, len(l), string(l))
1343 call assert_equal('msg1', l[0].text)
1344 set efm=%C%m
1345 lexpr 'msg2'
1346 let l = getloclist(0)
1347 call assert_equal(1, len(l), string(l))
1348 call assert_equal('msg2', l[0].text)
1349 lopen
1350 call setqflist([], 'r')
1351 caddbuf
1352 let l = getqflist()
1353 call assert_equal(1, len(l), string(l))
1354 call assert_equal('|| msg2', l[0].text)
1355
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001356 " When matching error lines, case should be ignored. Test for this.
1357 set noignorecase
1358 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1359 call assert_equal(10, l.items[0].lnum)
1360 call assert_equal('Line 20', l.items[0].text)
1361 set ignorecase&
1362
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001363 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001364 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001365endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001366
Bram Moolenaare9283662020-06-07 14:10:47 +02001367" Test for '%t' (error type) field in 'efm'
1368func Test_efm_error_type()
1369 let save_efm = &efm
1370
1371 " error type
1372 set efm=%f:%l:%t:%m
1373 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1374 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1375 let output = split(execute('clist'), "\n")
1376 call assert_equal([
1377 \ ' 1 Xfile1:10 error: msg1',
1378 \ ' 2 Xfile1:20 warning: msg2',
1379 \ ' 3 Xfile1:30 info: msg3',
1380 \ ' 4 Xfile1:40 note: msg4',
1381 \ ' 5 Xfile1:50 R: msg5'], output)
1382
1383 " error type and a error number
1384 set efm=%f:%l:%t:%n:%m
1385 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1386 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1387 let output = split(execute('clist'), "\n")
1388 call assert_equal([
1389 \ ' 1 Xfile1:10 error 2: msg1',
1390 \ ' 2 Xfile1:20 warning 4: msg2',
1391 \ ' 3 Xfile1:30 info 6: msg3',
1392 \ ' 4 Xfile1:40 note 8: msg4',
1393 \ ' 5 Xfile1:50 R 3: msg5'], output)
1394 let &efm = save_efm
1395endfunc
1396
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001397func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001398 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001399 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001400 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001401 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001402 colder
1403 cgetexpr []
1404 endfunc
1405 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001406 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001407 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001408 lolder
1409 lgetexpr []
1410 endfunc
1411 endif
1412
1413 augroup testgroup
1414 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001415 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001416 augroup END
1417
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001418 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001419 let words = [ "a", "b" ]
1420 let qflist = []
1421 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001422 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001423 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001424 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001425 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001426
1427 augroup! testgroup
1428endfunc
1429
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001430func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001431 call XquickfixChangedByAutocmd('c')
1432 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001433endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001434
1435func Test_caddbuffer_to_empty()
1436 helpgr quickfix
1437 call setqflist([], 'r')
1438 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001439 try
1440 cn
1441 catch
1442 " number of matches is unknown
1443 call assert_true(v:exception =~ 'E553:')
1444 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001445 quit!
1446endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001447
1448func Test_cgetexpr_works()
1449 " this must not crash Vim
1450 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001451 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001452endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001453
1454" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001455func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001456 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001457
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001458 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001459 \ {'bufnr': a:bnum, 'lnum': 2}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001460 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001461 call assert_equal(2, len(l))
1462 call assert_equal(2, l[1].lnum)
1463
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001464 Xnext
1465 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1466 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001467 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001468 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001469 call assert_equal(3, line('.'))
1470
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001471 " Appending entries to the list should not change the cursor position
1472 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001473 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001474 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001475 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001476 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1477 call assert_equal(1, line('.'))
1478 close
1479
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001480 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001481 \ {'bufnr': a:bnum, 'lnum': 4},
1482 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001483 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001484 call assert_equal(3, len(l))
1485 call assert_equal(5, l[2].lnum)
1486
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001487 call g:Xsetlist([])
1488 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001489 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001490
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001491 " Tests for setting the 'valid' flag
1492 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1493 Xwindow
1494 call assert_equal(1, winnr('$'))
1495 let l = g:Xgetlist()
1496 call g:Xsetlist(l)
1497 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001498 " Adding a non-valid entry should not mark the list as having valid entries
1499 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1500 Xwindow
1501 call assert_equal(1, winnr('$'))
1502
1503 " :cnext/:cprev should still work even with invalid entries in the list
1504 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1505 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1506 call g:Xsetlist(l)
1507 Xnext
1508 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1509 Xprev
1510 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1511 " :cnext/:cprev should still work after appending invalid entries to an
1512 " empty list
1513 call g:Xsetlist([])
1514 call g:Xsetlist(l, 'a')
1515 Xnext
1516 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1517 Xprev
1518 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1519
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001520 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1521 Xwindow
1522 call assert_equal(2, winnr('$'))
1523 Xclose
1524 let save_efm = &efm
1525 set efm=%m
1526 Xgetexpr 'TestMessage'
1527 let l = g:Xgetlist()
1528 call g:Xsetlist(l)
1529 call assert_equal(1, g:Xgetlist()[0].valid)
1530 let &efm = save_efm
1531
Bram Moolenaaree85df32017-03-19 14:19:50 +01001532 " Error cases:
1533 " Refer to a non-existing buffer and pass a non-dictionary type
1534 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1535 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1536 call g:Xsetlist([[1, 2,3]])
1537 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001538 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001539endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001540
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001541func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001542 new Xtestfile | only
1543 let bnum = bufnr('%')
1544 call setline(1, range(1,5))
1545
1546 call SetXlistTests('c', bnum)
1547 call SetXlistTests('l', bnum)
1548
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001549 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001550 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001551endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001552
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001553func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001554 call s:setup_commands(a:cchar)
1555
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001556 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001557 let @/ = 'Test_'
1558 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001559 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001560 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001561 Xvimgrep empty test_quickfix.vim
1562 call assert_true(len(g:Xgetlist()) > 0)
1563 Xvimgrep matches test_quickfix.vim
1564 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001565 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001566 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001567 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001568 call g:Xsetlist([], 'r')
1569 call assert_true(len(g:Xgetlist()) == 0)
1570 Xolder
1571 call assert_equal(testlen, len(g:Xgetlist()))
1572 Xnewer
1573 Xnewer
1574 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001575endfunc
1576
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001577func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001578 call Xlist_empty_middle('c')
1579 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001580endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001581
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001582func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001583 call s:setup_commands(a:cchar)
1584
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001585 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001586 Xvimgrep one test_quickfix.vim
1587 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001588 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001589 Xvimgrep two test_quickfix.vim
1590 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001591 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001592 Xvimgrep three test_quickfix.vim
1593 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001594 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001595 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001596 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001597 call g:Xsetlist([], 'r')
1598 call assert_true(len(g:Xgetlist()) == 0)
1599 Xnewer
1600 call assert_equal(twolen, len(g:Xgetlist()))
1601 Xnewer
1602 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001603endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001604
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001605func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001606 call Xlist_empty_older('c')
1607 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001608endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001609
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001610func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001611 call s:setup_commands(a:cchar)
1612
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001613 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1614 \ {'filename': 'fnameB', 'text': 'B'}]
1615 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1616 \ {'filename': 'fnameD', 'text': 'D'},
1617 \ {'filename': 'fnameE', 'text': 'E'}]
1618
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001619 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001620 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001621 silent! Xnewer 99
1622 call g:Xsetlist(list1)
1623 call g:Xsetlist(list2)
1624 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001625 call assert_equal(3, len(li))
1626 call assert_equal('C', li[0]['text'])
1627 call assert_equal('D', li[1]['text'])
1628 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001629 silent! Xolder
1630 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001631 call assert_equal(2, len(li))
1632 call assert_equal('A', li[0]['text'])
1633 call assert_equal('B', li[1]['text'])
1634
1635 " {action} is specified ' '.
1636 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001637 silent! Xnewer 99
1638 call g:Xsetlist(list1)
1639 call g:Xsetlist(list2, ' ')
1640 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001641 call assert_equal(3, len(li))
1642 call assert_equal('C', li[0]['text'])
1643 call assert_equal('D', li[1]['text'])
1644 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001645 silent! Xolder
1646 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001647 call assert_equal(2, len(li))
1648 call assert_equal('A', li[0]['text'])
1649 call assert_equal('B', li[1]['text'])
1650
1651 " {action} is specified 'a'.
1652 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 silent! Xnewer 99
1654 call g:Xsetlist(list1)
1655 call g:Xsetlist(list2, 'a')
1656 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001657 call assert_equal(5, len(li))
1658 call assert_equal('A', li[0]['text'])
1659 call assert_equal('B', li[1]['text'])
1660 call assert_equal('C', li[2]['text'])
1661 call assert_equal('D', li[3]['text'])
1662 call assert_equal('E', li[4]['text'])
1663
1664 " {action} is specified 'r'.
1665 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001666 silent! Xnewer 99
1667 call g:Xsetlist(list1)
1668 call g:Xsetlist(list2, 'r')
1669 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001670 call assert_equal(3, len(li))
1671 call assert_equal('C', li[0]['text'])
1672 call assert_equal('D', li[1]['text'])
1673 call assert_equal('E', li[2]['text'])
1674
1675 " Test for wrong value.
1676 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001677 call assert_fails("call g:Xsetlist(0)", 'E714:')
1678 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1679 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1680 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1681 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001682endfunc
1683
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001684func Test_setqflist_invalid_nr()
1685 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001686 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001687endfunc
1688
Bram Moolenaar99234f22020-02-10 22:56:54 +01001689func Test_setqflist_user_sets_buftype()
1690 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1691 set buftype=quickfix
1692 call setqflist([], 'a')
1693 enew
1694endfunc
1695
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001696func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001697 call XquickfixSetListWithAct('c')
1698 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001699endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001700
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001701func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001702 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001703
Bram Moolenaar049cba92016-06-26 14:38:04 +02001704 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001705 call assert_equal(1, l[0].lnum)
1706 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001707 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001708 call assert_equal(2, l[1].lnum)
1709 call assert_equal(1, l[1].col)
1710 call assert_equal(4070, len(l[1].text))
1711 call assert_equal(3, l[2].lnum)
1712 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001713 call assert_equal(4070, len(l[2].text))
1714 call assert_equal(4, l[3].lnum)
1715 call assert_equal(1, l[3].col)
1716 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001717
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001718 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001719endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001720
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001721func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001722 call s:setup_commands(a:cchar)
1723
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001724 let testfile = 'samples/quickfix.txt'
1725
1726 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001727 exe 'Xgetfile' testfile
1728 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001729
1730 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001731 Xexpr readfile(testfile)
1732 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001733
1734 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 Xexpr join(readfile(testfile), "\n")
1736 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001737
1738 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001739 exe 'edit' testfile
1740 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001741 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001742endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001743
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001744func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001745 call s:long_lines_tests('c')
1746 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001747endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001748
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001749func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001750 let l = []
1751 for i in range(1, 20)
1752 call add(l, 'Line' . i)
1753 endfor
1754 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001755endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001756
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001758 call s:create_test_file('Xqftestfile1')
1759 call s:create_test_file('Xqftestfile2')
1760 call s:create_test_file('Xqftestfile3')
1761
1762 new | only
1763 edit Xqftestfile1
1764 let file1_winid = win_getid()
1765 new Xqftestfile2
1766 let file2_winid = win_getid()
1767 cgetexpr ['Xqftestfile1:5:Line5',
1768 \ 'Xqftestfile1:6:Line6',
1769 \ 'Xqftestfile2:10:Line10',
1770 \ 'Xqftestfile2:11:Line11',
1771 \ 'Xqftestfile3:15:Line15',
1772 \ 'Xqftestfile3:16:Line16']
1773
1774 new
1775 let winid = win_getid()
1776 cfirst | cnext
1777 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 Moolenaar99895ea2017-04-20 22:44:47 +02001780 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001781 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001782
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001783 " Test for 'switchbuf' set to search for files in windows in the current
1784 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001785 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001786 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001787 cfirst | cnext
1788 call assert_equal(file1_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())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001791 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001792 call assert_equal(file2_winid, win_getid())
1793
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001794 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1795 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001796 enew | only
1797 set switchbuf=usetab
1798 tabedit Xqftestfile1
1799 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001800 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001801 tabfirst
1802 cfirst | cnext
1803 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001804 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001805 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001806 6cnext
1807 call assert_equal(4, tabpagenr())
1808 2cpfile
1809 call assert_equal(2, tabpagenr())
1810 2cnfile
1811 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001812 tabfirst | tabonly | enew
1813
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001814 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001815 set switchbuf=split
1816 cfirst | cnext
1817 call assert_equal(1, winnr('$'))
1818 cnext | cnext
1819 call assert_equal(2, winnr('$'))
1820 cnext | cnext
1821 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001822
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001823 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001824 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001825 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001826 cfirst | cnext
1827 call assert_equal(1, tabpagenr('$'))
1828 cnext | cnext
1829 call assert_equal(2, tabpagenr('$'))
1830 cnext | cnext
1831 call assert_equal(3, tabpagenr('$'))
1832 tabfirst | enew | tabonly | only
1833
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001834 set switchbuf=uselast
1835 split
1836 let last_winid = win_getid()
1837 copen
1838 exe "normal 1G\<CR>"
1839 call assert_equal(last_winid, win_getid())
1840 enew | only
1841
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001842 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1843 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001844 set switchbuf=
1845 edit Xqftestfile1
1846 let file1_winid = win_getid()
1847 new Xqftestfile2
1848 let file2_winid = win_getid()
1849 copen
1850 exe "normal 1G\<CR>"
1851 call assert_equal(file1_winid, win_getid())
1852 copen
1853 exe "normal 3G\<CR>"
1854 call assert_equal(file2_winid, win_getid())
1855 copen | only
1856 exe "normal 5G\<CR>"
1857 call assert_equal(2, winnr('$'))
1858 call assert_equal(1, bufwinnr('Xqftestfile3'))
1859
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001860 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001861 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001862 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001863 set switchbuf=usetab
1864 tabedit Xqftestfile1
1865 tabedit Xqftestfile2
1866 tabedit Xqftestfile3
1867 tabfirst
1868 copen | only
1869 clast
1870 call assert_equal(4, tabpagenr())
1871 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001872
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001873 " Jumping to a file that is not present in any of the tabpages and the
1874 " current tabpage doesn't have any usable windows, should open it in a new
1875 " window in the current tabpage.
1876 copen | only
1877 cfirst
1878 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001879 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001880
1881 " If opening a file changes 'switchbuf', then the new value should be
1882 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001883 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001884 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1885 enew | only
1886 set switchbuf&vim
1887 cexpr "Xqftestfile1:1:10"
1888 call assert_equal('split', &switchbuf)
1889 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1890 enew | only
1891 set switchbuf=useopen
1892 cexpr "Xqftestfile1:1:10"
1893 call assert_equal('usetab', &switchbuf)
1894 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1895 enew | only
1896 set switchbuf=useopen
1897 cexpr "Xqftestfile1:1:10"
1898 call assert_equal('', &switchbuf)
1899
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 call delete('Xqftestfile1')
1901 call delete('Xqftestfile2')
1902 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001903 set switchbuf&vim
1904
1905 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001906endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001907
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001908func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001909 call s:setup_commands(a:cchar)
1910
1911 enew | only
1912
Bram Moolenaarc1542742016-07-20 21:44:37 +02001913 let fname = 'Xqftestfile' . a:cchar
1914 call s:create_test_file(fname)
1915 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02001916
Bram Moolenaarc1542742016-07-20 21:44:37 +02001917 Xgetexpr [fname . ':5:Line5',
1918 \ fname . ':10:Line10',
1919 \ fname . ':15:Line15',
1920 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02001921
1922 6,14delete
1923 call append(6, ['Buffer', 'Window'])
1924
1925 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001926 call assert_equal(5, l[0].lnum)
1927 call assert_equal(6, l[2].lnum)
1928 call assert_equal(13, l[3].lnum)
1929
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001930 " If a file doesn't have any quickfix entries, then deleting lines in the
1931 " file should not update the quickfix list
1932 call g:Xsetlist([], 'f')
1933 1,2delete
1934 call assert_equal([], g:Xgetlist())
1935
Bram Moolenaar049cba92016-06-26 14:38:04 +02001936 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02001937 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001938endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001939
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001940func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02001941 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001942 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02001943 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02001944 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001945endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001946
1947" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001948func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001949 call s:setup_commands(a:cchar)
1950
1951 " The following lines are used for the grep test. Don't remove.
1952 " Grep_Test_Text: Match 1
1953 " Grep_Test_Text: Match 2
1954 " GrepAdd_Test_Text: Match 1
1955 " GrepAdd_Test_Text: Match 2
1956 enew! | only
1957 set makeef&vim
1958 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001959 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001960 Xopen
1961 call assert_true(w:quickfix_title =~ '^:grep')
1962 Xclose
1963 enew
1964 set makeef=Temp_File_##
1965 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001966 call assert_true(len(g:Xgetlist()) == 9)
1967
1968 " Try with 'grepprg' set to 'internal'
1969 set grepprg=internal
1970 silent Xgrep Grep_Test_Text: test_quickfix.vim
1971 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1972 call assert_true(len(g:Xgetlist()) == 9)
1973 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001974
1975 call writefile(['Vim'], 'XtestTempFile')
1976 set makeef=XtestTempFile
1977 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01001978 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001979 call assert_false(filereadable('XtestTempFile'))
1980 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001981endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001982
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001983func Test_grep()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001984 if !has('unix')
1985 " The grepprg may not be set on non-Unix systems
1986 return
1987 endif
1988
1989 call s:test_xgrep('c')
1990 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001991endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001992
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001993func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001994 " Use one 'errorformat' for two windows. Add an expression to each of them,
1995 " make sure they each keep their own state.
1996 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1997 call mkdir('Xone/a', 'p')
1998 call mkdir('Xtwo/a', 'p')
1999 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2000 call writefile(lines, 'Xone/a/one.txt')
2001 call writefile(lines, 'Xtwo/a/two.txt')
2002
2003 new one
2004 let one_id = win_getid()
2005 lexpr ""
2006 new two
2007 let two_id = win_getid()
2008 lexpr ""
2009
2010 laddexpr "Entering dir 'Xtwo/a'"
2011 call win_gotoid(one_id)
2012 laddexpr "Entering dir 'Xone/a'"
2013 call win_gotoid(two_id)
2014 laddexpr 'two.txt:5:two two two'
2015 call win_gotoid(one_id)
2016 laddexpr 'one.txt:3:one one one'
2017
2018 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002019 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2020 call assert_equal(3, loc_one[1].lnum)
2021
2022 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002023 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2024 call assert_equal(5, loc_two[1].lnum)
2025
2026 call win_gotoid(one_id)
2027 bwipe!
2028 call win_gotoid(two_id)
2029 bwipe!
2030 call delete('Xone', 'rf')
2031 call delete('Xtwo', 'rf')
2032endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002033
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002034func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002035 call s:setup_commands(a:cchar)
2036
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002037 " Calling lbottom without any errors should fail
2038 if a:cchar == 'l'
2039 call assert_fails('lbottom', 'E776:')
2040 endif
2041
Bram Moolenaar875feea2017-06-11 16:07:51 +02002042 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002043 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002044 let wid = win_getid()
2045 call assert_equal(1, line('.'))
2046 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002047 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002048 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002049 call win_gotoid(wid)
2050 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002051 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002052endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002053
2054" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002055func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002056 call XbottomTests('c')
2057 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002058endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002059
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002060func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002061 call s:setup_commands(a:cchar)
2062
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002063 " clear all lists after the first one, then replace the first one.
2064 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002065 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002066 let entry = {'filename': 'foo', 'lnum': 42}
2067 call g:Xsetlist([entry], 'r')
2068 call g:Xsetlist([entry, entry])
2069 call g:Xsetlist([entry, entry, entry])
2070 let res = split(execute(a:cchar . 'hist'), "\n")
2071 call assert_equal(3, len(res))
2072 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2073 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2074 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2075 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002076
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002077 " Test for changing the quickfix lists
2078 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2079 exe '1' . a:cchar . 'hist'
2080 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2081 exe '3' . a:cchar . 'hist'
2082 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2083 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2084 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2085
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002086 call g:Xsetlist([], 'f')
2087 let l = split(execute(a:cchar . 'hist'), "\n")
2088 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002089 if a:cchar == 'c'
2090 call assert_fails('4chist', 'E16:')
2091 else
2092 call assert_fails('4lhist', 'E776:')
2093 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002094
2095 " An empty list should still show the stack history
2096 call g:Xsetlist([])
2097 let res = split(execute(a:cchar . 'hist'), "\n")
2098 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2099
2100 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002101endfunc
2102
2103func Test_history()
2104 call HistoryTest('c')
2105 call HistoryTest('l')
2106endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002107
2108func Test_duplicate_buf()
2109 " make sure we can get the highest buffer number
2110 edit DoesNotExist
2111 edit DoesNotExist2
2112 let last_buffer = bufnr("$")
2113
2114 " make sure only one buffer is created
2115 call writefile(['this one', 'that one'], 'Xgrepthis')
2116 vimgrep one Xgrepthis
2117 vimgrep one Xgrepthis
2118 call assert_equal(last_buffer + 1, bufnr("$"))
2119
2120 call delete('Xgrepthis')
2121endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002122
2123" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002124func Xproperty_tests(cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002125 call s:setup_commands(a:cchar)
2126
2127 " Error cases
2128 call assert_fails('call g:Xgetlist(99)', 'E715:')
2129 call assert_fails('call g:Xsetlist(99)', 'E714:')
2130 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
2131
2132 " Set and get the title
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002133 call g:Xsetlist([])
Bram Moolenaard823fa92016-08-12 16:29:27 +02002134 Xopen
2135 wincmd p
2136 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002137 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2138 call assert_equal(0, s)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002139 let d = g:Xgetlist({"title":1})
2140 call assert_equal('Sample', d.title)
Bram Moolenaara2aa8a22018-04-24 13:55:00 +02002141 " Try setting title to a non-string value
2142 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2143 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002144
2145 Xopen
2146 call assert_equal('Sample', w:quickfix_title)
2147 Xclose
2148
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002149 " Tests for action argument
2150 silent! Xolder 999
2151 let qfnr = g:Xgetlist({'all':1}).nr
2152 call g:Xsetlist([], 'r', {'title' : 'N1'})
2153 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2154 call g:Xsetlist([], ' ', {'title' : 'N2'})
2155 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
Bram Moolenaar890680c2016-09-27 21:28:56 +02002156
2157 let res = g:Xgetlist({'nr': 0})
2158 call assert_equal(qfnr + 1, res.nr)
2159 call assert_equal(['nr'], keys(res))
2160
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002161 call g:Xsetlist([], ' ', {'title' : 'N3'})
2162 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2163
Bram Moolenaaree85df32017-03-19 14:19:50 +01002164 " Changing the title of an earlier quickfix list
Bram Moolenaar55b69262017-08-13 13:42:01 +02002165 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
Bram Moolenaaree85df32017-03-19 14:19:50 +01002166 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2167
2168 " Changing the title of an invalid quickfix list
2169 call assert_equal(-1, g:Xsetlist([], ' ',
2170 \ {'title' : 'SomeTitle', 'nr' : 99}))
2171 call assert_equal(-1, g:Xsetlist([], ' ',
2172 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2173
2174 if a:cchar == 'c'
2175 copen
2176 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2177 cclose
2178 endif
2179
Bram Moolenaard823fa92016-08-12 16:29:27 +02002180 " Invalid arguments
2181 call assert_fails('call g:Xgetlist([])', 'E715')
2182 call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
2183 let s = g:Xsetlist([], 'a', {'abc':1})
2184 call assert_equal(-1, s)
2185
2186 call assert_equal({}, g:Xgetlist({'abc':1}))
Bram Moolenaara6d48492017-12-12 22:45:31 +01002187 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2188 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002189
2190 if a:cchar == 'l'
Bram Moolenaar890680c2016-09-27 21:28:56 +02002191 call assert_equal({}, getloclist(99, {'title': 1}))
Bram Moolenaard823fa92016-08-12 16:29:27 +02002192 endif
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002193
2194 " Context related tests
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002195 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2196 call assert_equal(0, s)
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002197 call test_garbagecollect_now()
2198 let d = g:Xgetlist({'context':1})
2199 call assert_equal([1,2,3], d.context)
2200 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2201 let d = g:Xgetlist({'context':1})
2202 call assert_equal({'color':'green'}, d.context)
2203 call g:Xsetlist([], 'a', {'context':"Context info"})
2204 let d = g:Xgetlist({'context':1})
2205 call assert_equal("Context info", d.context)
2206 call g:Xsetlist([], 'a', {'context':246})
2207 let d = g:Xgetlist({'context':1})
2208 call assert_equal(246, d.context)
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02002209 " set other Vim data types as context
2210 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2211 if has('channel')
2212 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2213 endif
2214 if has('job')
2215 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2216 endif
2217 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2218 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2219 call g:Xsetlist([], 'a', {'context' : ''})
2220 call test_garbagecollect_now()
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002221 if a:cchar == 'l'
2222 " Test for copying context across two different location lists
2223 new | only
2224 let w1_id = win_getid()
2225 let l = [1]
2226 call setloclist(0, [], 'a', {'context':l})
2227 new
2228 let w2_id = win_getid()
2229 call add(l, 2)
2230 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2231 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2232 unlet! l
2233 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2234 only
2235 call setloclist(0, [], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01002236 call assert_equal('', getloclist(0, {'context':1}).context)
Bram Moolenaar8f77c5a2017-04-30 14:21:00 +02002237 endif
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002238
2239 " Test for changing the context of previous quickfix lists
2240 call g:Xsetlist([], 'f')
2241 Xexpr "One"
2242 Xexpr "Two"
2243 Xexpr "Three"
Bram Moolenaar55b69262017-08-13 13:42:01 +02002244 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2245 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002246 " Also, check for setting the context using quickfix list number zero.
Bram Moolenaar55b69262017-08-13 13:42:01 +02002247 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002248 call test_garbagecollect_now()
2249 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2250 call assert_equal([1], l.context)
2251 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2252 call assert_equal([2], l.context)
2253 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2254 call assert_equal([3], l.context)
2255
2256 " Test for changing the context through reference and for garbage
2257 " collection of quickfix context
2258 let l = ["red"]
2259 call g:Xsetlist([], ' ', {'context' : l})
2260 call add(l, "blue")
2261 let x = g:Xgetlist({'context' : 1})
2262 call add(x.context, "green")
2263 call assert_equal(["red", "blue", "green"], l)
2264 call assert_equal(["red", "blue", "green"], x.context)
2265 unlet l
2266 call test_garbagecollect_now()
2267 let m = g:Xgetlist({'context' : 1})
2268 call assert_equal(["red", "blue", "green"], m.context)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002269
2270 " Test for setting/getting items
2271 Xexpr ""
2272 let qfprev = g:Xgetlist({'nr':0})
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002273 let s = g:Xsetlist([], ' ', {'title':'Green',
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002274 \ 'items' : [{'filename':'F1', 'lnum':10}]})
Bram Moolenaar86f100dc2017-06-28 21:26:27 +02002275 call assert_equal(0, s)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002276 let qfcur = g:Xgetlist({'nr':0})
2277 call assert_true(qfcur.nr == qfprev.nr + 1)
2278 let l = g:Xgetlist({'items':1})
2279 call assert_equal('F1', bufname(l.items[0].bufnr))
2280 call assert_equal(10, l.items[0].lnum)
2281 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2282 \ {'filename':'F2', 'lnum':30}]})
2283 let l = g:Xgetlist({'items':1})
2284 call assert_equal('F2', bufname(l.items[2].bufnr))
2285 call assert_equal(30, l.items[2].lnum)
2286 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2287 let l = g:Xgetlist({'items':1})
2288 call assert_equal('F3', bufname(l.items[0].bufnr))
2289 call assert_equal(40, l.items[0].lnum)
2290 call g:Xsetlist([], 'r', {'items' : []})
2291 let l = g:Xgetlist({'items':1})
2292 call assert_equal(0, len(l.items))
2293
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002294 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2295 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2296 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2297 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2298
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02002299 " Test for getting id of window associated with a location list window
2300 if a:cchar == 'l'
2301 only
2302 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2303 let wid = win_getid()
2304 Xopen
2305 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2306 wincmd w
2307 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2308 only
2309 endif
2310
Bram Moolenaarae338332017-08-11 20:25:26 +02002311 " The following used to crash Vim with address sanitizer
2312 call g:Xsetlist([], 'f')
2313 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2314 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
2315
Bram Moolenaara2aa8a22018-04-24 13:55:00 +02002316 " Try setting the items using a string
2317 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
2318
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002319 " Save and restore the quickfix stack
2320 call g:Xsetlist([], 'f')
2321 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2322 Xexpr "File1:10:Line1"
2323 Xexpr "File2:20:Line2"
2324 Xexpr "File3:30:Line3"
2325 let last_qf = g:Xgetlist({'nr':'$'}).nr
2326 call assert_equal(3, last_qf)
2327 let qstack = []
2328 for i in range(1, last_qf)
2329 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2330 endfor
2331 call g:Xsetlist([], 'f')
2332 for i in range(len(qstack))
2333 call g:Xsetlist([], ' ', qstack[i])
2334 endfor
2335 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2336 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2337 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2338 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2339 call g:Xsetlist([], 'f')
2340
2341 " Swap two quickfix lists
2342 Xexpr "File1:10:Line10"
2343 Xexpr "File2:20:Line20"
2344 Xexpr "File3:30:Line30"
2345 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2346 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2347 let l1=g:Xgetlist({'nr':1,'all':1})
2348 let l2=g:Xgetlist({'nr':2,'all':1})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02002349 let save_id = l1.id
2350 let l1.id=l2.id
2351 let l2.id=save_id
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002352 call g:Xsetlist([], 'r', l1)
2353 call g:Xsetlist([], 'r', l2)
2354 let newl1=g:Xgetlist({'nr':1,'all':1})
2355 let newl2=g:Xgetlist({'nr':2,'all':1})
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002356 call assert_equal('Fruits', newl1.title)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002357 call assert_equal(['Fruits'], newl1.context)
2358 call assert_equal('Line20', newl1.items[0].text)
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002359 call assert_equal('Colors', newl2.title)
Bram Moolenaar6a8958d2017-06-22 21:33:20 +02002360 call assert_equal(['Colors'], newl2.context)
2361 call assert_equal('Line10', newl2.items[0].text)
2362 call g:Xsetlist([], 'f')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002363endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002364
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002365func Test_qf_property()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002366 call Xproperty_tests('c')
2367 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002368endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002369
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002370" Test for setting the current index in the location/quickfix list
2371func Xtest_setqfidx(cchar)
2372 call s:setup_commands(a:cchar)
2373
2374 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2375 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2376 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2377
2378 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2379 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2380 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2381 Xolder 2
2382 Xopen
2383 call assert_equal(3, line('.'))
2384 Xnewer
2385 call assert_equal(2, line('.'))
2386 Xnewer
2387 call assert_equal(2, line('.'))
2388 " Update the current index with the quickfix window open
2389 wincmd w
2390 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2391 Xopen
2392 call assert_equal(3, line('.'))
2393 Xclose
2394
2395 " Set the current index to the last entry
2396 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2397 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2398 " A large value should set the index to the last index
2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2400 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2401 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2402 " Invalid index values
2403 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2404 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2405 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2406 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2407 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2408 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2409 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2410
2411 call g:Xsetlist([], 'f')
2412 new | only
2413endfunc
2414
2415func Test_setqfidx()
2416 call Xtest_setqfidx('c')
2417 call Xtest_setqfidx('l')
2418endfunc
2419
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002420" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002421func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002422 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002423endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002424
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002425func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002426 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2427 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2428
2429 let g:acmds = []
2430 cexpr "F1:10:Line 10"
2431 caddexpr "F1:20:Line 20"
2432 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002433 cexpr ""
2434 caddexpr ""
2435 cgetexpr ""
2436 silent! cexpr non_existing_func()
2437 silent! caddexpr non_existing_func()
2438 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002439 let l = ['precexpr',
2440 \ 'postcexpr',
2441 \ 'precaddexpr',
2442 \ 'postcaddexpr',
2443 \ 'precgetexpr',
2444 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002445 \ 'precexpr',
2446 \ 'postcexpr',
2447 \ 'precaddexpr',
2448 \ 'postcaddexpr',
2449 \ 'precgetexpr',
2450 \ 'postcgetexpr',
2451 \ 'precexpr',
2452 \ 'precaddexpr',
2453 \ 'precgetexpr']
2454 call assert_equal(l, g:acmds)
2455
2456 let g:acmds = []
2457 enew! | call append(0, "F2:10:Line 10")
2458 cbuffer!
2459 enew! | call append(0, "F2:20:Line 20")
2460 cgetbuffer
2461 enew! | call append(0, "F2:30:Line 30")
2462 caddbuffer
2463 new
2464 let bnum = bufnr('%')
2465 bunload
2466 exe 'silent! cbuffer! ' . bnum
2467 exe 'silent! cgetbuffer ' . bnum
2468 exe 'silent! caddbuffer ' . bnum
2469 enew!
2470 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002471 \ 'postcbuffer',
2472 \ 'precgetbuffer',
2473 \ 'postcgetbuffer',
2474 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002475 \ 'postcaddbuffer',
2476 \ 'precbuffer',
2477 \ 'precgetbuffer',
2478 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002479 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002480
2481 call writefile(['Xtest:1:Line1'], 'Xtest')
2482 call writefile([], 'Xempty')
2483 let g:acmds = []
2484 cfile Xtest
2485 caddfile Xtest
2486 cgetfile Xtest
2487 cfile Xempty
2488 caddfile Xempty
2489 cgetfile Xempty
2490 silent! cfile do_not_exist
2491 silent! caddfile do_not_exist
2492 silent! cgetfile do_not_exist
2493 let l = ['precfile',
2494 \ 'postcfile',
2495 \ 'precaddfile',
2496 \ 'postcaddfile',
2497 \ 'precgetfile',
2498 \ 'postcgetfile',
2499 \ 'precfile',
2500 \ 'postcfile',
2501 \ 'precaddfile',
2502 \ 'postcaddfile',
2503 \ 'precgetfile',
2504 \ 'postcgetfile',
2505 \ 'precfile',
2506 \ 'postcfile',
2507 \ 'precaddfile',
2508 \ 'postcaddfile',
2509 \ 'precgetfile',
2510 \ 'postcgetfile']
2511 call assert_equal(l, g:acmds)
2512
2513 let g:acmds = []
2514 helpgrep quickfix
2515 silent! helpgrep non_existing_help_topic
2516 vimgrep test Xtest
2517 vimgrepadd test Xtest
2518 silent! vimgrep non_existing_test Xtest
2519 silent! vimgrepadd non_existing_test Xtest
2520 set makeprg=
2521 silent! make
2522 set makeprg&
2523 let l = ['prehelpgrep',
2524 \ 'posthelpgrep',
2525 \ 'prehelpgrep',
2526 \ 'posthelpgrep',
2527 \ 'previmgrep',
2528 \ 'postvimgrep',
2529 \ 'previmgrepadd',
2530 \ 'postvimgrepadd',
2531 \ 'previmgrep',
2532 \ 'postvimgrep',
2533 \ 'previmgrepadd',
2534 \ 'postvimgrepadd',
2535 \ 'premake',
2536 \ 'postmake']
2537 call assert_equal(l, g:acmds)
2538
2539 if has('unix')
2540 " Run this test only on Unix-like systems. The grepprg may not be set on
2541 " non-Unix systems.
2542 " The following lines are used for the grep test. Don't remove.
2543 " Grep_Autocmd_Text: Match 1
2544 " GrepAdd_Autocmd_Text: Match 2
2545 let g:acmds = []
2546 silent grep Grep_Autocmd_Text test_quickfix.vim
2547 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2548 silent grep abc123def Xtest
2549 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002550 set grepprg=internal
2551 silent grep Grep_Autocmd_Text test_quickfix.vim
2552 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2553 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2554 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2555 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002556 let l = ['pregrep',
2557 \ 'postgrep',
2558 \ 'pregrepadd',
2559 \ 'postgrepadd',
2560 \ 'pregrep',
2561 \ 'postgrep',
2562 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002563 \ 'postgrepadd',
2564 \ 'pregrep',
2565 \ 'postgrep',
2566 \ 'pregrepadd',
2567 \ 'postgrepadd',
2568 \ 'prelgrep',
2569 \ 'postlgrep',
2570 \ 'prelgrepadd',
2571 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002572 call assert_equal(l, g:acmds)
2573 endif
2574
2575 call delete('Xtest')
2576 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002577 au! QuickFixCmdPre
2578 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002579endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002580
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002581func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002582 set efm=%m
2583 lgetexpr '?'
2584
2585 try
2586 call DoesNotExit()
2587 catch
2588 lgetexpr '1'
2589 finally
2590 lgetexpr '1'
2591 endtry
2592
2593 call assert_equal('1', getloclist(0)[0].text)
2594
2595 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002596endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002597
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002598func Test_caddbuffer_wrong()
2599 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002600 let save_efm = &efm
2601 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2602 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2603 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002604 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002605 bwipe!
2606endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002607
2608func Test_caddexpr_wrong()
2609 " This used to cause a memory access in freed memory.
2610 cbuffer
2611 cbuffer
2612 copen
2613 let save_efm = &efm
2614 set efm=%
2615 call assert_fails('caddexpr ""', 'E376:')
2616 let &efm = save_efm
2617endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002618
2619func Test_dirstack_cleanup()
2620 " This used to cause a memory access in freed memory.
2621 let save_efm = &efm
2622 lexpr '0'
2623 lopen
2624 fun X(c)
2625 let save_efm=&efm
2626 set efm=%D%f
2627 if a:c == 'c'
2628 caddexpr '::'
2629 else
2630 laddexpr ':0:0'
2631 endif
2632 let &efm=save_efm
2633 endfun
2634 call X('c')
2635 call X('l')
2636 call setqflist([], 'r')
2637 caddbuffer
2638 let &efm = save_efm
2639endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002640
2641" Tests for jumping to entries from the location list window and quickfix
2642" window
2643func Test_cwindow_jump()
2644 set efm=%f%%%l%%%m
2645 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2646 lopen | only
2647 lfirst
2648 call assert_true(winnr('$') == 2)
2649 call assert_true(winnr() == 1)
2650 " Location list for the new window should be set
2651 call assert_true(getloclist(0)[2].text == 'Line 30')
2652
2653 " Open a scratch buffer
2654 " Open a new window and create a location list
2655 " Open the location list window and close the other window
2656 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002657 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002658 " should not be used.
2659 enew | only
2660 set buftype=nofile
2661 below new
2662 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2663 lopen
2664 2wincmd c
2665 lnext
2666 call assert_true(winnr('$') == 3)
2667 call assert_true(winnr() == 2)
2668
2669 " Open two windows with two different location lists
2670 " Open the location list window and close the previous window
2671 " Jump to an entry in the location list window
2672 " Should open the file in the first window and not set the location list.
2673 enew | only
2674 lgetexpr ["F1%5%Line 5"]
2675 below new
2676 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2677 lopen
2678 2wincmd c
2679 lnext
2680 call assert_true(winnr() == 1)
2681 call assert_true(getloclist(0)[0].text == 'Line 5')
2682
2683 enew | only
2684 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2685 copen
2686 cnext
2687 call assert_true(winnr('$') == 2)
2688 call assert_true(winnr() == 1)
2689
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002690 " open the quickfix buffer in two windows and jump to an entry. Should open
2691 " the file in the first quickfix window.
2692 enew | only
2693 copen
2694 let bnum = bufnr('')
2695 exe 'sbuffer ' . bnum
2696 wincmd b
2697 cfirst
2698 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002699 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002700 enew | only
2701 exe 'sb' bnum
2702 exe 'botright sb' bnum
2703 wincmd t
2704 clast
2705 call assert_equal(2, winnr())
2706 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2707 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2708
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002709 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002710 " window by wrapping around the window list.
2711 enew | only
2712 call setloclist(0, [], 'f')
2713 new | new
2714 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2715 lopen
2716 1close
2717 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2718 lnext
2719 call assert_equal(3, winnr())
2720 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2721
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002722 enew | only
2723 set efm&vim
2724endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002725
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002726func Test_cwindow_highlight()
2727 CheckScreendump
2728
2729 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002730 call setline(1, ['some', 'text', 'with', 'matches'])
2731 write XCwindow
2732 vimgrep e XCwindow
2733 redraw
2734 cwindow 4
2735 END
2736 call writefile(lines, 'XtestCwindow')
2737 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2738 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2739
2740 call term_sendkeys(buf, ":cnext\<CR>")
2741 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2742
2743 " clean up
2744 call StopVimInTerminal(buf)
2745 call delete('XtestCwindow')
2746 call delete('XCwindow')
2747endfunc
2748
Bram Moolenaaree85df32017-03-19 14:19:50 +01002749func XvimgrepTests(cchar)
2750 call s:setup_commands(a:cchar)
2751
2752 call writefile(['Editor:VIM vim',
2753 \ 'Editor:Emacs EmAcS',
2754 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2755 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2756
2757 " Error cases
2758 call assert_fails('Xvimgrep /abc *', 'E682:')
2759
2760 let @/=''
2761 call assert_fails('Xvimgrep // *', 'E35:')
2762
2763 call assert_fails('Xvimgrep abc', 'E683:')
2764 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2765 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2766
2767 Xexpr ""
2768 Xvimgrepadd Notepad Xtestfile1
2769 Xvimgrepadd MacOS Xtestfile2
2770 let l = g:Xgetlist()
2771 call assert_equal(2, len(l))
2772 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2773
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002774 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002775 let l = g:Xgetlist()
2776 call assert_equal(2, len(l))
2777 call assert_equal(8, l[0].col)
2778 call assert_equal(12, l[1].col)
2779
2780 1Xvimgrep ?Editor? Xtestfile*
2781 let l = g:Xgetlist()
2782 call assert_equal(1, len(l))
2783 call assert_equal('Editor:VIM vim', l[0].text)
2784
2785 edit +3 Xtestfile2
2786 Xvimgrep +\cemacs+j Xtestfile1
2787 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002788 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002789 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2790
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002791 " Test for unloading a buffer after vimgrep searched the buffer
2792 %bwipe
2793 Xvimgrep /Editor/j Xtestfile*
2794 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2795 call assert_equal([], getbufinfo('Xtestfile2'))
2796
Bram Moolenaaree85df32017-03-19 14:19:50 +01002797 call delete('Xtestfile1')
2798 call delete('Xtestfile2')
2799endfunc
2800
2801" Tests for the :vimgrep command
2802func Test_vimgrep()
2803 call XvimgrepTests('c')
2804 call XvimgrepTests('l')
2805endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002806
Bram Moolenaar1c299432018-10-28 14:36:09 +01002807" Test for incsearch highlighting of the :vimgrep pattern
2808" This test used to cause "E315: ml_get: invalid lnum" errors.
2809func Test_vimgrep_incsearch()
2810 enew
2811 set incsearch
2812 call test_override("char_avail", 1)
2813
2814 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2815 let l = getqflist()
2816 call assert_equal(2, len(l))
2817
2818 call test_override("ALL", 0)
2819 set noincsearch
2820endfunc
2821
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002822" Test vimgrep with the last search pattern not set
2823func Test_vimgrep_with_no_last_search_pat()
2824 let lines =<< trim [SCRIPT]
2825 call assert_fails('vimgrep // *', 'E35:')
2826 call writefile(v:errors, 'Xresult')
2827 qall!
2828 [SCRIPT]
2829 call writefile(lines, 'Xscript')
2830 if RunVim([], [], '--clean -S Xscript')
2831 call assert_equal([], readfile('Xresult'))
2832 endif
2833 call delete('Xscript')
2834 call delete('Xresult')
2835endfunc
2836
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002837func XfreeTests(cchar)
2838 call s:setup_commands(a:cchar)
2839
2840 enew | only
2841
2842 " Deleting the quickfix stack should work even When the current list is
2843 " somewhere in the middle of the stack
2844 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2845 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2846 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2847 Xolder
2848 call g:Xsetlist([], 'f')
2849 call assert_equal(0, len(g:Xgetlist()))
2850
2851 " After deleting the stack, adding a new list should create a stack with a
2852 " single list.
2853 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2854 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2855
2856 " Deleting the stack from a quickfix window should update/clear the
2857 " quickfix/location list window.
2858 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2859 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2860 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2861 Xolder
2862 Xwindow
2863 call g:Xsetlist([], 'f')
2864 call assert_equal(2, winnr('$'))
2865 call assert_equal(1, line('$'))
2866 Xclose
2867
2868 " Deleting the stack from a non-quickfix window should update/clear the
2869 " quickfix/location list window.
2870 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2871 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2872 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2873 Xolder
2874 Xwindow
2875 wincmd p
2876 call g:Xsetlist([], 'f')
2877 call assert_equal(0, len(g:Xgetlist()))
2878 wincmd p
2879 call assert_equal(2, winnr('$'))
2880 call assert_equal(1, line('$'))
2881
2882 " After deleting the location list stack, if the location list window is
2883 " opened, then a new location list should be created. So opening the
2884 " location list window again should not create a new window.
2885 if a:cchar == 'l'
2886 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2887 wincmd p
2888 lopen
2889 call assert_equal(2, winnr('$'))
2890 endif
2891 Xclose
2892endfunc
2893
Bram Moolenaar74240d32017-12-10 15:26:15 +01002894" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002895func Test_qf_free()
2896 call XfreeTests('c')
2897 call XfreeTests('l')
2898endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002899
2900" Test for buffer overflow when parsing lines and adding new entries to
2901" the quickfix list.
2902func Test_bufoverflow()
2903 set efm=%f:%l:%m
2904 cgetexpr ['File1:100:' . repeat('x', 1025)]
2905
2906 set efm=%+GCompiler:\ %.%#,%f:%l:%m
2907 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2908
2909 set efm=%DEntering\ directory\ %f,%f:%l:%m
2910 cgetexpr ['Entering directory ' . repeat('a', 1006),
2911 \ 'File1:10:Hello World']
2912 set efm&vim
2913endfunc
2914
Bram Moolenaar875feea2017-06-11 16:07:51 +02002915" Tests for getting the quickfix stack size
2916func XsizeTests(cchar)
2917 call s:setup_commands(a:cchar)
2918
2919 call g:Xsetlist([], 'f')
2920 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01002921 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2922 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02002923
2924 Xexpr "File1:10:Line1"
2925 Xexpr "File2:20:Line2"
2926 Xexpr "File3:30:Line3"
2927 Xolder | Xolder
2928 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2929 call g:Xsetlist([], 'f')
2930
2931 Xexpr "File1:10:Line1"
2932 Xexpr "File2:20:Line2"
2933 Xexpr "File3:30:Line3"
2934 Xolder | Xolder
2935 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2936 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2937endfunc
2938
2939func Test_Qf_Size()
2940 call XsizeTests('c')
2941 call XsizeTests('l')
2942endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02002943
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002944func Test_cclose_from_copen()
2945 augroup QF_Test
2946 au!
2947 au FileType qf :call assert_fails(':cclose', 'E788')
2948 augroup END
2949 copen
2950 augroup QF_Test
2951 au!
2952 augroup END
2953 augroup! QF_Test
2954endfunc
2955
Bram Moolenaar18141832017-06-25 21:17:25 +02002956func Test_cclose_in_autocmd()
2957 " Problem is only triggered if "starting" is zero, so that the OptionsSet
2958 " event will be triggered.
2959 call test_override('starting', 1)
2960 augroup QF_Test
2961 au!
2962 au FileType qf :call assert_fails(':cclose', 'E788')
2963 augroup END
2964 copen
2965 augroup QF_Test
2966 au!
2967 augroup END
2968 augroup! QF_Test
2969 call test_override('starting', 0)
2970endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002971
Bram Moolenaar379fb762018-08-30 15:58:28 +02002972" Check that ":file" without an argument is possible even when "curbuf_lock"
2973" is set.
2974func Test_file_from_copen()
2975 " Works without argument.
2976 augroup QF_Test
2977 au!
2978 au FileType qf file
2979 augroup END
2980 copen
2981
2982 augroup QF_Test
2983 au!
2984 augroup END
2985 cclose
2986
2987 " Fails with argument.
2988 augroup QF_Test
2989 au!
2990 au FileType qf call assert_fails(':file foo', 'E788')
2991 augroup END
2992 copen
2993 augroup QF_Test
2994 au!
2995 augroup END
2996 cclose
2997
2998 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02002999endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003000
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003001func Test_resize_from_copen()
3002 augroup QF_Test
3003 au!
3004 au FileType qf resize 5
3005 augroup END
3006 try
3007 " This should succeed without any exception. No other buffers are
3008 " involved in the autocmd.
3009 copen
3010 finally
3011 augroup QF_Test
3012 au!
3013 augroup END
3014 augroup! QF_Test
3015 endtry
3016endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003017
3018" Tests for the quickfix buffer b:changedtick variable
3019func Xchangedtick_tests(cchar)
3020 call s:setup_commands(a:cchar)
3021
3022 new | only
3023
3024 Xexpr "" | Xexpr "" | Xexpr ""
3025
3026 Xopen
3027 Xolder
3028 Xolder
3029 Xaddexpr "F1:10:Line10"
3030 Xaddexpr "F2:20:Line20"
3031 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3032 call g:Xsetlist([], 'f')
3033 call assert_equal(8, getbufvar('%', 'changedtick'))
3034 Xclose
3035endfunc
3036
3037func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003038 call Xchangedtick_tests('c')
3039 call Xchangedtick_tests('l')
3040endfunc
3041
3042" Tests for parsing an expression using setqflist()
3043func Xsetexpr_tests(cchar)
3044 call s:setup_commands(a:cchar)
3045
3046 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003047 call g:Xsetlist([], ' ', {'lines' : t})
3048 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003049
3050 let l = g:Xgetlist()
3051 call assert_equal(3, len(l))
3052 call assert_equal(20, l[1].lnum)
3053 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003054 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003055 let l = g:Xgetlist()
3056 call assert_equal(1, len(l))
3057 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003058 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3059 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003060
3061 call g:Xsetlist([], 'f')
3062 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003063 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3064 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3065 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3066 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003067 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3068 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003069
3070 " Adding entries using a custom efm
3071 set efm&
3072 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3073 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3074 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3075 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3076 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3077 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3078 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3079 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003080endfunc
3081
3082func Test_setexpr()
3083 call Xsetexpr_tests('c')
3084 call Xsetexpr_tests('l')
3085endfunc
3086
3087" Tests for per quickfix/location list directory stack
3088func Xmultidirstack_tests(cchar)
3089 call s:setup_commands(a:cchar)
3090
3091 call g:Xsetlist([], 'f')
3092 Xexpr "" | Xexpr ""
3093
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003094 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3095 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3096 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3097 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003098
3099 let l1 = g:Xgetlist({'nr':1, 'items':1})
3100 let l2 = g:Xgetlist({'nr':2, 'items':1})
3101 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3102 call assert_equal(3, l1.items[1].lnum)
3103 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3104 call assert_equal(5, l2.items[1].lnum)
3105endfunc
3106
3107func Test_multidirstack()
3108 call mkdir('Xone/a', 'p')
3109 call mkdir('Xtwo/a', 'p')
3110 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3111 call writefile(lines, 'Xone/a/one.txt')
3112 call writefile(lines, 'Xtwo/a/two.txt')
3113 let save_efm = &efm
3114 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3115
3116 call Xmultidirstack_tests('c')
3117 call Xmultidirstack_tests('l')
3118
3119 let &efm = save_efm
3120 call delete('Xone', 'rf')
3121 call delete('Xtwo', 'rf')
3122endfunc
3123
3124" Tests for per quickfix/location list file stack
3125func Xmultifilestack_tests(cchar)
3126 call s:setup_commands(a:cchar)
3127
3128 call g:Xsetlist([], 'f')
3129 Xexpr "" | Xexpr ""
3130
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003131 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3132 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3133 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3134 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003135
3136 let l1 = g:Xgetlist({'nr':1, 'items':1})
3137 let l2 = g:Xgetlist({'nr':2, 'items':1})
3138 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3139 call assert_equal(3, l1.items[1].lnum)
3140 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3141 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003142
3143 " Test for start of a new error line in the same line where a previous
3144 " error line ends with a file stack.
3145 let efm_val = 'Error\ l%l\ in\ %f,'
3146 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3147 let l = g:Xgetlist({'lines' : [
3148 \ '(one.txt',
3149 \ 'Error l4 in one.txt',
3150 \ ') (two.txt',
3151 \ 'Error l6 in two.txt',
3152 \ ')',
3153 \ 'Error l8 in one.txt'
3154 \ ], 'efm' : efm_val})
3155 call assert_equal(3, len(l.items))
3156 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3157 call assert_equal(4, l.items[0].lnum)
3158 call assert_equal('one.txt', l.items[0].text)
3159 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3160 call assert_equal(6, l.items[1].lnum)
3161 call assert_equal('two.txt', l.items[1].text)
3162 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3163 call assert_equal(8, l.items[2].lnum)
3164 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003165endfunc
3166
3167func Test_multifilestack()
3168 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3169 call writefile(lines, 'one.txt')
3170 call writefile(lines, 'two.txt')
3171 let save_efm = &efm
3172 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3173
3174 call Xmultifilestack_tests('c')
3175 call Xmultifilestack_tests('l')
3176
3177 let &efm = save_efm
3178 call delete('one.txt')
3179 call delete('two.txt')
3180endfunc
3181
3182" Tests for per buffer 'efm' setting
3183func Test_perbuf_efm()
3184 call writefile(["File1-10-Line10"], 'one.txt')
3185 call writefile(["File2#20#Line20"], 'two.txt')
3186 set efm=%f#%l#%m
3187 new | only
3188 new
3189 setlocal efm=%f-%l-%m
3190 cfile one.txt
3191 wincmd w
3192 caddfile two.txt
3193
3194 let l = getqflist()
3195 call assert_equal(10, l[0].lnum)
3196 call assert_equal('Line20', l[1].text)
3197
3198 set efm&
3199 new | only
3200 call delete('one.txt')
3201 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003202endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003203
3204" Open multiple help windows using ":lhelpgrep
3205" This test used to crash Vim
3206func Test_Multi_LL_Help()
3207 new | only
3208 lhelpgrep window
3209 lopen
3210 e#
3211 lhelpgrep buffer
3212 call assert_equal(3, winnr('$'))
3213 call assert_true(len(getloclist(1)) != 0)
3214 call assert_true(len(getloclist(2)) != 0)
3215 new | only
3216endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003217
3218" Tests for adding new quickfix lists using setqflist()
3219func XaddQf_tests(cchar)
3220 call s:setup_commands(a:cchar)
3221
3222 " Create a new list using ' ' for action
3223 call g:Xsetlist([], 'f')
3224 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3225 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3226 call assert_equal(1, l.nr)
3227 call assert_equal('Test1', l.title)
3228
3229 " Create a new list using ' ' for action and '$' for 'nr'
3230 call g:Xsetlist([], 'f')
3231 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3232 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3233 call assert_equal(1, l.nr)
3234 call assert_equal('Test2', l.title)
3235
3236 " Create a new list using 'a' for action
3237 call g:Xsetlist([], 'f')
3238 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3239 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3240 call assert_equal(1, l.nr)
3241 call assert_equal('Test3', l.title)
3242
3243 " Create a new list using 'a' for action and '$' for 'nr'
3244 call g:Xsetlist([], 'f')
3245 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3246 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3247 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3248 call assert_equal(1, l.nr)
3249 call assert_equal('Test4', l.title)
3250
3251 " Adding a quickfix list should remove all the lists following the current
3252 " list.
3253 Xexpr "" | Xexpr "" | Xexpr ""
3254 silent! 10Xolder
3255 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3256 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3257 call assert_equal(2, l.nr)
3258 call assert_equal('Test5', l.title)
3259
3260 " Add a quickfix list using '$' as the list number.
3261 let lastqf = g:Xgetlist({'nr':'$'}).nr
3262 silent! 99Xolder
3263 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3264 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3265 call assert_equal(lastqf + 1, l.nr)
3266 call assert_equal('Test6', l.title)
3267
3268 " Add a quickfix list using 'nr' set to one more than the quickfix
3269 " list size.
3270 let lastqf = g:Xgetlist({'nr':'$'}).nr
3271 silent! 99Xolder
3272 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3273 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3274 call assert_equal(lastqf + 1, l.nr)
3275 call assert_equal('Test7', l.title)
3276
3277 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3278 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3279 silent! 99Xolder
3280 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3281 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3282 call assert_equal(10, l.nr)
3283 call assert_equal('Test8', l.title)
3284
3285 " Add a quickfix list using 'nr' set to a value greater than 10
3286 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3287
3288 " Try adding a quickfix list with 'nr' set to a value greater than the
3289 " quickfix list size but less than 10.
3290 call g:Xsetlist([], 'f')
3291 Xexpr "" | Xexpr "" | Xexpr ""
3292 silent! 99Xolder
3293 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3294
3295 " Add a quickfix list using 'nr' set to a some string or list
3296 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3297endfunc
3298
3299func Test_add_qf()
3300 call XaddQf_tests('c')
3301 call XaddQf_tests('l')
3302endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003303
3304" Test for getting the quickfix list items from some text without modifying
3305" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003306func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003307 call s:setup_commands(a:cchar)
3308 call g:Xsetlist([], 'f')
3309
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003310 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003311 call assert_equal(2, len(l))
3312 call assert_equal(30, l[1].lnum)
3313
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003314 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3315 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3316 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3317 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003318
Bram Moolenaar36538222017-09-02 19:51:44 +02003319 " Parse text using a custom efm
3320 set efm&
3321 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3322 call assert_equal('Line30', l[0].text)
3323 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3324 call assert_equal('File3:30:Line30', l[0].text)
3325 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3326 call assert_equal({}, l)
3327 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3328 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3329
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003330 " Make sure that the quickfix stack is not modified
3331 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3332endfunc
3333
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003334func Test_get_list_from_lines()
3335 call XgetListFromLines('c')
3336 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003337endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003338
3339" Tests for the quickfix list id
3340func Xqfid_tests(cchar)
3341 call s:setup_commands(a:cchar)
3342
3343 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003344 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003345 Xexpr ''
3346 let start_id = g:Xgetlist({'id' : 0}).id
3347 Xexpr '' | Xexpr ''
3348 Xolder
3349 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3350 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3351 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003352 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003353 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003354 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3355 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003356
3357 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3358 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003359 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003360 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3361 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3362 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3363
3364 let qfid = g:Xgetlist({'id':0, 'nr':0})
3365 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003366 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003367endfunc
3368
3369func Test_qf_id()
3370 call Xqfid_tests('c')
3371 call Xqfid_tests('l')
3372endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003373
3374func Xqfjump_tests(cchar)
3375 call s:setup_commands(a:cchar)
3376
3377 call writefile(["Line1\tFoo", "Line2"], 'F1')
3378 call writefile(["Line1\tBar", "Line2"], 'F2')
3379 call writefile(["Line1\tBaz", "Line2"], 'F3')
3380
3381 call g:Xsetlist([], 'f')
3382
3383 " Tests for
3384 " Jumping to a line using a pattern
3385 " Jumping to a column greater than the last column in a line
3386 " Jumping to a line greater than the last line in the file
3387 let l = []
3388 for i in range(1, 7)
3389 call add(l, {})
3390 endfor
3391 let l[0].filename='F1'
3392 let l[0].pattern='Line1'
3393 let l[1].filename='F2'
3394 let l[1].pattern='Line1'
3395 let l[2].filename='F3'
3396 let l[2].pattern='Line1'
3397 let l[3].filename='F3'
3398 let l[3].lnum=1
3399 let l[3].col=9
3400 let l[3].vcol=1
3401 let l[4].filename='F3'
3402 let l[4].lnum=99
3403 let l[5].filename='F3'
3404 let l[5].lnum=1
3405 let l[5].col=99
3406 let l[5].vcol=1
3407 let l[6].filename='F3'
3408 let l[6].pattern='abcxyz'
3409
3410 call g:Xsetlist([], ' ', {'items' : l})
3411 Xopen | only
3412 2Xnext
3413 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003414 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003415 Xnext
3416 call assert_equal(7, col('.'))
3417 Xnext
3418 call assert_equal(2, line('.'))
3419 Xnext
3420 call assert_equal(9, col('.'))
3421 2
3422 Xnext
3423 call assert_equal(2, line('.'))
3424
3425 if a:cchar == 'l'
3426 " When jumping to a location list entry in the location list window and
3427 " no usable windows are available, then a new window should be opened.
3428 enew! | new | only
3429 call g:Xsetlist([], 'f')
3430 setlocal buftype=nofile
3431 new
3432 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']})
3433 Xopen
3434 let winid = win_getid()
3435 wincmd p
3436 close
3437 call win_gotoid(winid)
3438 Xnext
3439 call assert_equal(3, winnr('$'))
3440 call assert_equal(1, winnr())
3441 call assert_equal(2, line('.'))
3442
3443 " When jumping to an entry in the location list window and the window
3444 " associated with the location list is not present and a window containing
3445 " the file is already present, then that window should be used.
3446 close
3447 belowright new
3448 call g:Xsetlist([], 'f')
3449 edit F3
3450 call win_gotoid(winid)
3451 Xlast
3452 call assert_equal(3, winnr())
3453 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3454 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3455 endif
3456
3457 " Cleanup
3458 enew!
3459 new | only
3460
3461 call delete('F1')
3462 call delete('F2')
3463 call delete('F3')
3464endfunc
3465
3466func Test_qfjump()
3467 call Xqfjump_tests('c')
3468 call Xqfjump_tests('l')
3469endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003470
3471" Tests for the getqflist() and getloclist() functions when the list is not
3472" present or is empty
3473func Xgetlist_empty_tests(cchar)
3474 call s:setup_commands(a:cchar)
3475
3476 " Empty quickfix stack
3477 call g:Xsetlist([], 'f')
3478 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3479 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3480 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3481 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3482 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3483 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3484 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3485 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003486 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003487 if a:cchar == 'c'
3488 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003489 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003490 \ 'title' : '', 'winid' : 0, 'changedtick': 0},
3491 \ g:Xgetlist({'all' : 0}))
3492 else
3493 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3494 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003495 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
3496 \ 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003497 \ g:Xgetlist({'all' : 0}))
3498 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003499
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003500 " Quickfix window with empty stack
3501 silent! Xopen
3502 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003503 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003504 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3505 Xclose
3506
Bram Moolenaara6d48492017-12-12 22:45:31 +01003507 " Empty quickfix list
3508 Xexpr ""
3509 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3510 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3511 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3512 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3513 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3514 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3515 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3516 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003517 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003518
3519 let qfid = g:Xgetlist({'id' : 0}).id
3520 call g:Xsetlist([], 'f')
3521
3522 " Non-existing quickfix identifier
3523 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3524 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3525 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3526 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3527 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3528 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3529 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3530 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003531 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003532 if a:cchar == 'c'
3533 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3534 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003535 \ 'qfbufnr' : qfbufnr,
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003536 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3537 else
3538 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3539 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003540 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003541 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3542 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003543
3544 " Non-existing quickfix list number
3545 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3546 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3547 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3548 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3549 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3550 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3551 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3552 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003553 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003554 if a:cchar == 'c'
3555 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3556 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003557 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr},
3558 \ g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003559 else
3560 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3561 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003562 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003563 \ g:Xgetlist({'nr' : 5, 'all' : 0}))
3564 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003565endfunc
3566
3567func Test_getqflist()
3568 call Xgetlist_empty_tests('c')
3569 call Xgetlist_empty_tests('l')
3570endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003571
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003572func Test_getqflist_invalid_nr()
3573 " The following commands used to crash Vim
3574 cexpr ""
3575 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3576
3577 " Cleanup
3578 call setqflist([], 'r')
3579endfunc
3580
Bram Moolenaarb254af32017-12-18 19:48:58 +01003581" Tests for the quickfix/location list changedtick
3582func Xqftick_tests(cchar)
3583 call s:setup_commands(a:cchar)
3584
3585 call g:Xsetlist([], 'f')
3586
3587 Xexpr "F1:10:Line10"
3588 let qfid = g:Xgetlist({'id' : 0}).id
3589 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3590 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3591 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3592 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3593 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3594 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3595 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3596 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3597 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3598
3599 enew!
3600 call append(0, ["F5:50:L50", "F6:60:L60"])
3601 Xaddbuffer
3602 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3603 enew!
3604
3605 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3606 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3607 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3608 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3609 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3610 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3611 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3612 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3613 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3614 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3615 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3616
3617 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3618 Xfile Xone
3619 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3620 Xaddfile Xone
3621 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3622
3623 " Test case for updating a non-current quickfix list
3624 call g:Xsetlist([], 'f')
3625 Xexpr "F1:1:L1"
3626 Xexpr "F2:2:L2"
3627 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3628 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3629 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3630
3631 call delete("Xone")
3632endfunc
3633
3634func Test_qf_tick()
3635 call Xqftick_tests('c')
3636 call Xqftick_tests('l')
3637endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003638
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003639" Test helpgrep with lang specifier
3640func Xtest_helpgrep_with_lang_specifier(cchar)
3641 call s:setup_commands(a:cchar)
3642 Xhelpgrep Vim@en
3643 call assert_equal('help', &filetype)
3644 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3645 new | only
3646endfunc
3647
3648func Test_helpgrep_with_lang_specifier()
3649 call Xtest_helpgrep_with_lang_specifier('c')
3650 call Xtest_helpgrep_with_lang_specifier('l')
3651endfunc
3652
Bram Moolenaar12237442017-12-19 12:38:52 +01003653" The following test used to crash Vim.
3654" Open the location list window and close the regular window associated with
3655" the location list. When the garbage collection runs now, it incorrectly
3656" marks the location list context as not in use and frees the context.
3657func Test_ll_window_ctx()
3658 call setloclist(0, [], 'f')
3659 call setloclist(0, [], 'a', {'context' : []})
3660 lopen | only
3661 call test_garbagecollect_now()
3662 echo getloclist(0, {'context' : 1}).context
3663 enew | only
3664endfunc
3665
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003666" The following test used to crash vim
3667func Test_lfile_crash()
3668 sp Xtest
3669 au QuickFixCmdPre * bw
3670 call assert_fails('lfile', 'E40')
3671 au! QuickFixCmdPre
3672endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003673
3674" The following test used to crash vim
3675func Test_lbuffer_crash()
3676 sv Xtest
3677 augroup QF_Test
3678 au!
3679 au * * bw
3680 augroup END
3681 lbuffer
3682 augroup QF_Test
3683 au!
3684 augroup END
3685endfunc
3686
3687" The following test used to crash vim
3688func Test_lexpr_crash()
3689 augroup QF_Test
3690 au!
3691 au * * call setloclist(0, [], 'f')
3692 augroup END
3693 lexpr ""
3694 augroup QF_Test
3695 au!
3696 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003697
Bram Moolenaar3c097222017-12-21 20:54:49 +01003698 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003699 augroup QF_Test
3700 au!
3701 au BufNew * call setloclist(0, [], 'f')
3702 augroup END
3703 lexpr 'x:1:x'
3704 augroup QF_Test
3705 au!
3706 augroup END
3707
3708 enew | only
3709 lexpr ''
3710 lopen
3711 augroup QF_Test
3712 au!
3713 au FileType * call setloclist(0, [], 'f')
3714 augroup END
3715 lexpr ''
3716 augroup QF_Test
3717 au!
3718 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003719endfunc
3720
3721" The following test used to crash Vim
3722func Test_lvimgrep_crash()
3723 sv Xtest
3724 augroup QF_Test
3725 au!
3726 au * * call setloclist(0, [], 'f')
3727 augroup END
3728 lvimgrep quickfix test_quickfix.vim
3729 augroup QF_Test
3730 au!
3731 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003732
3733 new | only
3734 augroup QF_Test
3735 au!
3736 au BufEnter * call setloclist(0, [], 'r')
3737 augroup END
3738 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3739 augroup QF_Test
3740 au!
3741 augroup END
3742
Bram Moolenaar3c097222017-12-21 20:54:49 +01003743 enew | only
3744endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003745
Bram Moolenaar2573af32020-03-14 17:21:34 +01003746func Test_lvimgrep_crash2()
3747 au BufNewFile x sfind
3748 call assert_fails('lvimgrep x x', 'E480:')
3749 call assert_fails('lvimgrep x x x', 'E480:')
3750
3751 au! BufNewFile
3752endfunc
3753
Bram Moolenaarde046542017-12-26 13:53:11 +01003754" Test for the position of the quickfix and location list window
3755func Test_qfwin_pos()
3756 " Open two windows
3757 new | only
3758 new
3759 cexpr ['F1:10:L10']
3760 copen
3761 " Quickfix window should be the bottom most window
3762 call assert_equal(3, winnr())
3763 close
3764 " Open at the very top
3765 wincmd t
3766 topleft copen
3767 call assert_equal(1, winnr())
3768 close
3769 " open left of the current window
3770 wincmd t
3771 below new
3772 leftabove copen
3773 call assert_equal(2, winnr())
3774 close
3775 " open right of the current window
3776 rightbelow copen
3777 call assert_equal(3, winnr())
3778 close
3779endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003780
3781" Tests for quickfix/location lists changed by autocommands when
3782" :vimgrep/:lvimgrep commands are running.
3783func Test_vimgrep_autocmd()
3784 call setqflist([], 'f')
3785 call writefile(['stars'], 'Xtest1.txt')
3786 call writefile(['stars'], 'Xtest2.txt')
3787
3788 " Test 1:
3789 " When searching for a pattern using :vimgrep, if the quickfix list is
3790 " changed by an autocmd, the results should be added to the correct quickfix
3791 " list.
3792 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3793 silent vimgrep stars Xtest*.txt
3794 call assert_equal(1, getqflist({'nr' : 0}).nr)
3795 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3796 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3797 au! BufRead Xtest2.txt
3798
3799 " Test 2:
3800 " When searching for a pattern using :vimgrep, if the quickfix list is
3801 " freed, then a error should be given.
3802 silent! %bwipe!
3803 call setqflist([], 'f')
3804 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3805 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3806 au! BufRead Xtest2.txt
3807
3808 " Test 3:
3809 " When searching for a pattern using :lvimgrep, if the location list is
3810 " freed, then the command should error out.
3811 silent! %bwipe!
3812 let g:save_winid = win_getid()
3813 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3814 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3815 au! BufRead Xtest2.txt
3816
3817 call delete('Xtest1.txt')
3818 call delete('Xtest2.txt')
3819 call setqflist([], 'f')
3820endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003821
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003822" Test for an autocmd changing the current directory when running vimgrep
3823func Xvimgrep_autocmd_cd(cchar)
3824 call s:setup_commands(a:cchar)
3825
3826 %bwipe
3827 let save_cwd = getcwd()
3828
3829 augroup QF_Test
3830 au!
3831 autocmd BufRead * silent cd %:p:h
3832 augroup END
3833
3834 10Xvimgrep /vim/ Xdir/**
3835 let l = g:Xgetlist()
3836 call assert_equal('f1.txt', bufname(l[0].bufnr))
3837 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
3838
3839 augroup QF_Test
3840 au!
3841 augroup END
3842
3843 exe 'cd ' . save_cwd
3844endfunc
3845
3846func Test_vimgrep_autocmd_cd()
3847 call mkdir('Xdir/a', 'p')
3848 call mkdir('Xdir/b', 'p')
3849 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
3850 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
3851 call Xvimgrep_autocmd_cd('c')
3852 call Xvimgrep_autocmd_cd('l')
3853 %bwipe
3854 call delete('Xdir', 'rf')
3855endfunc
3856
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003857" The following test used to crash Vim
3858func Test_lhelpgrep_autocmd()
3859 lhelpgrep quickfix
3860 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3861 lhelpgrep buffer
3862 call assert_equal('help', &filetype)
3863 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3864 lhelpgrep tabpage
3865 call assert_equal('help', &filetype)
3866 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3867 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003868
3869 new | only
3870 augroup QF_Test
3871 au!
3872 au BufEnter * call setqflist([], 'f')
3873 augroup END
3874 call assert_fails('helpgrep quickfix', 'E925:')
3875 augroup QF_Test
3876 au! BufEnter
3877 augroup END
3878
3879 new | only
3880 augroup QF_Test
3881 au!
3882 au BufEnter * call setqflist([], 'r')
3883 augroup END
3884 call assert_fails('helpgrep quickfix', 'E925:')
3885 augroup QF_Test
3886 au! BufEnter
3887 augroup END
3888
3889 new | only
3890 augroup QF_Test
3891 au!
3892 au BufEnter * call setloclist(0, [], 'r')
3893 augroup END
3894 call assert_fails('lhelpgrep quickfix', 'E926:')
3895 augroup QF_Test
3896 au! BufEnter
3897 augroup END
3898
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003899 new | only
3900endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02003901
3902" Test for shortening/simplifying the file name when opening the
3903" quickfix window or when displaying the quickfix list
3904func Test_shorten_fname()
3905 if !has('unix')
3906 return
3907 endif
3908 %bwipe
3909 " Create a quickfix list with a absolute path filename
3910 let fname = getcwd() . '/test_quickfix.vim'
3911 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3912 call assert_equal(fname, bufname('test_quickfix.vim'))
3913 " Opening the quickfix window should simplify the file path
3914 cwindow
3915 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3916 cclose
3917 %bwipe
3918 " Create a quickfix list with a absolute path filename
3919 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3920 call assert_equal(fname, bufname('test_quickfix.vim'))
3921 " Displaying the quickfix list should simplify the file path
3922 silent! clist
3923 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3924endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02003925
3926" Quickfix title tests
3927" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3928" Otherwise due to indentation, the title is set with spaces at the beginning
3929" of the command.
3930func Test_qftitle()
3931 call writefile(["F1:1:Line1"], 'Xerr')
3932
3933 " :cexpr
3934 exe "cexpr readfile('Xerr')"
3935 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3936
3937 " :cgetexpr
3938 exe "cgetexpr readfile('Xerr')"
3939 call assert_equal(":cgetexpr readfile('Xerr')",
3940 \ getqflist({'title' : 1}).title)
3941
3942 " :caddexpr
3943 call setqflist([], 'f')
3944 exe "caddexpr readfile('Xerr')"
3945 call assert_equal(":caddexpr readfile('Xerr')",
3946 \ getqflist({'title' : 1}).title)
3947
3948 " :cbuffer
3949 new Xerr
3950 exe "cbuffer"
3951 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3952
3953 " :cgetbuffer
3954 edit Xerr
3955 exe "cgetbuffer"
3956 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3957
3958 " :caddbuffer
3959 call setqflist([], 'f')
3960 edit Xerr
3961 exe "caddbuffer"
3962 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3963
3964 " :cfile
3965 exe "cfile Xerr"
3966 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
3967
3968 " :cgetfile
3969 exe "cgetfile Xerr"
3970 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
3971
3972 " :caddfile
3973 call setqflist([], 'f')
3974 exe "caddfile Xerr"
3975 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
3976
3977 " :grep
3978 set grepprg=internal
3979 exe "grep F1 Xerr"
3980 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
3981
3982 " :grepadd
3983 call setqflist([], 'f')
3984 exe "grepadd F1 Xerr"
3985 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
3986 set grepprg&vim
3987
3988 " :vimgrep
3989 exe "vimgrep F1 Xerr"
3990 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
3991
3992 " :vimgrepadd
3993 call setqflist([], 'f')
3994 exe "vimgrepadd F1 Xerr"
3995 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
3996
3997 call setqflist(['F1:10:L10'], ' ')
3998 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3999
4000 call setqflist([], 'f')
4001 call setqflist(['F1:10:L10'], 'a')
4002 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4003
4004 call setqflist([], 'f')
4005 call setqflist(['F1:10:L10'], 'r')
4006 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4007
4008 close
4009 call delete('Xerr')
4010
4011 call setqflist([], ' ', {'title' : 'Errors'})
4012 copen
4013 call assert_equal('Errors', w:quickfix_title)
4014 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4015 call assert_equal('Errors', w:quickfix_title)
4016 cclose
4017endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004018
4019func Test_lbuffer_with_bwipe()
4020 new
4021 new
4022 augroup nasty
4023 au * * bwipe
4024 augroup END
4025 lbuffer
4026 augroup nasty
4027 au!
4028 augroup END
4029endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004030
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004031" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4032" running
4033func Xexpr_acmd_freelist(cchar)
4034 call s:setup_commands(a:cchar)
4035
Bram Moolenaar0366c012018-06-18 20:52:13 +02004036 " This was using freed memory.
4037 augroup nasty
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004038 au * * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004039 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004040 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004041 augroup nasty
4042 au!
4043 augroup END
4044endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004045
4046func Test_cexpr_acmd_freelist()
4047 call Xexpr_acmd_freelist('c')
4048 call Xexpr_acmd_freelist('l')
4049endfunc
4050
4051" Test for commands that create a new quickfix/location list and jump to the
4052" first error automatically.
4053func Xjumpto_first_error_test(cchar)
4054 call s:setup_commands(a:cchar)
4055
4056 call s:create_test_file('Xtestfile1')
4057 call s:create_test_file('Xtestfile2')
4058 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4059
4060 " Test for cexpr/lexpr
4061 enew
4062 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004063 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004064 call assert_equal(2, line('.'))
4065
4066 " Test for cfile/lfile
4067 enew
4068 call writefile(l, 'Xerr')
4069 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004070 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004071 call assert_equal(2, line('.'))
4072
4073 " Test for cbuffer/lbuffer
4074 edit Xerr
4075 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004076 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004077 call assert_equal(2, line('.'))
4078
4079 call delete('Xerr')
4080 call delete('Xtestfile1')
4081 call delete('Xtestfile2')
4082endfunc
4083
4084func Test_jumpto_first_error()
4085 call Xjumpto_first_error_test('c')
4086 call Xjumpto_first_error_test('l')
4087endfunc
4088
4089" Test for a quickfix autocmd changing the quickfix/location list before
4090" jumping to the first error in the new list.
4091func Xautocmd_changelist(cchar)
4092 call s:setup_commands(a:cchar)
4093
4094 " Test for cfile/lfile
4095 call s:create_test_file('Xtestfile1')
4096 call s:create_test_file('Xtestfile2')
4097 Xexpr 'Xtestfile1:2:Line2'
4098 autocmd QuickFixCmdPost * Xolder
4099 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4100 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004101 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004102 call assert_equal(4, line('.'))
4103 autocmd! QuickFixCmdPost
4104
4105 " Test for cbuffer/lbuffer
4106 call g:Xsetlist([], 'f')
4107 Xexpr 'Xtestfile1:2:Line2'
4108 autocmd QuickFixCmdPost * Xolder
4109 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4110 edit Xerr
4111 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004112 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004113 call assert_equal(4, line('.'))
4114 autocmd! QuickFixCmdPost
4115
4116 " Test for cexpr/lexpr
4117 call g:Xsetlist([], 'f')
4118 Xexpr 'Xtestfile1:2:Line2'
4119 autocmd QuickFixCmdPost * Xolder
4120 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004121 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004122 call assert_equal(4, line('.'))
4123 autocmd! QuickFixCmdPost
4124
Bram Moolenaar851332e2018-07-03 19:16:00 +02004125 " The grepprg may not be set on non-Unix systems
4126 if has('unix')
4127 " Test for grep/lgrep
4128 call g:Xsetlist([], 'f')
4129 Xexpr 'Xtestfile1:2:Line2'
4130 autocmd QuickFixCmdPost * Xolder
4131 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004132 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004133 call assert_equal(5, line('.'))
4134 autocmd! QuickFixCmdPost
4135 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004136
4137 " Test for vimgrep/lvimgrep
4138 call g:Xsetlist([], 'f')
4139 Xexpr 'Xtestfile1:2:Line2'
4140 autocmd QuickFixCmdPost * Xolder
4141 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004142 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004143 call assert_equal(5, line('.'))
4144 autocmd! QuickFixCmdPost
4145
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004146 " Test for autocommands clearing the quickfix list before jumping to the
4147 " first error. This should not result in an error
4148 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4149 let v:errmsg = ''
4150 " Test for cfile/lfile
4151 Xfile Xerr
4152 call assert_true(v:errmsg !~# 'E42:')
4153 " Test for cbuffer/lbuffer
4154 edit Xerr
4155 Xbuffer
4156 call assert_true(v:errmsg !~# 'E42:')
4157 " Test for cexpr/lexpr
4158 Xexpr 'Xtestfile2:4:Line4'
4159 call assert_true(v:errmsg !~# 'E42:')
4160 " Test for grep/lgrep
4161 " The grepprg may not be set on non-Unix systems
4162 if has('unix')
4163 silent Xgrep Line5 Xtestfile2
4164 call assert_true(v:errmsg !~# 'E42:')
4165 endif
4166 " Test for vimgrep/lvimgrep
4167 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4168 autocmd! QuickFixCmdPost
4169
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004170 call delete('Xerr')
4171 call delete('Xtestfile1')
4172 call delete('Xtestfile2')
4173endfunc
4174
4175func Test_autocmd_changelist()
4176 call Xautocmd_changelist('c')
4177 call Xautocmd_changelist('l')
4178endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004179
4180" Tests for the ':filter /pat/ clist' command
4181func Test_filter_clist()
4182 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4183 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4184 \ split(execute('filter /Line 15/ clist'), "\n"))
4185 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4186 \ split(execute('filter /Xfile1/ clist'), "\n"))
4187 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4188
4189 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4190 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4191 call assert_equal([' 2 pqr:pat2: '],
4192 \ split(execute('filter /pqr/ clist'), "\n"))
4193 call assert_equal([' 1 abc:pat1: '],
4194 \ split(execute('filter /pat1/ clist'), "\n"))
4195endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004196
4197" Tests for the "CTRL-W <CR>" command.
4198func Xview_result_split_tests(cchar)
4199 call s:setup_commands(a:cchar)
4200
4201 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4202 call g:Xsetlist([])
4203 Xopen
4204 let l:win_count = winnr('$')
4205 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
4206 call assert_equal(l:win_count, winnr('$'))
4207 Xclose
4208endfunc
4209
4210func Test_view_result_split()
4211 call Xview_result_split_tests('c')
4212 call Xview_result_split_tests('l')
4213endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004214
4215" Test that :cc sets curswant
4216func Test_curswant()
4217 helpgrep quickfix
4218 normal! llll
4219 1cc
4220 call assert_equal(getcurpos()[4], virtcol('.'))
4221 cclose | helpclose
4222endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004223
4224" Test for opening a file from the quickfix window using CTRL-W <Enter>
4225" doesn't leave an empty buffer around.
4226func Test_splitview()
4227 call s:create_test_file('Xtestfile1')
4228 call s:create_test_file('Xtestfile2')
4229 new | only
4230 let last_bufnr = bufnr('Test_sv_1', 1)
4231 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4232 cgetexpr l
4233 copen
4234 let numbufs = len(getbufinfo())
4235 exe "normal \<C-W>\<CR>"
4236 copen
4237 exe "normal j\<C-W>\<CR>"
4238 " Make sure new empty buffers are not created
4239 call assert_equal(numbufs, len(getbufinfo()))
4240 " Creating a new buffer should use the next available buffer number
4241 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4242 bwipe Test_sv_1
4243 bwipe Test_sv_2
4244 new | only
4245
4246 " When split opening files from location list window, make sure that two
4247 " windows doesn't refer to the same location list
4248 lgetexpr l
4249 let locid = getloclist(0, {'id' : 0}).id
4250 lopen
4251 exe "normal \<C-W>\<CR>"
4252 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4253 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4254 new | only
4255
4256 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004257 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004258 lhelpgrep window
4259 let locid = getloclist(0, {'id' : 0}).id
4260 lwindow
4261 exe "normal j\<C-W>\<CR>"
4262 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4263 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4264 new | only
4265
Bram Moolenaar406cd902020-02-18 21:54:41 +01004266 " Using :split or :vsplit from a quickfix window should behave like a :new
4267 " or a :vnew command
4268 copen
4269 split
4270 call assert_equal(3, winnr('$'))
4271 let l = getwininfo()
4272 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4273 close
4274 copen
4275 vsplit
4276 let l = getwininfo()
4277 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4278 new | only
4279
Bram Moolenaarb2443732018-11-11 22:50:27 +01004280 call delete('Xtestfile1')
4281 call delete('Xtestfile2')
4282endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004283
4284" Test for parsing entries using visual screen column
4285func Test_viscol()
4286 enew
4287 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4288 edit Xfile1
4289
4290 " Use byte offset for column number
4291 set efm&
4292 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4293 call assert_equal([5, 8], [col('.'), virtcol('.')])
4294 cnext
4295 call assert_equal([9, 12], [col('.'), virtcol('.')])
4296 cnext
4297 call assert_equal([14, 20], [col('.'), virtcol('.')])
4298
4299 " Use screen column offset for column number
4300 set efm=%f:%l:%v:%m
4301 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4302 call assert_equal([5, 8], [col('.'), virtcol('.')])
4303 cnext
4304 call assert_equal([9, 12], [col('.'), virtcol('.')])
4305 cnext
4306 call assert_equal([14, 20], [col('.'), virtcol('.')])
4307 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4308 call assert_equal([5, 8], [col('.'), virtcol('.')])
4309 cnext
4310 call assert_equal([10, 16], [col('.'), virtcol('.')])
4311 cnext
4312 call assert_equal([14, 20], [col('.'), virtcol('.')])
4313
4314 enew
4315 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4316
4317 " Use byte offset for column number
4318 set efm&
4319 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4320 call assert_equal([8, 10], [col('.'), virtcol('.')])
4321 cnext
4322 call assert_equal([11, 17], [col('.'), virtcol('.')])
4323 cnext
4324 call assert_equal([16, 25], [col('.'), virtcol('.')])
4325
4326 " Use screen column offset for column number
4327 set efm=%f:%l:%v:%m
4328 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4329 call assert_equal([8, 10], [col('.'), virtcol('.')])
4330 cnext
4331 call assert_equal([11, 17], [col('.'), virtcol('.')])
4332 cnext
4333 call assert_equal([16, 25], [col('.'), virtcol('.')])
4334
4335 enew | only
4336 set efm&
4337 call delete('Xfile1')
4338endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004339
4340" Test for the quickfix window buffer
4341func Xqfbuf_test(cchar)
4342 call s:setup_commands(a:cchar)
4343
4344 " Quickfix buffer should be reused across closing and opening a quickfix
4345 " window
4346 Xexpr "F1:10:Line10"
4347 Xopen
4348 let qfbnum = bufnr('')
4349 Xclose
4350 " Even after the quickfix window is closed, the buffer should be loaded
4351 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004352 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004353 Xopen
4354 " Buffer should be reused when opening the window again
4355 call assert_equal(qfbnum, bufnr(''))
4356 Xclose
4357
4358 if a:cchar == 'l'
4359 %bwipe
4360 " For a location list, when both the file window and the location list
4361 " window for the list are closed, then the buffer should be freed.
4362 new | only
4363 lexpr "F1:10:Line10"
4364 let wid = win_getid()
4365 lopen
4366 let qfbnum = bufnr('')
4367 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4368 close
4369 " When the location list window is closed, the buffer name should not
4370 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004371 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004372 call assert_true(bufloaded(qfbnum))
4373
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004374 " After deleting a location list buffer using ":bdelete", opening the
4375 " location list window should mark the buffer as a location list buffer.
4376 exe "bdelete " . qfbnum
4377 lopen
4378 call assert_equal("quickfix", &buftype)
4379 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4380 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4381 call assert_false(&swapfile)
4382 lclose
4383
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004384 " When the location list is cleared for the window, the buffer should be
4385 " removed
4386 call setloclist(0, [], 'f')
4387 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004388 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004389
4390 " When the location list is freed with the location list window open, the
4391 " location list buffer should not be lost. It should be reused when the
4392 " location list is again populated.
4393 lexpr "F1:10:Line10"
4394 lopen
4395 let wid = win_getid()
4396 let qfbnum = bufnr('')
4397 wincmd p
4398 call setloclist(0, [], 'f')
4399 lexpr "F1:10:Line10"
4400 lopen
4401 call assert_equal(wid, win_getid())
4402 call assert_equal(qfbnum, bufnr(''))
4403 lclose
4404
4405 " When the window with the location list is closed, the buffer should be
4406 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004407 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004408 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004409 endif
4410endfunc
4411
4412func Test_qfbuf()
4413 call Xqfbuf_test('c')
4414 call Xqfbuf_test('l')
4415endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004416
4417" If there is an autocmd to use only one window, then opening the location
4418" list window used to crash Vim.
4419func Test_winonly_autocmd()
4420 call s:create_test_file('Xtest1')
4421 " Autocmd to show only one Vim window at a time
4422 autocmd WinEnter * only
4423 new
4424 " Load the location list
4425 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4426 let loclistid = getloclist(0, {'id' : 0}).id
4427 " Open the location list window. Only this window will be shown and the file
4428 " window is closed.
4429 lopen
4430 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4431 " Jump to an entry in the location list and make sure that the cursor is
4432 " positioned correctly.
4433 ll 3
4434 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004435 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004436 call assert_equal(15, line('.'))
4437 " Cleanup
4438 autocmd! WinEnter
4439 new | only
4440 call delete('Xtest1')
4441endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004442
4443" Test to make sure that an empty quickfix buffer is not reused for loading
4444" a normal buffer.
4445func Test_empty_qfbuf()
4446 enew | only
4447 call writefile(["Test"], 'Xfile1')
4448 call setqflist([], 'f')
4449 copen | only
4450 let qfbuf = bufnr('')
4451 edit Xfile1
4452 call assert_notequal(qfbuf, bufnr(''))
4453 enew
4454 call delete('Xfile1')
4455endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004456
4457" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004458" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004459func Xtest_below(cchar)
4460 call s:setup_commands(a:cchar)
4461
4462 " No quickfix/location list
4463 call assert_fails('Xbelow', 'E42:')
4464 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004465 call assert_fails('Xbefore', 'E42:')
4466 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004467
4468 " Empty quickfix/location list
4469 call g:Xsetlist([])
4470 call assert_fails('Xbelow', 'E42:')
4471 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004472 call assert_fails('Xbefore', 'E42:')
4473 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004474
4475 call s:create_test_file('X1')
4476 call s:create_test_file('X2')
4477 call s:create_test_file('X3')
4478 call s:create_test_file('X4')
4479
4480 " Invalid entries
4481 edit X1
4482 call g:Xsetlist(["E1", "E2"])
4483 call assert_fails('Xbelow', 'E42:')
4484 call assert_fails('Xabove', 'E42:')
4485 call assert_fails('3Xbelow', 'E42:')
4486 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004487 call assert_fails('Xbefore', 'E42:')
4488 call assert_fails('Xafter', 'E42:')
4489 call assert_fails('3Xbefore', 'E42:')
4490 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004491
4492 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004493 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 +02004494 edit +7 X2
4495 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004496 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004497 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004498 normal 7G
4499 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004500 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004501 call assert_fails('Xbefore', 'E553:')
4502
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004503 normal 2j
4504 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004505 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004506 normal 7G
4507 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004508 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004509
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004510 " Last error in this file
4511 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004512 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004513 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004514 normal gg
4515 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004516 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004517 call assert_fails('Xafter', 'E553:')
4518
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004519 " First error in this file
4520 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004521 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004522 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004523 normal G
4524 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004525 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004526 call assert_fails('Xbefore', 'E553:')
4527
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004528 normal gg
4529 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004530 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004531 normal gg
4532 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004533 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004534
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004535 normal G
4536 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004537 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004538 normal G
4539 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004540 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004541
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004542 edit X4
4543 call assert_fails('Xabove', 'E42:')
4544 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004545 call assert_fails('Xbefore', 'E42:')
4546 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004547 if a:cchar == 'l'
4548 " If a buffer has location list entries from some other window but not
4549 " from the current window, then the commands should fail.
4550 edit X1 | split | call setloclist(0, [], 'f')
4551 call assert_fails('Xabove', 'E776:')
4552 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004553 call assert_fails('Xbefore', 'E776:')
4554 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004555 close
4556 endif
4557
4558 " Test for lines with multiple quickfix entries
4559 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4560 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4561 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4562 edit +1 X2
4563 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004564 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004565 normal 1G
4566 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004567 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004568
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004569 normal gg
4570 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004571 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004572 normal gg
4573 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004574 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004575
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004576 normal G
4577 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004578 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004579 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004580 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004581 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004582
4583 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004584 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004585 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004586 normal G
4587 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004588 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004589
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004590 normal 10G
4591 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004592 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004593 normal 10G$
4594 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004595 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004596
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004597 normal 10G
4598 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004599 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004600 normal 9G
4601 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004602 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004603
4604 " Invalid range
4605 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004606 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004607 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004608 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004609 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004610 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004611 endif
4612
4613 call delete('X1')
4614 call delete('X2')
4615 call delete('X3')
4616 call delete('X4')
4617endfunc
4618
4619func Test_cbelow()
4620 call Xtest_below('c')
4621 call Xtest_below('l')
4622endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004623
4624func Test_quickfix_count()
4625 let commands = [
4626 \ 'cNext',
4627 \ 'cNfile',
4628 \ 'cabove',
4629 \ 'cbelow',
4630 \ 'cfirst',
4631 \ 'clast',
4632 \ 'cnewer',
4633 \ 'cnext',
4634 \ 'cnfile',
4635 \ 'colder',
4636 \ 'cprevious',
4637 \ 'crewind',
4638 \
4639 \ 'lNext',
4640 \ 'lNfile',
4641 \ 'labove',
4642 \ 'lbelow',
4643 \ 'lfirst',
4644 \ 'llast',
4645 \ 'lnewer',
4646 \ 'lnext',
4647 \ 'lnfile',
4648 \ 'lolder',
4649 \ 'lprevious',
4650 \ 'lrewind',
4651 \ ]
4652 for cmd in commands
4653 call assert_fails('-1' .. cmd, 'E16:')
4654 call assert_fails('.' .. cmd, 'E16:')
4655 call assert_fails('%' .. cmd, 'E16:')
4656 call assert_fails('$' .. cmd, 'E16:')
4657 endfor
4658endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004659
4660" Test for aborting quickfix commands using QuickFixCmdPre
4661func Xtest_qfcmd_abort(cchar)
4662 call s:setup_commands(a:cchar)
4663
4664 call g:Xsetlist([], 'f')
4665
4666 " cexpr/lexpr
4667 let e = ''
4668 try
4669 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4670 catch /.*/
4671 let e = v:exception
4672 endtry
4673 call assert_equal('AbortCmd', e)
4674 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4675
4676 " cfile/lfile
4677 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4678 let e = ''
4679 try
4680 Xfile Xfile1
4681 catch /.*/
4682 let e = v:exception
4683 endtry
4684 call assert_equal('AbortCmd', e)
4685 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4686 call delete('Xfile1')
4687
4688 " cgetbuffer/lgetbuffer
4689 enew!
4690 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4691 let e = ''
4692 try
4693 Xgetbuffer
4694 catch /.*/
4695 let e = v:exception
4696 endtry
4697 call assert_equal('AbortCmd', e)
4698 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4699 enew!
4700
4701 " vimgrep/lvimgrep
4702 let e = ''
4703 try
4704 Xvimgrep /func/ test_quickfix.vim
4705 catch /.*/
4706 let e = v:exception
4707 endtry
4708 call assert_equal('AbortCmd', e)
4709 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4710
4711 " helpgrep/lhelpgrep
4712 let e = ''
4713 try
4714 Xhelpgrep quickfix
4715 catch /.*/
4716 let e = v:exception
4717 endtry
4718 call assert_equal('AbortCmd', e)
4719 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4720
4721 " grep/lgrep
4722 if has('unix')
4723 let e = ''
4724 try
4725 silent Xgrep func test_quickfix.vim
4726 catch /.*/
4727 let e = v:exception
4728 endtry
4729 call assert_equal('AbortCmd', e)
4730 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4731 endif
4732endfunc
4733
4734func Test_qfcmd_abort()
4735 augroup QF_Test
4736 au!
4737 autocmd QuickFixCmdPre * throw "AbortCmd"
4738 augroup END
4739
4740 call Xtest_qfcmd_abort('c')
4741 call Xtest_qfcmd_abort('l')
4742
4743 augroup QF_Test
4744 au!
4745 augroup END
4746endfunc
4747
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004748" Test for using a file in one of the parent directories.
4749func Test_search_in_dirstack()
4750 call mkdir('Xtestdir/a/b/c', 'p')
4751 let save_cwd = getcwd()
4752 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4753 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4754 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4755 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4756
4757 let lines = "Entering dir Xtestdir\n" .
4758 \ "Entering dir a\n" .
4759 \ "Entering dir b\n" .
4760 \ "Xfile2:2:X2_L2\n" .
4761 \ "Leaving dir a\n" .
4762 \ "Xfile1:2:X1_L2\n" .
4763 \ "Xfile3:1:X3_L1\n" .
4764 \ "Entering dir c\n" .
4765 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004766 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004767 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004768 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004769 call assert_equal(11, getqflist({'size' : 0}).size)
4770 call assert_equal(4, getqflist({'idx' : 0}).idx)
4771 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004772 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004773 cnext
4774 call assert_equal(6, getqflist({'idx' : 0}).idx)
4775 call assert_equal('X1_L2', getline('.'))
4776 cnext
4777 call assert_equal(7, getqflist({'idx' : 0}).idx)
4778 call assert_equal(1, line('$'))
4779 call assert_equal('', getline(1))
4780 cnext
4781 call assert_equal(9, getqflist({'idx' : 0}).idx)
4782 call assert_equal(1, line('$'))
4783 call assert_equal('', getline(1))
4784
4785 set efm&
4786 exe 'cd ' . save_cwd
4787 call delete('Xtestdir', 'rf')
4788endfunc
4789
Bram Moolenaar1860bde2020-01-06 21:47:21 +01004790" Test for :cquit
4791func Test_cquit()
4792 " Exit Vim with a non-zero value
4793 if RunVim([], ["cquit 7"], '')
4794 call assert_equal(7, v:shell_error)
4795 endif
4796
4797 if RunVim([], ["50cquit"], '')
4798 call assert_equal(50, v:shell_error)
4799 endif
4800
4801 " Exit Vim with default value
4802 if RunVim([], ["cquit"], '')
4803 call assert_equal(1, v:shell_error)
4804 endif
4805
4806 " Exit Vim with zero value
4807 if RunVim([], ["cquit 0"], '')
4808 call assert_equal(0, v:shell_error)
4809 endif
4810
4811 " Exit Vim with negative value
4812 call assert_fails('-3cquit', 'E16:')
4813endfunc
4814
Bram Moolenaar858ba062020-05-31 23:11:59 +02004815" Test for getting a specific item from a quickfix list
4816func Xtest_getqflist_by_idx(cchar)
4817 call s:setup_commands(a:cchar)
4818 " Empty list
4819 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
4820 Xexpr ['F1:10:L10', 'F1:20:L20']
4821 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
4822 call assert_equal(bufnr('F1'), l[0].bufnr)
4823 call assert_equal(20, l[0].lnum)
4824 call assert_equal('L20', l[0].text)
4825 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
4826 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
4827 %bwipe!
4828endfunc
4829
4830func Test_getqflist_by_idx()
4831 call Xtest_getqflist_by_idx('c')
4832 call Xtest_getqflist_by_idx('l')
4833endfunc
4834
4835" Test for the 'quickfixtextfunc' setting
4836func Tqfexpr(info)
4837 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004838 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004839 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004840 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004841 endif
4842
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004843 let l = []
4844 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4845 let e = qfl[idx]
4846 let s = ''
4847 if e.bufnr != 0
4848 let bname = bufname(e.bufnr)
4849 let s ..= fnamemodify(bname, ':.')
4850 endif
4851 let s ..= '-'
4852 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
4853 let s ..= e.text
4854 call add(l, s)
4855 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02004856
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004857 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004858endfunc
4859
4860func Xtest_qftextfunc(cchar)
4861 call s:setup_commands(a:cchar)
4862
4863 set efm=%f:%l:%c:%m
4864 set quickfixtextfunc=Tqfexpr
4865 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4866 Xwindow
4867 call assert_equal('F1-L10C2-green', getline(1))
4868 call assert_equal('F1-L20C4-blue', getline(2))
4869 Xclose
4870 set quickfixtextfunc&vim
4871 Xwindow
4872 call assert_equal('F1|10 col 2| green', getline(1))
4873 call assert_equal('F1|20 col 4| blue', getline(2))
4874 Xclose
4875 set efm&
4876 set quickfixtextfunc&
4877
4878 " Test for per list 'quickfixtextfunc' setting
4879 func PerQfText(info)
4880 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004881 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004882 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004883 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004884 endif
4885 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004886 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02004887 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004888 let l = []
4889 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4890 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
4891 endfor
4892 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004893 endfunc
4894 set quickfixtextfunc=Tqfexpr
4895 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
4896 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
4897 Xwindow
4898 call assert_equal('Line 10, Col 2', getline(1))
4899 call assert_equal('Line 20, Col 4', getline(2))
4900 Xclose
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02004901 " Add entries to the list when the quickfix buffer is hidden
4902 Xaddexpr ['F1:30:6:red']
4903 Xwindow
4904 call assert_equal('Line 30, Col 6', getline(3))
4905 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02004906 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
4907 set quickfixtextfunc&
4908 delfunc PerQfText
4909
4910 " Non-existing function
4911 set quickfixtextfunc=Tabc
4912 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4913 call assert_fails("Xwindow", 'E117:')
4914 Xclose
4915 set quickfixtextfunc&
4916
4917 " set option to a non-function
4918 set quickfixtextfunc=[10,\ 20]
4919 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4920 call assert_fails("Xwindow", 'E117:')
4921 Xclose
4922 set quickfixtextfunc&
4923
4924 " set option to a function with different set of arguments
4925 func Xqftext(a, b, c)
4926 return a:a .. a:b .. a:c
4927 endfunc
4928 set quickfixtextfunc=Xqftext
4929 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
4930 call assert_fails("Xwindow", 'E119:')
4931 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004932
4933 " set option to a function that returns a list with non-strings
4934 func Xqftext2(d)
4935 return ['one', [], 'two']
4936 endfunc
4937 set quickfixtextfunc=Xqftext2
4938 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
4939 \ 'E730:')
4940 call assert_fails('Xwindow', 'E730:')
4941 call assert_equal(['one', 'F1|20 col 4| blue', 'two'], getline(1, '$'))
4942 Xclose
4943
Bram Moolenaar858ba062020-05-31 23:11:59 +02004944 set quickfixtextfunc&
4945 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004946 delfunc Xqftext2
Bram Moolenaar858ba062020-05-31 23:11:59 +02004947endfunc
4948
4949func Test_qftextfunc()
4950 call Xtest_qftextfunc('c')
4951 call Xtest_qftextfunc('l')
4952endfunc
4953
Bram Moolenaarec98e932020-06-08 19:35:59 +02004954" Running :lhelpgrep command more than once in a help window, doesn't jump to
4955" the help topic
4956func Test_lhelpgrep_from_help_window()
4957 call mkdir('Xtestdir/doc', 'p')
4958 call writefile(['window'], 'Xtestdir/doc/a.txt')
4959 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
4960 let save_rtp = &rtp
4961 let &rtp = 'Xtestdir'
4962 lhelpgrep window
4963 lhelpgrep buffer
4964 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
4965 lhelpgrep window
4966 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
4967 let &rtp = save_rtp
4968 call delete('Xtestdir', 'rf')
4969 new | only!
4970endfunc
4971
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004972" vim: shiftwidth=2 sts=2 expandtab