blob: 6a86b1d77c7c7e06290bd0b2598cbdfcc9a431a1 [file] [log] [blame]
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001" Test for the quickfix feature.
Bram Moolenaarda59dd52016-01-05 21:59:58 +01002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature quickfix
Bram Moolenaarda59dd52016-01-05 21:59:58 +01005
Bram Moolenaare00fdf32019-09-15 19:09:42 +02006source screendump.vim
7
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01008set encoding=utf-8
9
Bram Moolenaar2b946c92016-11-12 18:14:44 +010010func s:setup_commands(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020011 if a:cchar == 'c'
12 command! -nargs=* -bang Xlist <mods>clist<bang> <args>
13 command! -nargs=* Xgetexpr <mods>cgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020014 command! -nargs=* Xaddexpr <mods>caddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020015 command! -nargs=* -count Xolder <mods><count>colder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020016 command! -nargs=* Xnewer <mods>cnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010017 command! -nargs=* Xopen <mods> copen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020018 command! -nargs=* Xwindow <mods>cwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020019 command! -nargs=* Xbottom <mods>cbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020020 command! -nargs=* Xclose <mods>cclose <args>
21 command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
22 command! -nargs=* Xgetfile <mods>cgetfile <args>
23 command! -nargs=* Xaddfile <mods>caddfile <args>
24 command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
25 command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
26 command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
27 command! -nargs=* Xrewind <mods>crewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020028 command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
29 command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020030 command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
31 command! -nargs=* -bang Xlast <mods>clast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020032 command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020033 command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020034 command! -nargs=* Xexpr <mods>cexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010035 command! -count -nargs=* Xvimgrep <mods> <count>vimgrep <args>
36 command! -nargs=* Xvimgrepadd <mods> vimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020037 command! -nargs=* Xgrep <mods> grep <args>
38 command! -nargs=* Xgrepadd <mods> grepadd <args>
39 command! -nargs=* Xhelpgrep helpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010040 command! -nargs=0 -count Xcc <count>cc
Bram Moolenaar3ff33112019-05-03 21:56:35 +020041 command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
42 command! -count=1 -nargs=0 Xabove <mods><count>cabove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020043 command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
44 command! -count=1 -nargs=0 Xafter <mods><count>cafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020045 let g:Xgetlist = function('getqflist')
46 let g:Xsetlist = function('setqflist')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020047 call setqflist([], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020048 else
49 command! -nargs=* -bang Xlist <mods>llist<bang> <args>
50 command! -nargs=* Xgetexpr <mods>lgetexpr <args>
Bram Moolenaar361c8f02016-07-02 15:41:47 +020051 command! -nargs=* Xaddexpr <mods>laddexpr <args>
Bram Moolenaar55b69262017-08-13 13:42:01 +020052 command! -nargs=* -count Xolder <mods><count>lolder <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020053 command! -nargs=* Xnewer <mods>lnewer <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010054 command! -nargs=* Xopen <mods> lopen <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020055 command! -nargs=* Xwindow <mods>lwindow <args>
Bram Moolenaar537ef082016-07-09 17:56:19 +020056 command! -nargs=* Xbottom <mods>lbottom <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020057 command! -nargs=* Xclose <mods>lclose <args>
58 command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
59 command! -nargs=* Xgetfile <mods>lgetfile <args>
60 command! -nargs=* Xaddfile <mods>laddfile <args>
61 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
62 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
63 command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
64 command! -nargs=* Xrewind <mods>lrewind <args>
Bram Moolenaar99895ea2017-04-20 22:44:47 +020065 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
66 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020067 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
68 command! -nargs=* -bang Xlast <mods>llast<bang> <args>
Bram Moolenaar25190db2019-05-04 15:05:28 +020069 command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +020070 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020071 command! -nargs=* Xexpr <mods>lexpr <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010072 command! -count -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
73 command! -nargs=* Xvimgrepadd <mods> lvimgrepadd <args>
Bram Moolenaar049cba92016-06-26 14:38:04 +020074 command! -nargs=* Xgrep <mods> lgrep <args>
75 command! -nargs=* Xgrepadd <mods> lgrepadd <args>
76 command! -nargs=* Xhelpgrep lhelpgrep <args>
Bram Moolenaar74240d32017-12-10 15:26:15 +010077 command! -nargs=0 -count Xcc <count>ll
Bram Moolenaar3ff33112019-05-03 21:56:35 +020078 command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
79 command! -count=1 -nargs=0 Xabove <mods><count>labove
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +020080 command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
81 command! -count=1 -nargs=0 Xafter <mods><count>lafter
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020082 let g:Xgetlist = function('getloclist', [0])
83 let g:Xsetlist = function('setloclist', [0])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020084 call setloclist(0, [], 'f')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020085 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +010086endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020087
Bram Moolenaarda59dd52016-01-05 21:59:58 +010088" Tests for the :clist and :llist commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +010089func XlistTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020090 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +010091
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +020092 if a:cchar == 'l'
93 call assert_fails('llist', 'E776:')
94 endif
Bram Moolenaarda59dd52016-01-05 21:59:58 +010095 " With an empty list, command should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +020096 Xgetexpr []
97 silent! Xlist
Bram Moolenaarda59dd52016-01-05 21:59:58 +010098 call assert_true(v:errmsg ==# 'E42: No Errors')
99
100 " Populate the list and then try
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200101 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100102 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100103 \ 'non-error| 3', 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100104
105 " List only valid entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100106 let l = split(execute('Xlist', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100107 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
108 \ ' 4 Xtestfile2:2 col 2: Line2',
109 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
110
111 " List all the entries
Bram Moolenaaree85df32017-03-19 14:19:50 +0100112 let l = split(execute('Xlist!', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100113 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
114 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100115 \ ' 5: non-error| 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100116
117 " List a range of errors
Bram Moolenaaree85df32017-03-19 14:19:50 +0100118 let l = split(execute('Xlist 3,6', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100119 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
120 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
121
Bram Moolenaaree85df32017-03-19 14:19:50 +0100122 let l = split(execute('Xlist! 3,4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100123 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
124
Bram Moolenaaree85df32017-03-19 14:19:50 +0100125 let l = split(execute('Xlist -6,-4', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100126 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
127
Bram Moolenaaree85df32017-03-19 14:19:50 +0100128 let l = split(execute('Xlist! -5,-3', ''), "\n")
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100129 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
130 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100131
132 " Test for '+'
Bram Moolenaaree85df32017-03-19 14:19:50 +0100133 let l = split(execute('Xlist! +2', ''), "\n")
Bram Moolenaar391b1dd2017-03-04 13:47:11 +0100134 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
135 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
Bram Moolenaaree85df32017-03-19 14:19:50 +0100136
137 " Different types of errors
138 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
139 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
140 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
141 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
142 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
143 let l = split(execute('Xlist', ""), "\n")
144 call assert_equal([' 1:10 col 5 warning 11: Warning',
145 \ ' 2:20 col 10 error 22: Error',
146 \ ' 3:30 col 15 info 33: Info',
147 \ ' 4:40 col 20 x 44: Other',
148 \ ' 5:50 col 25 55: one'], l)
149
Bram Moolenaard76ce852018-05-01 15:02:04 +0200150 " Test for module names, one needs to explicitly set `'valid':v:true` so
151 call g:Xsetlist([
152 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
153 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
154 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
155 let l = split(execute('Xlist', ""), "\n")
156 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning',
157 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning',
158 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l)
159
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100160 " For help entries in the quickfix list, only the filename without directory
161 " should be displayed
162 Xhelpgrep setqflist()
163 let l = split(execute('Xlist 1', ''), "\n")
164 call assert_match('^ 1 [^\\/]\{-}:', l[0])
165
Bram Moolenaaree85df32017-03-19 14:19:50 +0100166 " Error cases
167 call assert_fails('Xlist abc', 'E488:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100168endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100169
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100170func Test_clist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100171 call XlistTests('c')
172 call XlistTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100173endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100174
175" Tests for the :colder, :cnewer, :lolder and :lnewer commands
176" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100177" already set by the caller.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100178func XageTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200179 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100180
Bram Moolenaar87f59b02019-04-04 14:04:11 +0200181 if a:cchar == 'l'
182 " No location list for the current window
183 call assert_fails('lolder', 'E776:')
184 call assert_fails('lnewer', 'E776:')
185 endif
186
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200187 let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200188 call g:Xsetlist(list)
189
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100190 " Jumping to a non existent list should return error
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200191 silent! Xolder 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100192 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
193
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200194 silent! Xnewer 99
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100195 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
196
197 " Add three quickfix/location lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200198 Xgetexpr ['Xtestfile1:1:3:Line1']
199 Xgetexpr ['Xtestfile2:2:2:Line2']
200 Xgetexpr ['Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100201
202 " Go back two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200203 Xolder
204 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100205 call assert_equal('Line2', l[0].text)
206
207 " Go forward two lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200208 Xnewer
209 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100210 call assert_equal('Line3', l[0].text)
211
212 " Test for the optional count argument
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200213 Xolder 2
214 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100215 call assert_equal('Line1', l[0].text)
216
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200217 Xnewer 2
218 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100219 call assert_equal('Line3', l[0].text)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100220endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100221
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100222func Test_cage()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100223 call XageTests('c')
224 call XageTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100225endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100226
227" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
228" commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100229func XwindowTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200230 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100231
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200232 " Opening the location list window without any errors should fail
233 if a:cchar == 'l'
234 call assert_fails('lopen', 'E776:')
235 endif
236
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100237 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200238 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100239
240 " Quickfix/Location window should not open with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200241 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100242 call assert_true(winnr('$') == 1)
243
244 " Create a list with valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200245 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
246 \ 'Xtestfile3:3:1:Line3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100247
248 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200249 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100250 call assert_true(winnr('$') == 2 && winnr() == 2 &&
251 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
Bram Moolenaar537ef082016-07-09 17:56:19 +0200252 redraw!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100253
254 " Close the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200255 Xclose
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100256 call assert_true(winnr('$') == 1)
257
258 " Create a list with no valid entries
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200259 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100260
261 " Open the window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200262 Xopen 5
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100263 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
264 \ && winheight('.') == 5)
265
266 " Opening the window again, should move the cursor to that window
267 wincmd t
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200268 Xopen 7
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100269 call assert_true(winnr('$') == 2 && winnr() == 2 &&
270 \ winheight('.') == 7 &&
271 \ getline('.') ==# '|| non-error 1')
272
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100273 " :cnext in quickfix window should move to the next entry
274 Xnext
275 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100276
277 " Calling cwindow should close the quickfix window with no valid errors
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200278 Xwindow
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100279 call assert_true(winnr('$') == 1)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200280
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100281 " Specifying the width should adjust the width for a vertically split
282 " quickfix window.
283 vert Xopen
284 call assert_equal(10, winwidth(0))
285 vert Xopen 12
286 call assert_equal(12, winwidth(0))
287 Xclose
288
Bram Moolenaar5d3c9f82020-06-26 20:41:39 +0200289 " Horizontally or vertically splitting the quickfix window should create a
290 " normal window/buffer
291 Xopen
292 wincmd s
293 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
294 call assert_equal(0, getwininfo(win_getid())[0].loclist)
295 call assert_notequal('quickfix', &buftype)
296 close
297 Xopen
298 wincmd v
299 call assert_equal(0, getwininfo(win_getid())[0].quickfix)
300 call assert_equal(0, getwininfo(win_getid())[0].loclist)
301 call assert_notequal('quickfix', &buftype)
302 close
303 Xopen
304 Xclose
305
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200306 if a:cchar == 'c'
307 " Opening the quickfix window in multiple tab pages should reuse the
308 " quickfix buffer
309 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
310 \ 'Xtestfile3:3:1:Line3']
311 Xopen
312 let qfbufnum = bufnr('%')
313 tabnew
314 Xopen
315 call assert_equal(qfbufnum, bufnr('%'))
316 new | only | tabonly
317 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100318endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100319
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100320func Test_cwindow()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100321 call XwindowTests('c')
322 call XwindowTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100323endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100324
Bram Moolenaar36d50222019-05-02 20:17:40 +0200325func Test_copenHeight()
326 copen
327 wincmd H
328 let height = winheight(0)
329 copen 10
330 call assert_equal(height, winheight(0))
331 quit
332endfunc
333
Bram Moolenaar1142a312019-10-16 14:51:39 +0200334func Test_copenHeight_tabline()
335 set tabline=foo showtabline=2
336 copen
337 wincmd H
338 let height = winheight(0)
339 copen 10
340 call assert_equal(height, winheight(0))
341 quit
342 set tabline& showtabline&
343endfunc
344
345
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100346" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
347" commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100348func XfileTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200349 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100350
351 call writefile(['Xtestfile1:700:10:Line 700',
352 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
353
354 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200355 Xfile Xqftestfile1
356 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100357 call assert_true(len(l) == 2 &&
358 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
359 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
360
Bram Moolenaar049cba92016-06-26 14:38:04 +0200361 " Test with a non existent file
362 call assert_fails('Xfile non_existent_file', 'E40')
363
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100364 " Run cfile/lfile from a modified buffer
365 enew!
366 silent! put ='Quickfix'
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200367 silent! Xfile Xqftestfile1
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100368 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
369
370 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200371 Xaddfile Xqftestfile1
372 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100373 call assert_true(len(l) == 3 &&
374 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
375
376 call writefile(['Xtestfile1:222:77:Line 222',
377 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
378
379 enew!
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200380 Xgetfile Xqftestfile1
381 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100382 call assert_true(len(l) == 2 &&
383 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
384 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
385
Bram Moolenaar70077dd2019-11-24 12:12:42 +0100386 " Test for a file with a long line and without a newline at the end
387 let text = repeat('x', 1024)
388 let t = 'a.txt:18:' . text
389 call writefile([t], 'Xqftestfile1', 'b')
390 silent! Xfile Xqftestfile1
391 call assert_equal(text, g:Xgetlist()[0].text)
392
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100393 call delete('Xqftestfile1')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100394endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100395
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100396func Test_cfile()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100397 call XfileTests('c')
398 call XfileTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100399endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100400
401" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
402" :lgetbuffer commands.
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100403func XbufferTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200404 call s:setup_commands(a:cchar)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100405
406 enew!
407 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
408 \ 'Xtestfile8:800:15:Line 800'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200409 Xbuffer!
410 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100411 call assert_true(len(l) == 2 &&
412 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
413 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
414
415 enew!
416 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
417 \ 'Xtestfile10:950:66:Line 950'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200418 Xgetbuffer
419 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100420 call assert_true(len(l) == 2 &&
421 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
422 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
423
424 enew!
425 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
426 \ 'Xtestfile12:750:25:Line 750'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200427 Xaddbuffer
428 let l = g:Xgetlist()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100429 call assert_true(len(l) == 4 &&
430 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
431 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
432 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
Bram Moolenaarab47c612016-06-14 22:02:26 +0200433 enew!
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100434
Bram Moolenaaree85df32017-03-19 14:19:50 +0100435 " Check for invalid buffer
436 call assert_fails('Xbuffer 199', 'E474:')
437
438 " Check for unloaded buffer
439 edit Xtestfile1
440 let bnr = bufnr('%')
441 enew!
442 call assert_fails('Xbuffer ' . bnr, 'E681:')
443
444 " Check for invalid range
445 " Using Xbuffer will not run the range check in the cbuffer/lbuffer
446 " commands. So directly call the commands.
447 if (a:cchar == 'c')
448 call assert_fails('900,999cbuffer', 'E16:')
449 else
450 call assert_fails('900,999lbuffer', 'E16:')
451 endif
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100452endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100453
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100454func Test_cbuffer()
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100455 call XbufferTests('c')
456 call XbufferTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100457endfunc
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100458
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100459func XexprTests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200460 call s:setup_commands(a:cchar)
461
462 call assert_fails('Xexpr 10', 'E777:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100463endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200464
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100465func Test_cexpr()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200466 call XexprTests('c')
467 call XexprTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100468endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200469
470" Tests for :cnext, :cprev, :cfirst, :clast commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100471func Xtest_browse(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200472 call s:setup_commands(a:cchar)
473
Bram Moolenaar74240d32017-12-10 15:26:15 +0100474 call g:Xsetlist([], 'f')
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200475 " Jumping to first or next location list entry without any error should
476 " result in failure
Bram Moolenaar74240d32017-12-10 15:26:15 +0100477 if a:cchar == 'c'
478 let err = 'E42:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100479 let cmd = '$cc'
Bram Moolenaar74240d32017-12-10 15:26:15 +0100480 else
481 let err = 'E776:'
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100482 let cmd = '$ll'
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200483 endif
Bram Moolenaar74240d32017-12-10 15:26:15 +0100484 call assert_fails('Xnext', err)
485 call assert_fails('Xprev', err)
486 call assert_fails('Xnfile', err)
487 call assert_fails('Xpfile', err)
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +0100488 call assert_fails(cmd, err)
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +0200489
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100490 Xexpr ''
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100491 call assert_fails(cmd, 'E42:')
492
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200493 call s:create_test_file('Xqftestfile1')
494 call s:create_test_file('Xqftestfile2')
495
496 Xgetexpr ['Xqftestfile1:5:Line5',
497 \ 'Xqftestfile1:6:Line6',
498 \ 'Xqftestfile2:10:Line10',
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200499 \ 'Xqftestfile2:11:Line11',
500 \ 'RegularLine1',
501 \ 'RegularLine2']
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200502
503 Xfirst
Bram Moolenaar818fc9a2020-02-21 17:54:45 +0100504 call assert_fails('-5Xcc', 'E16:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200505 call assert_fails('Xprev', 'E553')
506 call assert_fails('Xpfile', 'E553')
507 Xnfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200508 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200509 call assert_equal(10, line('.'))
510 Xpfile
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200511 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200512 call assert_equal(6, line('.'))
Bram Moolenaar74240d32017-12-10 15:26:15 +0100513 5Xcc
514 call assert_equal(5, g:Xgetlist({'idx':0}).idx)
515 2Xcc
516 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100517 if a:cchar == 'c'
518 cc
519 else
520 ll
521 endif
522 call assert_equal(2, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100523 10Xcc
524 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200525 Xlast
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200526 Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200527 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200528 call assert_equal(11, line('.'))
529 call assert_fails('Xnext', 'E553')
530 call assert_fails('Xnfile', 'E553')
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100531 " To process the range using quickfix list entries, directly use the
532 " quickfix commands (don't use the user defined commands)
533 if a:cchar == 'c'
534 $cc
535 else
536 $ll
537 endif
538 call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200539 Xrewind
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200540 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200541 call assert_equal(5, line('.'))
542
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200543 10Xnext
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200544 call assert_equal('Xqftestfile2', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200545 call assert_equal(11, line('.'))
546 10Xprev
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200547 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200548 call assert_equal(5, line('.'))
549
Bram Moolenaar74240d32017-12-10 15:26:15 +0100550 " Jumping to an error from the error window using cc command
551 Xgetexpr ['Xqftestfile1:5:Line5',
552 \ 'Xqftestfile1:6:Line6',
553 \ 'Xqftestfile2:10:Line10',
554 \ 'Xqftestfile2:11:Line11']
555 Xopen
556 10Xcc
557 call assert_equal(11, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200558 call assert_equal('Xqftestfile2', @%)
Bram Moolenaarf0cee192020-02-16 13:33:56 +0100559 Xopen
560 call cursor(2, 1)
561 if a:cchar == 'c'
562 .cc
563 else
564 .ll
565 endif
566 call assert_equal(6, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200567 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100568
569 " Jumping to an error from the error window (when only the error window is
570 " present)
571 Xopen | only
572 Xlast 1
573 call assert_equal(5, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200574 call assert_equal('Xqftestfile1', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +0100575
Bram Moolenaaree85df32017-03-19 14:19:50 +0100576 Xexpr ""
577 call assert_fails('Xnext', 'E42:')
578
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200579 call delete('Xqftestfile1')
580 call delete('Xqftestfile2')
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200581
582 " Should be able to use next/prev with invalid entries
583 Xexpr ""
584 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
585 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +0100586 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'sh|moo']
Bram Moolenaarfc2b2702017-09-15 22:43:07 +0200587 call assert_equal(5, g:Xgetlist({'size' : 0}).size)
588 Xlast
589 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
590 Xfirst
591 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
592 2Xnext
593 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100594endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200595
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100596func Test_browse()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200597 call Xtest_browse('c')
598 call Xtest_browse('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100599endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200600
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100601func Test_nomem()
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200602 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100603 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100604
Bram Moolenaarce90e362019-09-08 18:58:44 +0200605 call GetAllocId('qf_dirname_now')->test_alloc_fail(0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100606 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100607
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200608 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100609 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100610
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200611 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100612 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100613
Bram Moolenaar8e8df252016-05-25 21:23:21 +0200614 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100615 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100616
617endfunc
618
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100619func s:test_xhelpgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +0200620 call s:setup_commands(a:cchar)
621 Xhelpgrep quickfix
622 Xopen
623 if a:cchar == 'c'
624 let title_text = ':helpgrep quickfix'
625 else
626 let title_text = ':lhelpgrep quickfix'
627 endif
628 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200629
630 " Jumping to a help topic should open the help window
631 only
632 Xnext
633 call assert_true(&buftype == 'help')
634 call assert_true(winnr('$') == 2)
635 " Jumping to the next match should reuse the help window
636 Xnext
637 call assert_true(&buftype == 'help')
638 call assert_true(winnr() == 1)
639 call assert_true(winnr('$') == 2)
640 " Jumping to the next match from the quickfix window should reuse the help
641 " window
642 Xopen
643 Xnext
644 call assert_true(&buftype == 'help')
645 call assert_true(winnr() == 1)
646 call assert_true(winnr('$') == 2)
647
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100648 " This wipes out the buffer, make sure that doesn't cause trouble.
Bram Moolenaar049cba92016-06-26 14:38:04 +0200649 Xclose
Bram Moolenaaree85df32017-03-19 14:19:50 +0100650
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100651 " When the current window is vertically split, jumping to a help match
652 " should open the help window at the top.
653 only | enew
654 let w1 = win_getid()
655 vert new
656 let w2 = win_getid()
657 Xnext
658 let w3 = win_getid()
659 call assert_true(&buftype == 'help')
660 call assert_true(winnr() == 1)
Bram Moolenaara106e6c2019-11-24 22:13:58 +0100661 " See jump_to_help_window() for details
662 let w2_width = winwidth(w2)
663 if w2_width != &columns && w2_width < 80
664 call assert_equal(['col', [['leaf', w3],
665 \ ['row', [['leaf', w2], ['leaf', w1]]]]], winlayout())
666 else
667 call assert_equal(['row', [['col', [['leaf', w3], ['leaf', w2]]],
668 \ ['leaf', w1]]] , winlayout())
669 endif
Bram Moolenaarf9ae1542019-11-18 22:02:16 +0100670
671 new | only
672 set buftype=help
673 set modified
674 call assert_fails('Xnext', 'E37:')
675 set nomodified
676 new | only
677
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +0200678 if a:cchar == 'l'
679 " When a help window is present, running :lhelpgrep should reuse the
680 " help window and not the current window
681 new | only
682 call g:Xsetlist([], 'f')
683 help index.txt
684 wincmd w
685 lhelpgrep quickfix
686 call assert_equal(1, winnr())
687 call assert_notequal([], getloclist(1))
688 call assert_equal([], getloclist(2))
689 endif
690
Bram Moolenaar99895ea2017-04-20 22:44:47 +0200691 new | only
692
Bram Moolenaaree85df32017-03-19 14:19:50 +0100693 " Search for non existing help string
694 call assert_fails('Xhelpgrep a1b2c3', 'E480:')
Bram Moolenaar108e7b42018-10-11 17:39:12 +0200695 " Invalid regular expression
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200696 call assert_fails('Xhelpgrep \@<!', 'E866:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100697endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +0200698
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100699func Test_helpgrep()
Bram Moolenaar049cba92016-06-26 14:38:04 +0200700 call s:test_xhelpgrep('c')
Bram Moolenaarcf25fdb2016-08-03 21:04:53 +0200701 helpclose
Bram Moolenaar049cba92016-06-26 14:38:04 +0200702 call s:test_xhelpgrep('l')
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100703endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100704
Bram Moolenaar6920c722016-01-22 22:44:10 +0100705func Test_errortitle()
706 augroup QfBufWinEnter
707 au!
708 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
709 augroup END
710 copen
711 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
712 call setqflist(a)
713 call assert_equal(':setqflist()', g:a)
714 augroup QfBufWinEnter
715 au!
716 augroup END
717 augroup! QfBufWinEnter
718endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100719
Bram Moolenaar5584df62016-03-18 21:00:51 +0100720func Test_vimgreptitle()
721 augroup QfBufWinEnter
722 au!
723 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
724 augroup END
725 try
726 vimgrep /pattern/j file
727 catch /E480/
728 endtry
729 copen
730 call assert_equal(': vimgrep /pattern/j file', g:a)
731 augroup QfBufWinEnter
732 au!
733 augroup END
734 augroup! QfBufWinEnter
735endfunc
736
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100737func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200738 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100739
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200740 Xgetexpr ['file:1:1:message']
741 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100742 if a:cchar == 'c'
743 call setqflist(l, 'r')
744 else
745 call setloclist(0, l, 'r')
746 endif
747
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200748 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100749 if a:cchar == 'c'
750 let title = ':setqflist()'
751 else
752 let title = ':setloclist()'
753 endif
754 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200755 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100756endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100757
758" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100759func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200760 call XqfTitleTests('c')
761 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100762endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100763
764" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100765func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100766 let save_efm = &efm
767 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
768 cgetexpr ['WWWW', 'EEEE', 'CCCC']
769 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
770 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
771 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
772 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
773 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
774 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
775 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
776 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
777 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100778endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100779
780" This will test for problems in quickfix:
781" A. incorrectly copying location lists which caused the location list to show
782" a different name than the file that was actually being displayed.
783" B. not reusing the window for which the location list window is opened but
784" instead creating new windows.
785" C. make sure that the location list window is not reused instead of the
786" window it belongs to.
787"
788" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100789func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100790 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
791 let word = substitute(base, '\v(.*)\..*', '\1', '')
792
793 setl modifiable
794 setl noreadonly
795 setl noswapfile
796 setl bufhidden=delete
797 %del _
798 " For problem 2:
799 " 'buftype' has to be set to reproduce the constant opening of new windows
800 setl buftype=nofile
801
802 call setline(1, word)
803
804 setl nomodified
805 setl nomodifiable
806 setl readonly
807 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100808endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100809
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100810func Test_locationlist()
Bram 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 Moolenaarbe7a50c2020-06-30 22:11:44 +02002363
2364 " Cannot specify both a non-empty list argument and a dict argument
2365 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002366endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002367
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002368func Test_qf_property()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002369 call Xproperty_tests('c')
2370 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002371endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002372
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002373" Test for setting the current index in the location/quickfix list
2374func Xtest_setqfidx(cchar)
2375 call s:setup_commands(a:cchar)
2376
2377 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2378 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2379 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2380
2381 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2382 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2383 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2384 Xolder 2
2385 Xopen
2386 call assert_equal(3, line('.'))
2387 Xnewer
2388 call assert_equal(2, line('.'))
2389 Xnewer
2390 call assert_equal(2, line('.'))
2391 " Update the current index with the quickfix window open
2392 wincmd w
2393 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2394 Xopen
2395 call assert_equal(3, line('.'))
2396 Xclose
2397
2398 " Set the current index to the last entry
2399 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2400 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2401 " A large value should set the index to the last index
2402 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2403 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2404 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2405 " Invalid index values
2406 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2407 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2408 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2409 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2410 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2411 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2412 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2413
2414 call g:Xsetlist([], 'f')
2415 new | only
2416endfunc
2417
2418func Test_setqfidx()
2419 call Xtest_setqfidx('c')
2420 call Xtest_setqfidx('l')
2421endfunc
2422
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002423" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002424func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002425 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002426endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002427
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002428func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002429 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2430 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2431
2432 let g:acmds = []
2433 cexpr "F1:10:Line 10"
2434 caddexpr "F1:20:Line 20"
2435 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002436 cexpr ""
2437 caddexpr ""
2438 cgetexpr ""
2439 silent! cexpr non_existing_func()
2440 silent! caddexpr non_existing_func()
2441 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002442 let l = ['precexpr',
2443 \ 'postcexpr',
2444 \ 'precaddexpr',
2445 \ 'postcaddexpr',
2446 \ 'precgetexpr',
2447 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002448 \ 'precexpr',
2449 \ 'postcexpr',
2450 \ 'precaddexpr',
2451 \ 'postcaddexpr',
2452 \ 'precgetexpr',
2453 \ 'postcgetexpr',
2454 \ 'precexpr',
2455 \ 'precaddexpr',
2456 \ 'precgetexpr']
2457 call assert_equal(l, g:acmds)
2458
2459 let g:acmds = []
2460 enew! | call append(0, "F2:10:Line 10")
2461 cbuffer!
2462 enew! | call append(0, "F2:20:Line 20")
2463 cgetbuffer
2464 enew! | call append(0, "F2:30:Line 30")
2465 caddbuffer
2466 new
2467 let bnum = bufnr('%')
2468 bunload
2469 exe 'silent! cbuffer! ' . bnum
2470 exe 'silent! cgetbuffer ' . bnum
2471 exe 'silent! caddbuffer ' . bnum
2472 enew!
2473 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002474 \ 'postcbuffer',
2475 \ 'precgetbuffer',
2476 \ 'postcgetbuffer',
2477 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002478 \ 'postcaddbuffer',
2479 \ 'precbuffer',
2480 \ 'precgetbuffer',
2481 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002482 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002483
2484 call writefile(['Xtest:1:Line1'], 'Xtest')
2485 call writefile([], 'Xempty')
2486 let g:acmds = []
2487 cfile Xtest
2488 caddfile Xtest
2489 cgetfile Xtest
2490 cfile Xempty
2491 caddfile Xempty
2492 cgetfile Xempty
2493 silent! cfile do_not_exist
2494 silent! caddfile do_not_exist
2495 silent! cgetfile do_not_exist
2496 let l = ['precfile',
2497 \ 'postcfile',
2498 \ 'precaddfile',
2499 \ 'postcaddfile',
2500 \ 'precgetfile',
2501 \ 'postcgetfile',
2502 \ 'precfile',
2503 \ 'postcfile',
2504 \ 'precaddfile',
2505 \ 'postcaddfile',
2506 \ 'precgetfile',
2507 \ 'postcgetfile',
2508 \ 'precfile',
2509 \ 'postcfile',
2510 \ 'precaddfile',
2511 \ 'postcaddfile',
2512 \ 'precgetfile',
2513 \ 'postcgetfile']
2514 call assert_equal(l, g:acmds)
2515
2516 let g:acmds = []
2517 helpgrep quickfix
2518 silent! helpgrep non_existing_help_topic
2519 vimgrep test Xtest
2520 vimgrepadd test Xtest
2521 silent! vimgrep non_existing_test Xtest
2522 silent! vimgrepadd non_existing_test Xtest
2523 set makeprg=
2524 silent! make
2525 set makeprg&
2526 let l = ['prehelpgrep',
2527 \ 'posthelpgrep',
2528 \ 'prehelpgrep',
2529 \ 'posthelpgrep',
2530 \ 'previmgrep',
2531 \ 'postvimgrep',
2532 \ 'previmgrepadd',
2533 \ 'postvimgrepadd',
2534 \ 'previmgrep',
2535 \ 'postvimgrep',
2536 \ 'previmgrepadd',
2537 \ 'postvimgrepadd',
2538 \ 'premake',
2539 \ 'postmake']
2540 call assert_equal(l, g:acmds)
2541
2542 if has('unix')
2543 " Run this test only on Unix-like systems. The grepprg may not be set on
2544 " non-Unix systems.
2545 " The following lines are used for the grep test. Don't remove.
2546 " Grep_Autocmd_Text: Match 1
2547 " GrepAdd_Autocmd_Text: Match 2
2548 let g:acmds = []
2549 silent grep Grep_Autocmd_Text test_quickfix.vim
2550 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2551 silent grep abc123def Xtest
2552 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002553 set grepprg=internal
2554 silent grep Grep_Autocmd_Text test_quickfix.vim
2555 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2556 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2557 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2558 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002559 let l = ['pregrep',
2560 \ 'postgrep',
2561 \ 'pregrepadd',
2562 \ 'postgrepadd',
2563 \ 'pregrep',
2564 \ 'postgrep',
2565 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002566 \ 'postgrepadd',
2567 \ 'pregrep',
2568 \ 'postgrep',
2569 \ 'pregrepadd',
2570 \ 'postgrepadd',
2571 \ 'prelgrep',
2572 \ 'postlgrep',
2573 \ 'prelgrepadd',
2574 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002575 call assert_equal(l, g:acmds)
2576 endif
2577
2578 call delete('Xtest')
2579 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002580 au! QuickFixCmdPre
2581 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002582endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002583
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002584func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002585 set efm=%m
2586 lgetexpr '?'
2587
2588 try
2589 call DoesNotExit()
2590 catch
2591 lgetexpr '1'
2592 finally
2593 lgetexpr '1'
2594 endtry
2595
2596 call assert_equal('1', getloclist(0)[0].text)
2597
2598 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002599endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002600
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002601func Test_caddbuffer_wrong()
2602 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002603 let save_efm = &efm
2604 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2605 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2606 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002607 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002608 bwipe!
2609endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002610
2611func Test_caddexpr_wrong()
2612 " This used to cause a memory access in freed memory.
2613 cbuffer
2614 cbuffer
2615 copen
2616 let save_efm = &efm
2617 set efm=%
2618 call assert_fails('caddexpr ""', 'E376:')
2619 let &efm = save_efm
2620endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002621
2622func Test_dirstack_cleanup()
2623 " This used to cause a memory access in freed memory.
2624 let save_efm = &efm
2625 lexpr '0'
2626 lopen
2627 fun X(c)
2628 let save_efm=&efm
2629 set efm=%D%f
2630 if a:c == 'c'
2631 caddexpr '::'
2632 else
2633 laddexpr ':0:0'
2634 endif
2635 let &efm=save_efm
2636 endfun
2637 call X('c')
2638 call X('l')
2639 call setqflist([], 'r')
2640 caddbuffer
2641 let &efm = save_efm
2642endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002643
2644" Tests for jumping to entries from the location list window and quickfix
2645" window
2646func Test_cwindow_jump()
2647 set efm=%f%%%l%%%m
2648 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2649 lopen | only
2650 lfirst
2651 call assert_true(winnr('$') == 2)
2652 call assert_true(winnr() == 1)
2653 " Location list for the new window should be set
2654 call assert_true(getloclist(0)[2].text == 'Line 30')
2655
2656 " Open a scratch buffer
2657 " Open a new window and create a location list
2658 " Open the location list window and close the other window
2659 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002660 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002661 " should not be used.
2662 enew | only
2663 set buftype=nofile
2664 below new
2665 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2666 lopen
2667 2wincmd c
2668 lnext
2669 call assert_true(winnr('$') == 3)
2670 call assert_true(winnr() == 2)
2671
2672 " Open two windows with two different location lists
2673 " Open the location list window and close the previous window
2674 " Jump to an entry in the location list window
2675 " Should open the file in the first window and not set the location list.
2676 enew | only
2677 lgetexpr ["F1%5%Line 5"]
2678 below new
2679 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2680 lopen
2681 2wincmd c
2682 lnext
2683 call assert_true(winnr() == 1)
2684 call assert_true(getloclist(0)[0].text == 'Line 5')
2685
2686 enew | only
2687 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2688 copen
2689 cnext
2690 call assert_true(winnr('$') == 2)
2691 call assert_true(winnr() == 1)
2692
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002693 " open the quickfix buffer in two windows and jump to an entry. Should open
2694 " the file in the first quickfix window.
2695 enew | only
2696 copen
2697 let bnum = bufnr('')
2698 exe 'sbuffer ' . bnum
2699 wincmd b
2700 cfirst
2701 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002702 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002703 enew | only
2704 exe 'sb' bnum
2705 exe 'botright sb' bnum
2706 wincmd t
2707 clast
2708 call assert_equal(2, winnr())
2709 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2710 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2711
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002712 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002713 " window by wrapping around the window list.
2714 enew | only
2715 call setloclist(0, [], 'f')
2716 new | new
2717 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2718 lopen
2719 1close
2720 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2721 lnext
2722 call assert_equal(3, winnr())
2723 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2724
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002725 enew | only
2726 set efm&vim
2727endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002728
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002729func Test_cwindow_highlight()
2730 CheckScreendump
2731
2732 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002733 call setline(1, ['some', 'text', 'with', 'matches'])
2734 write XCwindow
2735 vimgrep e XCwindow
2736 redraw
2737 cwindow 4
2738 END
2739 call writefile(lines, 'XtestCwindow')
2740 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2741 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2742
2743 call term_sendkeys(buf, ":cnext\<CR>")
2744 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2745
2746 " clean up
2747 call StopVimInTerminal(buf)
2748 call delete('XtestCwindow')
2749 call delete('XCwindow')
2750endfunc
2751
Bram Moolenaaree85df32017-03-19 14:19:50 +01002752func XvimgrepTests(cchar)
2753 call s:setup_commands(a:cchar)
2754
2755 call writefile(['Editor:VIM vim',
2756 \ 'Editor:Emacs EmAcS',
2757 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2758 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2759
2760 " Error cases
2761 call assert_fails('Xvimgrep /abc *', 'E682:')
2762
2763 let @/=''
2764 call assert_fails('Xvimgrep // *', 'E35:')
2765
2766 call assert_fails('Xvimgrep abc', 'E683:')
2767 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2768 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2769
2770 Xexpr ""
2771 Xvimgrepadd Notepad Xtestfile1
2772 Xvimgrepadd MacOS Xtestfile2
2773 let l = g:Xgetlist()
2774 call assert_equal(2, len(l))
2775 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2776
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002777 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002778 let l = g:Xgetlist()
2779 call assert_equal(2, len(l))
2780 call assert_equal(8, l[0].col)
2781 call assert_equal(12, l[1].col)
2782
2783 1Xvimgrep ?Editor? Xtestfile*
2784 let l = g:Xgetlist()
2785 call assert_equal(1, len(l))
2786 call assert_equal('Editor:VIM vim', l[0].text)
2787
2788 edit +3 Xtestfile2
2789 Xvimgrep +\cemacs+j Xtestfile1
2790 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002791 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002792 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2793
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002794 " Test for unloading a buffer after vimgrep searched the buffer
2795 %bwipe
2796 Xvimgrep /Editor/j Xtestfile*
2797 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2798 call assert_equal([], getbufinfo('Xtestfile2'))
2799
Bram Moolenaaree85df32017-03-19 14:19:50 +01002800 call delete('Xtestfile1')
2801 call delete('Xtestfile2')
2802endfunc
2803
2804" Tests for the :vimgrep command
2805func Test_vimgrep()
2806 call XvimgrepTests('c')
2807 call XvimgrepTests('l')
2808endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002809
Bram Moolenaar1c299432018-10-28 14:36:09 +01002810" Test for incsearch highlighting of the :vimgrep pattern
2811" This test used to cause "E315: ml_get: invalid lnum" errors.
2812func Test_vimgrep_incsearch()
2813 enew
2814 set incsearch
2815 call test_override("char_avail", 1)
2816
2817 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2818 let l = getqflist()
2819 call assert_equal(2, len(l))
2820
2821 call test_override("ALL", 0)
2822 set noincsearch
2823endfunc
2824
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002825" Test vimgrep with the last search pattern not set
2826func Test_vimgrep_with_no_last_search_pat()
2827 let lines =<< trim [SCRIPT]
2828 call assert_fails('vimgrep // *', 'E35:')
2829 call writefile(v:errors, 'Xresult')
2830 qall!
2831 [SCRIPT]
2832 call writefile(lines, 'Xscript')
2833 if RunVim([], [], '--clean -S Xscript')
2834 call assert_equal([], readfile('Xresult'))
2835 endif
2836 call delete('Xscript')
2837 call delete('Xresult')
2838endfunc
2839
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002840func Test_vimgrep_existing_swapfile()
2841 call writefile(['match apple with apple'], 'Xapple')
2842 call writefile(['swapfile'], '.Xapple.swp')
2843 let g:foundSwap = 0
2844 let g:ignoreSwapExists = 1
2845 augroup grep
2846 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2847 augroup END
2848 vimgrep apple Xapple
2849 call assert_equal(1, g:foundSwap)
2850 call assert_match('.Xapple.swo', swapname(''))
2851
2852 call delete('Xapple')
2853 call delete('Xapple.swp')
2854 augroup grep
2855 au! SwapExists
2856 augroup END
2857 unlet g:ignoreSwapExists
2858endfunc
2859
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002860func XfreeTests(cchar)
2861 call s:setup_commands(a:cchar)
2862
2863 enew | only
2864
2865 " Deleting the quickfix stack should work even When the current list is
2866 " somewhere in the middle of the stack
2867 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2868 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2869 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2870 Xolder
2871 call g:Xsetlist([], 'f')
2872 call assert_equal(0, len(g:Xgetlist()))
2873
2874 " After deleting the stack, adding a new list should create a stack with a
2875 " single list.
2876 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2877 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2878
2879 " Deleting the stack from a quickfix window should update/clear the
2880 " quickfix/location list window.
2881 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2882 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2883 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2884 Xolder
2885 Xwindow
2886 call g:Xsetlist([], 'f')
2887 call assert_equal(2, winnr('$'))
2888 call assert_equal(1, line('$'))
2889 Xclose
2890
2891 " Deleting the stack from a non-quickfix window should update/clear the
2892 " quickfix/location list window.
2893 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2894 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2895 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2896 Xolder
2897 Xwindow
2898 wincmd p
2899 call g:Xsetlist([], 'f')
2900 call assert_equal(0, len(g:Xgetlist()))
2901 wincmd p
2902 call assert_equal(2, winnr('$'))
2903 call assert_equal(1, line('$'))
2904
2905 " After deleting the location list stack, if the location list window is
2906 " opened, then a new location list should be created. So opening the
2907 " location list window again should not create a new window.
2908 if a:cchar == 'l'
2909 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2910 wincmd p
2911 lopen
2912 call assert_equal(2, winnr('$'))
2913 endif
2914 Xclose
2915endfunc
2916
Bram Moolenaar74240d32017-12-10 15:26:15 +01002917" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002918func Test_qf_free()
2919 call XfreeTests('c')
2920 call XfreeTests('l')
2921endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002922
2923" Test for buffer overflow when parsing lines and adding new entries to
2924" the quickfix list.
2925func Test_bufoverflow()
2926 set efm=%f:%l:%m
2927 cgetexpr ['File1:100:' . repeat('x', 1025)]
2928
2929 set efm=%+GCompiler:\ %.%#,%f:%l:%m
2930 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2931
2932 set efm=%DEntering\ directory\ %f,%f:%l:%m
2933 cgetexpr ['Entering directory ' . repeat('a', 1006),
2934 \ 'File1:10:Hello World']
2935 set efm&vim
2936endfunc
2937
Bram Moolenaar875feea2017-06-11 16:07:51 +02002938" Tests for getting the quickfix stack size
2939func XsizeTests(cchar)
2940 call s:setup_commands(a:cchar)
2941
2942 call g:Xsetlist([], 'f')
2943 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01002944 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2945 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02002946
2947 Xexpr "File1:10:Line1"
2948 Xexpr "File2:20:Line2"
2949 Xexpr "File3:30:Line3"
2950 Xolder | Xolder
2951 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2952 call g:Xsetlist([], 'f')
2953
2954 Xexpr "File1:10:Line1"
2955 Xexpr "File2:20:Line2"
2956 Xexpr "File3:30:Line3"
2957 Xolder | Xolder
2958 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2959 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2960endfunc
2961
2962func Test_Qf_Size()
2963 call XsizeTests('c')
2964 call XsizeTests('l')
2965endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02002966
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002967func Test_cclose_from_copen()
2968 augroup QF_Test
2969 au!
2970 au FileType qf :call assert_fails(':cclose', 'E788')
2971 augroup END
2972 copen
2973 augroup QF_Test
2974 au!
2975 augroup END
2976 augroup! QF_Test
2977endfunc
2978
Bram Moolenaar18141832017-06-25 21:17:25 +02002979func Test_cclose_in_autocmd()
2980 " Problem is only triggered if "starting" is zero, so that the OptionsSet
2981 " event will be triggered.
2982 call test_override('starting', 1)
2983 augroup QF_Test
2984 au!
2985 au FileType qf :call assert_fails(':cclose', 'E788')
2986 augroup END
2987 copen
2988 augroup QF_Test
2989 au!
2990 augroup END
2991 augroup! QF_Test
2992 call test_override('starting', 0)
2993endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02002994
Bram Moolenaar379fb762018-08-30 15:58:28 +02002995" Check that ":file" without an argument is possible even when "curbuf_lock"
2996" is set.
2997func Test_file_from_copen()
2998 " Works without argument.
2999 augroup QF_Test
3000 au!
3001 au FileType qf file
3002 augroup END
3003 copen
3004
3005 augroup QF_Test
3006 au!
3007 augroup END
3008 cclose
3009
3010 " Fails with argument.
3011 augroup QF_Test
3012 au!
3013 au FileType qf call assert_fails(':file foo', 'E788')
3014 augroup END
3015 copen
3016 augroup QF_Test
3017 au!
3018 augroup END
3019 cclose
3020
3021 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003022endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003023
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003024func Test_resize_from_copen()
3025 augroup QF_Test
3026 au!
3027 au FileType qf resize 5
3028 augroup END
3029 try
3030 " This should succeed without any exception. No other buffers are
3031 " involved in the autocmd.
3032 copen
3033 finally
3034 augroup QF_Test
3035 au!
3036 augroup END
3037 augroup! QF_Test
3038 endtry
3039endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003040
3041" Tests for the quickfix buffer b:changedtick variable
3042func Xchangedtick_tests(cchar)
3043 call s:setup_commands(a:cchar)
3044
3045 new | only
3046
3047 Xexpr "" | Xexpr "" | Xexpr ""
3048
3049 Xopen
3050 Xolder
3051 Xolder
3052 Xaddexpr "F1:10:Line10"
3053 Xaddexpr "F2:20:Line20"
3054 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3055 call g:Xsetlist([], 'f')
3056 call assert_equal(8, getbufvar('%', 'changedtick'))
3057 Xclose
3058endfunc
3059
3060func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003061 call Xchangedtick_tests('c')
3062 call Xchangedtick_tests('l')
3063endfunc
3064
3065" Tests for parsing an expression using setqflist()
3066func Xsetexpr_tests(cchar)
3067 call s:setup_commands(a:cchar)
3068
3069 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003070 call g:Xsetlist([], ' ', {'lines' : t})
3071 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003072
3073 let l = g:Xgetlist()
3074 call assert_equal(3, len(l))
3075 call assert_equal(20, l[1].lnum)
3076 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003077 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003078 let l = g:Xgetlist()
3079 call assert_equal(1, len(l))
3080 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003081 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3082 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003083
3084 call g:Xsetlist([], 'f')
3085 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003086 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3087 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3088 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3089 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003090 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3091 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003092
3093 " Adding entries using a custom efm
3094 set efm&
3095 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3096 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3097 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3098 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3099 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3100 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3101 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3102 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003103endfunc
3104
3105func Test_setexpr()
3106 call Xsetexpr_tests('c')
3107 call Xsetexpr_tests('l')
3108endfunc
3109
3110" Tests for per quickfix/location list directory stack
3111func Xmultidirstack_tests(cchar)
3112 call s:setup_commands(a:cchar)
3113
3114 call g:Xsetlist([], 'f')
3115 Xexpr "" | Xexpr ""
3116
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003117 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3118 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3119 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3120 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003121
3122 let l1 = g:Xgetlist({'nr':1, 'items':1})
3123 let l2 = g:Xgetlist({'nr':2, 'items':1})
3124 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3125 call assert_equal(3, l1.items[1].lnum)
3126 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3127 call assert_equal(5, l2.items[1].lnum)
3128endfunc
3129
3130func Test_multidirstack()
3131 call mkdir('Xone/a', 'p')
3132 call mkdir('Xtwo/a', 'p')
3133 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3134 call writefile(lines, 'Xone/a/one.txt')
3135 call writefile(lines, 'Xtwo/a/two.txt')
3136 let save_efm = &efm
3137 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3138
3139 call Xmultidirstack_tests('c')
3140 call Xmultidirstack_tests('l')
3141
3142 let &efm = save_efm
3143 call delete('Xone', 'rf')
3144 call delete('Xtwo', 'rf')
3145endfunc
3146
3147" Tests for per quickfix/location list file stack
3148func Xmultifilestack_tests(cchar)
3149 call s:setup_commands(a:cchar)
3150
3151 call g:Xsetlist([], 'f')
3152 Xexpr "" | Xexpr ""
3153
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003154 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3155 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3156 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3157 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003158
3159 let l1 = g:Xgetlist({'nr':1, 'items':1})
3160 let l2 = g:Xgetlist({'nr':2, 'items':1})
3161 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3162 call assert_equal(3, l1.items[1].lnum)
3163 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3164 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003165
3166 " Test for start of a new error line in the same line where a previous
3167 " error line ends with a file stack.
3168 let efm_val = 'Error\ l%l\ in\ %f,'
3169 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3170 let l = g:Xgetlist({'lines' : [
3171 \ '(one.txt',
3172 \ 'Error l4 in one.txt',
3173 \ ') (two.txt',
3174 \ 'Error l6 in two.txt',
3175 \ ')',
3176 \ 'Error l8 in one.txt'
3177 \ ], 'efm' : efm_val})
3178 call assert_equal(3, len(l.items))
3179 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3180 call assert_equal(4, l.items[0].lnum)
3181 call assert_equal('one.txt', l.items[0].text)
3182 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3183 call assert_equal(6, l.items[1].lnum)
3184 call assert_equal('two.txt', l.items[1].text)
3185 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3186 call assert_equal(8, l.items[2].lnum)
3187 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003188endfunc
3189
3190func Test_multifilestack()
3191 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3192 call writefile(lines, 'one.txt')
3193 call writefile(lines, 'two.txt')
3194 let save_efm = &efm
3195 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3196
3197 call Xmultifilestack_tests('c')
3198 call Xmultifilestack_tests('l')
3199
3200 let &efm = save_efm
3201 call delete('one.txt')
3202 call delete('two.txt')
3203endfunc
3204
3205" Tests for per buffer 'efm' setting
3206func Test_perbuf_efm()
3207 call writefile(["File1-10-Line10"], 'one.txt')
3208 call writefile(["File2#20#Line20"], 'two.txt')
3209 set efm=%f#%l#%m
3210 new | only
3211 new
3212 setlocal efm=%f-%l-%m
3213 cfile one.txt
3214 wincmd w
3215 caddfile two.txt
3216
3217 let l = getqflist()
3218 call assert_equal(10, l[0].lnum)
3219 call assert_equal('Line20', l[1].text)
3220
3221 set efm&
3222 new | only
3223 call delete('one.txt')
3224 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003225endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003226
3227" Open multiple help windows using ":lhelpgrep
3228" This test used to crash Vim
3229func Test_Multi_LL_Help()
3230 new | only
3231 lhelpgrep window
3232 lopen
3233 e#
3234 lhelpgrep buffer
3235 call assert_equal(3, winnr('$'))
3236 call assert_true(len(getloclist(1)) != 0)
3237 call assert_true(len(getloclist(2)) != 0)
3238 new | only
3239endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003240
3241" Tests for adding new quickfix lists using setqflist()
3242func XaddQf_tests(cchar)
3243 call s:setup_commands(a:cchar)
3244
3245 " Create a new list using ' ' for action
3246 call g:Xsetlist([], 'f')
3247 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3248 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3249 call assert_equal(1, l.nr)
3250 call assert_equal('Test1', l.title)
3251
3252 " Create a new list using ' ' for action and '$' for 'nr'
3253 call g:Xsetlist([], 'f')
3254 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3255 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3256 call assert_equal(1, l.nr)
3257 call assert_equal('Test2', l.title)
3258
3259 " Create a new list using 'a' for action
3260 call g:Xsetlist([], 'f')
3261 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3262 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3263 call assert_equal(1, l.nr)
3264 call assert_equal('Test3', l.title)
3265
3266 " Create a new list using 'a' for action and '$' for 'nr'
3267 call g:Xsetlist([], 'f')
3268 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3269 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3270 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3271 call assert_equal(1, l.nr)
3272 call assert_equal('Test4', l.title)
3273
3274 " Adding a quickfix list should remove all the lists following the current
3275 " list.
3276 Xexpr "" | Xexpr "" | Xexpr ""
3277 silent! 10Xolder
3278 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3279 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3280 call assert_equal(2, l.nr)
3281 call assert_equal('Test5', l.title)
3282
3283 " Add a quickfix list using '$' as the list number.
3284 let lastqf = g:Xgetlist({'nr':'$'}).nr
3285 silent! 99Xolder
3286 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3287 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3288 call assert_equal(lastqf + 1, l.nr)
3289 call assert_equal('Test6', l.title)
3290
3291 " Add a quickfix list using 'nr' set to one more than the quickfix
3292 " list size.
3293 let lastqf = g:Xgetlist({'nr':'$'}).nr
3294 silent! 99Xolder
3295 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3296 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3297 call assert_equal(lastqf + 1, l.nr)
3298 call assert_equal('Test7', l.title)
3299
3300 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3301 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3302 silent! 99Xolder
3303 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3304 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3305 call assert_equal(10, l.nr)
3306 call assert_equal('Test8', l.title)
3307
3308 " Add a quickfix list using 'nr' set to a value greater than 10
3309 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3310
3311 " Try adding a quickfix list with 'nr' set to a value greater than the
3312 " quickfix list size but less than 10.
3313 call g:Xsetlist([], 'f')
3314 Xexpr "" | Xexpr "" | Xexpr ""
3315 silent! 99Xolder
3316 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3317
3318 " Add a quickfix list using 'nr' set to a some string or list
3319 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3320endfunc
3321
3322func Test_add_qf()
3323 call XaddQf_tests('c')
3324 call XaddQf_tests('l')
3325endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003326
3327" Test for getting the quickfix list items from some text without modifying
3328" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003329func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003330 call s:setup_commands(a:cchar)
3331 call g:Xsetlist([], 'f')
3332
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003333 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003334 call assert_equal(2, len(l))
3335 call assert_equal(30, l[1].lnum)
3336
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003337 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3338 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3339 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3340 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003341
Bram Moolenaar36538222017-09-02 19:51:44 +02003342 " Parse text using a custom efm
3343 set efm&
3344 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3345 call assert_equal('Line30', l[0].text)
3346 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3347 call assert_equal('File3:30:Line30', l[0].text)
3348 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3349 call assert_equal({}, l)
3350 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3351 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3352
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003353 " Make sure that the quickfix stack is not modified
3354 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3355endfunc
3356
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003357func Test_get_list_from_lines()
3358 call XgetListFromLines('c')
3359 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003360endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003361
3362" Tests for the quickfix list id
3363func Xqfid_tests(cchar)
3364 call s:setup_commands(a:cchar)
3365
3366 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003367 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003368 Xexpr ''
3369 let start_id = g:Xgetlist({'id' : 0}).id
3370 Xexpr '' | Xexpr ''
3371 Xolder
3372 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3373 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3374 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003375 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003376 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003377 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3378 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003379
3380 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3381 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003382 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003383 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3384 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3385 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3386
3387 let qfid = g:Xgetlist({'id':0, 'nr':0})
3388 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003389 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003390endfunc
3391
3392func Test_qf_id()
3393 call Xqfid_tests('c')
3394 call Xqfid_tests('l')
3395endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003396
3397func Xqfjump_tests(cchar)
3398 call s:setup_commands(a:cchar)
3399
3400 call writefile(["Line1\tFoo", "Line2"], 'F1')
3401 call writefile(["Line1\tBar", "Line2"], 'F2')
3402 call writefile(["Line1\tBaz", "Line2"], 'F3')
3403
3404 call g:Xsetlist([], 'f')
3405
3406 " Tests for
3407 " Jumping to a line using a pattern
3408 " Jumping to a column greater than the last column in a line
3409 " Jumping to a line greater than the last line in the file
3410 let l = []
3411 for i in range(1, 7)
3412 call add(l, {})
3413 endfor
3414 let l[0].filename='F1'
3415 let l[0].pattern='Line1'
3416 let l[1].filename='F2'
3417 let l[1].pattern='Line1'
3418 let l[2].filename='F3'
3419 let l[2].pattern='Line1'
3420 let l[3].filename='F3'
3421 let l[3].lnum=1
3422 let l[3].col=9
3423 let l[3].vcol=1
3424 let l[4].filename='F3'
3425 let l[4].lnum=99
3426 let l[5].filename='F3'
3427 let l[5].lnum=1
3428 let l[5].col=99
3429 let l[5].vcol=1
3430 let l[6].filename='F3'
3431 let l[6].pattern='abcxyz'
3432
3433 call g:Xsetlist([], ' ', {'items' : l})
3434 Xopen | only
3435 2Xnext
3436 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003437 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003438 Xnext
3439 call assert_equal(7, col('.'))
3440 Xnext
3441 call assert_equal(2, line('.'))
3442 Xnext
3443 call assert_equal(9, col('.'))
3444 2
3445 Xnext
3446 call assert_equal(2, line('.'))
3447
3448 if a:cchar == 'l'
3449 " When jumping to a location list entry in the location list window and
3450 " no usable windows are available, then a new window should be opened.
3451 enew! | new | only
3452 call g:Xsetlist([], 'f')
3453 setlocal buftype=nofile
3454 new
3455 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']})
3456 Xopen
3457 let winid = win_getid()
3458 wincmd p
3459 close
3460 call win_gotoid(winid)
3461 Xnext
3462 call assert_equal(3, winnr('$'))
3463 call assert_equal(1, winnr())
3464 call assert_equal(2, line('.'))
3465
3466 " When jumping to an entry in the location list window and the window
3467 " associated with the location list is not present and a window containing
3468 " the file is already present, then that window should be used.
3469 close
3470 belowright new
3471 call g:Xsetlist([], 'f')
3472 edit F3
3473 call win_gotoid(winid)
3474 Xlast
3475 call assert_equal(3, winnr())
3476 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3477 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3478 endif
3479
3480 " Cleanup
3481 enew!
3482 new | only
3483
3484 call delete('F1')
3485 call delete('F2')
3486 call delete('F3')
3487endfunc
3488
3489func Test_qfjump()
3490 call Xqfjump_tests('c')
3491 call Xqfjump_tests('l')
3492endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003493
3494" Tests for the getqflist() and getloclist() functions when the list is not
3495" present or is empty
3496func Xgetlist_empty_tests(cchar)
3497 call s:setup_commands(a:cchar)
3498
3499 " Empty quickfix stack
3500 call g:Xsetlist([], 'f')
3501 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3502 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3503 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3504 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3505 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3506 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3507 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3508 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003509 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003510 if a:cchar == 'c'
3511 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003512 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003513 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3514 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003515 else
3516 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3517 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003518 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003519 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003520 \ g:Xgetlist({'all' : 0}))
3521 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003522
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003523 " Quickfix window with empty stack
3524 silent! Xopen
3525 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003526 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003527 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3528 Xclose
3529
Bram Moolenaara6d48492017-12-12 22:45:31 +01003530 " Empty quickfix list
3531 Xexpr ""
3532 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3533 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3534 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3535 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3536 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3537 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3538 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3539 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003540 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003541
3542 let qfid = g:Xgetlist({'id' : 0}).id
3543 call g:Xsetlist([], 'f')
3544
3545 " Non-existing quickfix identifier
3546 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3547 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3548 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3549 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3550 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3551 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3552 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3553 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003554 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003555 if a:cchar == 'c'
3556 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3557 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003558 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003559 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3560 else
3561 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3562 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003563 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3564 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003565 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3566 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003567
3568 " Non-existing quickfix list number
3569 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3570 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3571 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3572 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3573 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3574 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3575 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3576 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003577 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003578 if a:cchar == 'c'
3579 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3580 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003581 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3582 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003583 else
3584 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3585 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003586 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3587 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003588 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003589endfunc
3590
3591func Test_getqflist()
3592 call Xgetlist_empty_tests('c')
3593 call Xgetlist_empty_tests('l')
3594endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003595
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003596func Test_getqflist_invalid_nr()
3597 " The following commands used to crash Vim
3598 cexpr ""
3599 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3600
3601 " Cleanup
3602 call setqflist([], 'r')
3603endfunc
3604
Bram Moolenaarb254af32017-12-18 19:48:58 +01003605" Tests for the quickfix/location list changedtick
3606func Xqftick_tests(cchar)
3607 call s:setup_commands(a:cchar)
3608
3609 call g:Xsetlist([], 'f')
3610
3611 Xexpr "F1:10:Line10"
3612 let qfid = g:Xgetlist({'id' : 0}).id
3613 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3614 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3615 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3616 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3617 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3618 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3619 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3620 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3621 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3622
3623 enew!
3624 call append(0, ["F5:50:L50", "F6:60:L60"])
3625 Xaddbuffer
3626 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3627 enew!
3628
3629 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3630 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3631 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3632 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3633 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3634 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3635 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3636 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3637 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3638 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3639 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3640
3641 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3642 Xfile Xone
3643 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3644 Xaddfile Xone
3645 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3646
3647 " Test case for updating a non-current quickfix list
3648 call g:Xsetlist([], 'f')
3649 Xexpr "F1:1:L1"
3650 Xexpr "F2:2:L2"
3651 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3652 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3653 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3654
3655 call delete("Xone")
3656endfunc
3657
3658func Test_qf_tick()
3659 call Xqftick_tests('c')
3660 call Xqftick_tests('l')
3661endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003662
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003663" Test helpgrep with lang specifier
3664func Xtest_helpgrep_with_lang_specifier(cchar)
3665 call s:setup_commands(a:cchar)
3666 Xhelpgrep Vim@en
3667 call assert_equal('help', &filetype)
3668 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3669 new | only
3670endfunc
3671
3672func Test_helpgrep_with_lang_specifier()
3673 call Xtest_helpgrep_with_lang_specifier('c')
3674 call Xtest_helpgrep_with_lang_specifier('l')
3675endfunc
3676
Bram Moolenaar12237442017-12-19 12:38:52 +01003677" The following test used to crash Vim.
3678" Open the location list window and close the regular window associated with
3679" the location list. When the garbage collection runs now, it incorrectly
3680" marks the location list context as not in use and frees the context.
3681func Test_ll_window_ctx()
3682 call setloclist(0, [], 'f')
3683 call setloclist(0, [], 'a', {'context' : []})
3684 lopen | only
3685 call test_garbagecollect_now()
3686 echo getloclist(0, {'context' : 1}).context
3687 enew | only
3688endfunc
3689
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003690" The following test used to crash vim
3691func Test_lfile_crash()
3692 sp Xtest
3693 au QuickFixCmdPre * bw
3694 call assert_fails('lfile', 'E40')
3695 au! QuickFixCmdPre
3696endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003697
3698" The following test used to crash vim
3699func Test_lbuffer_crash()
3700 sv Xtest
3701 augroup QF_Test
3702 au!
3703 au * * bw
3704 augroup END
3705 lbuffer
3706 augroup QF_Test
3707 au!
3708 augroup END
3709endfunc
3710
3711" The following test used to crash vim
3712func Test_lexpr_crash()
3713 augroup QF_Test
3714 au!
3715 au * * call setloclist(0, [], 'f')
3716 augroup END
3717 lexpr ""
3718 augroup QF_Test
3719 au!
3720 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003721
Bram Moolenaar3c097222017-12-21 20:54:49 +01003722 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003723 augroup QF_Test
3724 au!
3725 au BufNew * call setloclist(0, [], 'f')
3726 augroup END
3727 lexpr 'x:1:x'
3728 augroup QF_Test
3729 au!
3730 augroup END
3731
3732 enew | only
3733 lexpr ''
3734 lopen
3735 augroup QF_Test
3736 au!
3737 au FileType * call setloclist(0, [], 'f')
3738 augroup END
3739 lexpr ''
3740 augroup QF_Test
3741 au!
3742 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003743endfunc
3744
3745" The following test used to crash Vim
3746func Test_lvimgrep_crash()
3747 sv Xtest
3748 augroup QF_Test
3749 au!
3750 au * * call setloclist(0, [], 'f')
3751 augroup END
3752 lvimgrep quickfix test_quickfix.vim
3753 augroup QF_Test
3754 au!
3755 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003756
3757 new | only
3758 augroup QF_Test
3759 au!
3760 au BufEnter * call setloclist(0, [], 'r')
3761 augroup END
3762 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3763 augroup QF_Test
3764 au!
3765 augroup END
3766
Bram Moolenaar3c097222017-12-21 20:54:49 +01003767 enew | only
3768endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003769
Bram Moolenaar2573af32020-03-14 17:21:34 +01003770func Test_lvimgrep_crash2()
3771 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003772 call assert_fails('lvimgrep x x', 'E471:')
3773 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003774
3775 au! BufNewFile
3776endfunc
3777
Bram Moolenaarde046542017-12-26 13:53:11 +01003778" Test for the position of the quickfix and location list window
3779func Test_qfwin_pos()
3780 " Open two windows
3781 new | only
3782 new
3783 cexpr ['F1:10:L10']
3784 copen
3785 " Quickfix window should be the bottom most window
3786 call assert_equal(3, winnr())
3787 close
3788 " Open at the very top
3789 wincmd t
3790 topleft copen
3791 call assert_equal(1, winnr())
3792 close
3793 " open left of the current window
3794 wincmd t
3795 below new
3796 leftabove copen
3797 call assert_equal(2, winnr())
3798 close
3799 " open right of the current window
3800 rightbelow copen
3801 call assert_equal(3, winnr())
3802 close
3803endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003804
3805" Tests for quickfix/location lists changed by autocommands when
3806" :vimgrep/:lvimgrep commands are running.
3807func Test_vimgrep_autocmd()
3808 call setqflist([], 'f')
3809 call writefile(['stars'], 'Xtest1.txt')
3810 call writefile(['stars'], 'Xtest2.txt')
3811
3812 " Test 1:
3813 " When searching for a pattern using :vimgrep, if the quickfix list is
3814 " changed by an autocmd, the results should be added to the correct quickfix
3815 " list.
3816 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3817 silent vimgrep stars Xtest*.txt
3818 call assert_equal(1, getqflist({'nr' : 0}).nr)
3819 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3820 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3821 au! BufRead Xtest2.txt
3822
3823 " Test 2:
3824 " When searching for a pattern using :vimgrep, if the quickfix list is
3825 " freed, then a error should be given.
3826 silent! %bwipe!
3827 call setqflist([], 'f')
3828 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3829 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3830 au! BufRead Xtest2.txt
3831
3832 " Test 3:
3833 " When searching for a pattern using :lvimgrep, if the location list is
3834 " freed, then the command should error out.
3835 silent! %bwipe!
3836 let g:save_winid = win_getid()
3837 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3838 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3839 au! BufRead Xtest2.txt
3840
3841 call delete('Xtest1.txt')
3842 call delete('Xtest2.txt')
3843 call setqflist([], 'f')
3844endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003845
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003846" Test for an autocmd changing the current directory when running vimgrep
3847func Xvimgrep_autocmd_cd(cchar)
3848 call s:setup_commands(a:cchar)
3849
3850 %bwipe
3851 let save_cwd = getcwd()
3852
3853 augroup QF_Test
3854 au!
3855 autocmd BufRead * silent cd %:p:h
3856 augroup END
3857
3858 10Xvimgrep /vim/ Xdir/**
3859 let l = g:Xgetlist()
3860 call assert_equal('f1.txt', bufname(l[0].bufnr))
3861 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
3862
3863 augroup QF_Test
3864 au!
3865 augroup END
3866
3867 exe 'cd ' . save_cwd
3868endfunc
3869
3870func Test_vimgrep_autocmd_cd()
3871 call mkdir('Xdir/a', 'p')
3872 call mkdir('Xdir/b', 'p')
3873 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
3874 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
3875 call Xvimgrep_autocmd_cd('c')
3876 call Xvimgrep_autocmd_cd('l')
3877 %bwipe
3878 call delete('Xdir', 'rf')
3879endfunc
3880
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003881" The following test used to crash Vim
3882func Test_lhelpgrep_autocmd()
3883 lhelpgrep quickfix
3884 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3885 lhelpgrep buffer
3886 call assert_equal('help', &filetype)
3887 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3888 lhelpgrep tabpage
3889 call assert_equal('help', &filetype)
3890 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3891 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003892
3893 new | only
3894 augroup QF_Test
3895 au!
3896 au BufEnter * call setqflist([], 'f')
3897 augroup END
3898 call assert_fails('helpgrep quickfix', 'E925:')
3899 augroup QF_Test
3900 au! BufEnter
3901 augroup END
3902
3903 new | only
3904 augroup QF_Test
3905 au!
3906 au BufEnter * call setqflist([], 'r')
3907 augroup END
3908 call assert_fails('helpgrep quickfix', 'E925:')
3909 augroup QF_Test
3910 au! BufEnter
3911 augroup END
3912
3913 new | only
3914 augroup QF_Test
3915 au!
3916 au BufEnter * call setloclist(0, [], 'r')
3917 augroup END
3918 call assert_fails('lhelpgrep quickfix', 'E926:')
3919 augroup QF_Test
3920 au! BufEnter
3921 augroup END
3922
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003923 new | only
3924endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02003925
3926" Test for shortening/simplifying the file name when opening the
3927" quickfix window or when displaying the quickfix list
3928func Test_shorten_fname()
3929 if !has('unix')
3930 return
3931 endif
3932 %bwipe
3933 " Create a quickfix list with a absolute path filename
3934 let fname = getcwd() . '/test_quickfix.vim'
3935 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3936 call assert_equal(fname, bufname('test_quickfix.vim'))
3937 " Opening the quickfix window should simplify the file path
3938 cwindow
3939 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3940 cclose
3941 %bwipe
3942 " Create a quickfix list with a absolute path filename
3943 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3944 call assert_equal(fname, bufname('test_quickfix.vim'))
3945 " Displaying the quickfix list should simplify the file path
3946 silent! clist
3947 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3948endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02003949
3950" Quickfix title tests
3951" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3952" Otherwise due to indentation, the title is set with spaces at the beginning
3953" of the command.
3954func Test_qftitle()
3955 call writefile(["F1:1:Line1"], 'Xerr')
3956
3957 " :cexpr
3958 exe "cexpr readfile('Xerr')"
3959 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3960
3961 " :cgetexpr
3962 exe "cgetexpr readfile('Xerr')"
3963 call assert_equal(":cgetexpr readfile('Xerr')",
3964 \ getqflist({'title' : 1}).title)
3965
3966 " :caddexpr
3967 call setqflist([], 'f')
3968 exe "caddexpr readfile('Xerr')"
3969 call assert_equal(":caddexpr readfile('Xerr')",
3970 \ getqflist({'title' : 1}).title)
3971
3972 " :cbuffer
3973 new Xerr
3974 exe "cbuffer"
3975 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3976
3977 " :cgetbuffer
3978 edit Xerr
3979 exe "cgetbuffer"
3980 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3981
3982 " :caddbuffer
3983 call setqflist([], 'f')
3984 edit Xerr
3985 exe "caddbuffer"
3986 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3987
3988 " :cfile
3989 exe "cfile Xerr"
3990 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
3991
3992 " :cgetfile
3993 exe "cgetfile Xerr"
3994 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
3995
3996 " :caddfile
3997 call setqflist([], 'f')
3998 exe "caddfile Xerr"
3999 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4000
4001 " :grep
4002 set grepprg=internal
4003 exe "grep F1 Xerr"
4004 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4005
4006 " :grepadd
4007 call setqflist([], 'f')
4008 exe "grepadd F1 Xerr"
4009 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4010 set grepprg&vim
4011
4012 " :vimgrep
4013 exe "vimgrep F1 Xerr"
4014 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4015
4016 " :vimgrepadd
4017 call setqflist([], 'f')
4018 exe "vimgrepadd F1 Xerr"
4019 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4020
4021 call setqflist(['F1:10:L10'], ' ')
4022 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4023
4024 call setqflist([], 'f')
4025 call setqflist(['F1:10:L10'], 'a')
4026 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4027
4028 call setqflist([], 'f')
4029 call setqflist(['F1:10:L10'], 'r')
4030 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4031
4032 close
4033 call delete('Xerr')
4034
4035 call setqflist([], ' ', {'title' : 'Errors'})
4036 copen
4037 call assert_equal('Errors', w:quickfix_title)
4038 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4039 call assert_equal('Errors', w:quickfix_title)
4040 cclose
4041endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004042
4043func Test_lbuffer_with_bwipe()
4044 new
4045 new
4046 augroup nasty
4047 au * * bwipe
4048 augroup END
4049 lbuffer
4050 augroup nasty
4051 au!
4052 augroup END
4053endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004054
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004055" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4056" running
4057func Xexpr_acmd_freelist(cchar)
4058 call s:setup_commands(a:cchar)
4059
Bram Moolenaar0366c012018-06-18 20:52:13 +02004060 " This was using freed memory.
4061 augroup nasty
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004062 au * * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004063 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004064 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004065 augroup nasty
4066 au!
4067 augroup END
4068endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004069
4070func Test_cexpr_acmd_freelist()
4071 call Xexpr_acmd_freelist('c')
4072 call Xexpr_acmd_freelist('l')
4073endfunc
4074
4075" Test for commands that create a new quickfix/location list and jump to the
4076" first error automatically.
4077func Xjumpto_first_error_test(cchar)
4078 call s:setup_commands(a:cchar)
4079
4080 call s:create_test_file('Xtestfile1')
4081 call s:create_test_file('Xtestfile2')
4082 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4083
4084 " Test for cexpr/lexpr
4085 enew
4086 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004087 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004088 call assert_equal(2, line('.'))
4089
4090 " Test for cfile/lfile
4091 enew
4092 call writefile(l, 'Xerr')
4093 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004094 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004095 call assert_equal(2, line('.'))
4096
4097 " Test for cbuffer/lbuffer
4098 edit Xerr
4099 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004100 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004101 call assert_equal(2, line('.'))
4102
4103 call delete('Xerr')
4104 call delete('Xtestfile1')
4105 call delete('Xtestfile2')
4106endfunc
4107
4108func Test_jumpto_first_error()
4109 call Xjumpto_first_error_test('c')
4110 call Xjumpto_first_error_test('l')
4111endfunc
4112
4113" Test for a quickfix autocmd changing the quickfix/location list before
4114" jumping to the first error in the new list.
4115func Xautocmd_changelist(cchar)
4116 call s:setup_commands(a:cchar)
4117
4118 " Test for cfile/lfile
4119 call s:create_test_file('Xtestfile1')
4120 call s:create_test_file('Xtestfile2')
4121 Xexpr 'Xtestfile1:2:Line2'
4122 autocmd QuickFixCmdPost * Xolder
4123 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4124 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004125 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004126 call assert_equal(4, line('.'))
4127 autocmd! QuickFixCmdPost
4128
4129 " Test for cbuffer/lbuffer
4130 call g:Xsetlist([], 'f')
4131 Xexpr 'Xtestfile1:2:Line2'
4132 autocmd QuickFixCmdPost * Xolder
4133 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4134 edit Xerr
4135 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004136 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004137 call assert_equal(4, line('.'))
4138 autocmd! QuickFixCmdPost
4139
4140 " Test for cexpr/lexpr
4141 call g:Xsetlist([], 'f')
4142 Xexpr 'Xtestfile1:2:Line2'
4143 autocmd QuickFixCmdPost * Xolder
4144 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004145 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004146 call assert_equal(4, line('.'))
4147 autocmd! QuickFixCmdPost
4148
Bram Moolenaar851332e2018-07-03 19:16:00 +02004149 " The grepprg may not be set on non-Unix systems
4150 if has('unix')
4151 " Test for grep/lgrep
4152 call g:Xsetlist([], 'f')
4153 Xexpr 'Xtestfile1:2:Line2'
4154 autocmd QuickFixCmdPost * Xolder
4155 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004156 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004157 call assert_equal(5, line('.'))
4158 autocmd! QuickFixCmdPost
4159 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004160
4161 " Test for vimgrep/lvimgrep
4162 call g:Xsetlist([], 'f')
4163 Xexpr 'Xtestfile1:2:Line2'
4164 autocmd QuickFixCmdPost * Xolder
4165 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004166 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004167 call assert_equal(5, line('.'))
4168 autocmd! QuickFixCmdPost
4169
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004170 " Test for autocommands clearing the quickfix list before jumping to the
4171 " first error. This should not result in an error
4172 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4173 let v:errmsg = ''
4174 " Test for cfile/lfile
4175 Xfile Xerr
4176 call assert_true(v:errmsg !~# 'E42:')
4177 " Test for cbuffer/lbuffer
4178 edit Xerr
4179 Xbuffer
4180 call assert_true(v:errmsg !~# 'E42:')
4181 " Test for cexpr/lexpr
4182 Xexpr 'Xtestfile2:4:Line4'
4183 call assert_true(v:errmsg !~# 'E42:')
4184 " Test for grep/lgrep
4185 " The grepprg may not be set on non-Unix systems
4186 if has('unix')
4187 silent Xgrep Line5 Xtestfile2
4188 call assert_true(v:errmsg !~# 'E42:')
4189 endif
4190 " Test for vimgrep/lvimgrep
4191 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4192 autocmd! QuickFixCmdPost
4193
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004194 call delete('Xerr')
4195 call delete('Xtestfile1')
4196 call delete('Xtestfile2')
4197endfunc
4198
4199func Test_autocmd_changelist()
4200 call Xautocmd_changelist('c')
4201 call Xautocmd_changelist('l')
4202endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004203
4204" Tests for the ':filter /pat/ clist' command
4205func Test_filter_clist()
4206 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4207 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4208 \ split(execute('filter /Line 15/ clist'), "\n"))
4209 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4210 \ split(execute('filter /Xfile1/ clist'), "\n"))
4211 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4212
4213 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4214 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4215 call assert_equal([' 2 pqr:pat2: '],
4216 \ split(execute('filter /pqr/ clist'), "\n"))
4217 call assert_equal([' 1 abc:pat1: '],
4218 \ split(execute('filter /pat1/ clist'), "\n"))
4219endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004220
4221" Tests for the "CTRL-W <CR>" command.
4222func Xview_result_split_tests(cchar)
4223 call s:setup_commands(a:cchar)
4224
4225 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4226 call g:Xsetlist([])
4227 Xopen
4228 let l:win_count = winnr('$')
4229 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
4230 call assert_equal(l:win_count, winnr('$'))
4231 Xclose
4232endfunc
4233
4234func Test_view_result_split()
4235 call Xview_result_split_tests('c')
4236 call Xview_result_split_tests('l')
4237endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004238
4239" Test that :cc sets curswant
4240func Test_curswant()
4241 helpgrep quickfix
4242 normal! llll
4243 1cc
4244 call assert_equal(getcurpos()[4], virtcol('.'))
4245 cclose | helpclose
4246endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004247
4248" Test for opening a file from the quickfix window using CTRL-W <Enter>
4249" doesn't leave an empty buffer around.
4250func Test_splitview()
4251 call s:create_test_file('Xtestfile1')
4252 call s:create_test_file('Xtestfile2')
4253 new | only
4254 let last_bufnr = bufnr('Test_sv_1', 1)
4255 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4256 cgetexpr l
4257 copen
4258 let numbufs = len(getbufinfo())
4259 exe "normal \<C-W>\<CR>"
4260 copen
4261 exe "normal j\<C-W>\<CR>"
4262 " Make sure new empty buffers are not created
4263 call assert_equal(numbufs, len(getbufinfo()))
4264 " Creating a new buffer should use the next available buffer number
4265 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4266 bwipe Test_sv_1
4267 bwipe Test_sv_2
4268 new | only
4269
4270 " When split opening files from location list window, make sure that two
4271 " windows doesn't refer to the same location list
4272 lgetexpr l
4273 let locid = getloclist(0, {'id' : 0}).id
4274 lopen
4275 exe "normal \<C-W>\<CR>"
4276 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4277 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4278 new | only
4279
4280 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004281 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004282 lhelpgrep window
4283 let locid = getloclist(0, {'id' : 0}).id
4284 lwindow
4285 exe "normal j\<C-W>\<CR>"
4286 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4287 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4288 new | only
4289
Bram Moolenaar406cd902020-02-18 21:54:41 +01004290 " Using :split or :vsplit from a quickfix window should behave like a :new
4291 " or a :vnew command
4292 copen
4293 split
4294 call assert_equal(3, winnr('$'))
4295 let l = getwininfo()
4296 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4297 close
4298 copen
4299 vsplit
4300 let l = getwininfo()
4301 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4302 new | only
4303
Bram Moolenaarb2443732018-11-11 22:50:27 +01004304 call delete('Xtestfile1')
4305 call delete('Xtestfile2')
4306endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004307
4308" Test for parsing entries using visual screen column
4309func Test_viscol()
4310 enew
4311 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4312 edit Xfile1
4313
4314 " Use byte offset for column number
4315 set efm&
4316 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4317 call assert_equal([5, 8], [col('.'), virtcol('.')])
4318 cnext
4319 call assert_equal([9, 12], [col('.'), virtcol('.')])
4320 cnext
4321 call assert_equal([14, 20], [col('.'), virtcol('.')])
4322
4323 " Use screen column offset for column number
4324 set efm=%f:%l:%v:%m
4325 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4326 call assert_equal([5, 8], [col('.'), virtcol('.')])
4327 cnext
4328 call assert_equal([9, 12], [col('.'), virtcol('.')])
4329 cnext
4330 call assert_equal([14, 20], [col('.'), virtcol('.')])
4331 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4332 call assert_equal([5, 8], [col('.'), virtcol('.')])
4333 cnext
4334 call assert_equal([10, 16], [col('.'), virtcol('.')])
4335 cnext
4336 call assert_equal([14, 20], [col('.'), virtcol('.')])
4337
4338 enew
4339 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4340
4341 " Use byte offset for column number
4342 set efm&
4343 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4344 call assert_equal([8, 10], [col('.'), virtcol('.')])
4345 cnext
4346 call assert_equal([11, 17], [col('.'), virtcol('.')])
4347 cnext
4348 call assert_equal([16, 25], [col('.'), virtcol('.')])
4349
4350 " Use screen column offset for column number
4351 set efm=%f:%l:%v:%m
4352 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4353 call assert_equal([8, 10], [col('.'), virtcol('.')])
4354 cnext
4355 call assert_equal([11, 17], [col('.'), virtcol('.')])
4356 cnext
4357 call assert_equal([16, 25], [col('.'), virtcol('.')])
4358
4359 enew | only
4360 set efm&
4361 call delete('Xfile1')
4362endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004363
4364" Test for the quickfix window buffer
4365func Xqfbuf_test(cchar)
4366 call s:setup_commands(a:cchar)
4367
4368 " Quickfix buffer should be reused across closing and opening a quickfix
4369 " window
4370 Xexpr "F1:10:Line10"
4371 Xopen
4372 let qfbnum = bufnr('')
4373 Xclose
4374 " Even after the quickfix window is closed, the buffer should be loaded
4375 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004376 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004377 Xopen
4378 " Buffer should be reused when opening the window again
4379 call assert_equal(qfbnum, bufnr(''))
4380 Xclose
4381
4382 if a:cchar == 'l'
4383 %bwipe
4384 " For a location list, when both the file window and the location list
4385 " window for the list are closed, then the buffer should be freed.
4386 new | only
4387 lexpr "F1:10:Line10"
4388 let wid = win_getid()
4389 lopen
4390 let qfbnum = bufnr('')
4391 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4392 close
4393 " When the location list window is closed, the buffer name should not
4394 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004395 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004396 call assert_true(bufloaded(qfbnum))
4397
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004398 " After deleting a location list buffer using ":bdelete", opening the
4399 " location list window should mark the buffer as a location list buffer.
4400 exe "bdelete " . qfbnum
4401 lopen
4402 call assert_equal("quickfix", &buftype)
4403 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4404 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4405 call assert_false(&swapfile)
4406 lclose
4407
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004408 " When the location list is cleared for the window, the buffer should be
4409 " removed
4410 call setloclist(0, [], 'f')
4411 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004412 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004413
4414 " When the location list is freed with the location list window open, the
4415 " location list buffer should not be lost. It should be reused when the
4416 " location list is again populated.
4417 lexpr "F1:10:Line10"
4418 lopen
4419 let wid = win_getid()
4420 let qfbnum = bufnr('')
4421 wincmd p
4422 call setloclist(0, [], 'f')
4423 lexpr "F1:10:Line10"
4424 lopen
4425 call assert_equal(wid, win_getid())
4426 call assert_equal(qfbnum, bufnr(''))
4427 lclose
4428
4429 " When the window with the location list is closed, the buffer should be
4430 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004431 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004432 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004433 endif
4434endfunc
4435
4436func Test_qfbuf()
4437 call Xqfbuf_test('c')
4438 call Xqfbuf_test('l')
4439endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004440
4441" If there is an autocmd to use only one window, then opening the location
4442" list window used to crash Vim.
4443func Test_winonly_autocmd()
4444 call s:create_test_file('Xtest1')
4445 " Autocmd to show only one Vim window at a time
4446 autocmd WinEnter * only
4447 new
4448 " Load the location list
4449 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4450 let loclistid = getloclist(0, {'id' : 0}).id
4451 " Open the location list window. Only this window will be shown and the file
4452 " window is closed.
4453 lopen
4454 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4455 " Jump to an entry in the location list and make sure that the cursor is
4456 " positioned correctly.
4457 ll 3
4458 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004459 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004460 call assert_equal(15, line('.'))
4461 " Cleanup
4462 autocmd! WinEnter
4463 new | only
4464 call delete('Xtest1')
4465endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004466
4467" Test to make sure that an empty quickfix buffer is not reused for loading
4468" a normal buffer.
4469func Test_empty_qfbuf()
4470 enew | only
4471 call writefile(["Test"], 'Xfile1')
4472 call setqflist([], 'f')
4473 copen | only
4474 let qfbuf = bufnr('')
4475 edit Xfile1
4476 call assert_notequal(qfbuf, bufnr(''))
4477 enew
4478 call delete('Xfile1')
4479endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004480
4481" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004482" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004483func Xtest_below(cchar)
4484 call s:setup_commands(a:cchar)
4485
4486 " No quickfix/location list
4487 call assert_fails('Xbelow', 'E42:')
4488 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004489 call assert_fails('Xbefore', 'E42:')
4490 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004491
4492 " Empty quickfix/location list
4493 call g:Xsetlist([])
4494 call assert_fails('Xbelow', 'E42:')
4495 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004496 call assert_fails('Xbefore', 'E42:')
4497 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004498
4499 call s:create_test_file('X1')
4500 call s:create_test_file('X2')
4501 call s:create_test_file('X3')
4502 call s:create_test_file('X4')
4503
4504 " Invalid entries
4505 edit X1
4506 call g:Xsetlist(["E1", "E2"])
4507 call assert_fails('Xbelow', 'E42:')
4508 call assert_fails('Xabove', 'E42:')
4509 call assert_fails('3Xbelow', 'E42:')
4510 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004511 call assert_fails('Xbefore', 'E42:')
4512 call assert_fails('Xafter', 'E42:')
4513 call assert_fails('3Xbefore', 'E42:')
4514 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004515
4516 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004517 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 +02004518 edit +7 X2
4519 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004520 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004521 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004522 normal 7G
4523 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004524 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004525 call assert_fails('Xbefore', 'E553:')
4526
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004527 normal 2j
4528 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004529 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004530 normal 7G
4531 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004532 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004533
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004534 " Last error in this file
4535 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004536 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004537 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004538 normal gg
4539 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004540 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004541 call assert_fails('Xafter', 'E553:')
4542
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004543 " First error in this file
4544 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004545 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004546 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004547 normal G
4548 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004549 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004550 call assert_fails('Xbefore', 'E553:')
4551
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004552 normal gg
4553 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004554 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004555 normal gg
4556 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004557 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004558
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004559 normal G
4560 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004561 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004562 normal G
4563 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004564 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004565
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004566 edit X4
4567 call assert_fails('Xabove', 'E42:')
4568 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004569 call assert_fails('Xbefore', 'E42:')
4570 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004571 if a:cchar == 'l'
4572 " If a buffer has location list entries from some other window but not
4573 " from the current window, then the commands should fail.
4574 edit X1 | split | call setloclist(0, [], 'f')
4575 call assert_fails('Xabove', 'E776:')
4576 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004577 call assert_fails('Xbefore', 'E776:')
4578 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004579 close
4580 endif
4581
4582 " Test for lines with multiple quickfix entries
4583 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4584 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4585 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4586 edit +1 X2
4587 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004588 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004589 normal 1G
4590 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004591 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004592
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004593 normal gg
4594 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004595 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004596 normal gg
4597 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004598 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004599
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004600 normal G
4601 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004602 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004603 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004604 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004605 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004606
4607 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004608 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004609 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004610 normal G
4611 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004612 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004613
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004614 normal 10G
4615 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004616 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004617 normal 10G$
4618 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004619 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004620
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004621 normal 10G
4622 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004623 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004624 normal 9G
4625 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004626 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004627
4628 " Invalid range
4629 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004630 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004631 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004632 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004633 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004634 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004635 endif
4636
4637 call delete('X1')
4638 call delete('X2')
4639 call delete('X3')
4640 call delete('X4')
4641endfunc
4642
4643func Test_cbelow()
4644 call Xtest_below('c')
4645 call Xtest_below('l')
4646endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004647
4648func Test_quickfix_count()
4649 let commands = [
4650 \ 'cNext',
4651 \ 'cNfile',
4652 \ 'cabove',
4653 \ 'cbelow',
4654 \ 'cfirst',
4655 \ 'clast',
4656 \ 'cnewer',
4657 \ 'cnext',
4658 \ 'cnfile',
4659 \ 'colder',
4660 \ 'cprevious',
4661 \ 'crewind',
4662 \
4663 \ 'lNext',
4664 \ 'lNfile',
4665 \ 'labove',
4666 \ 'lbelow',
4667 \ 'lfirst',
4668 \ 'llast',
4669 \ 'lnewer',
4670 \ 'lnext',
4671 \ 'lnfile',
4672 \ 'lolder',
4673 \ 'lprevious',
4674 \ 'lrewind',
4675 \ ]
4676 for cmd in commands
4677 call assert_fails('-1' .. cmd, 'E16:')
4678 call assert_fails('.' .. cmd, 'E16:')
4679 call assert_fails('%' .. cmd, 'E16:')
4680 call assert_fails('$' .. cmd, 'E16:')
4681 endfor
4682endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004683
4684" Test for aborting quickfix commands using QuickFixCmdPre
4685func Xtest_qfcmd_abort(cchar)
4686 call s:setup_commands(a:cchar)
4687
4688 call g:Xsetlist([], 'f')
4689
4690 " cexpr/lexpr
4691 let e = ''
4692 try
4693 Xexpr ["F1:10:Line10", "F2:20:Line20"]
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
4700 " cfile/lfile
4701 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4702 let e = ''
4703 try
4704 Xfile Xfile1
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 call delete('Xfile1')
4711
4712 " cgetbuffer/lgetbuffer
4713 enew!
4714 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4715 let e = ''
4716 try
4717 Xgetbuffer
4718 catch /.*/
4719 let e = v:exception
4720 endtry
4721 call assert_equal('AbortCmd', e)
4722 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4723 enew!
4724
4725 " vimgrep/lvimgrep
4726 let e = ''
4727 try
4728 Xvimgrep /func/ test_quickfix.vim
4729 catch /.*/
4730 let e = v:exception
4731 endtry
4732 call assert_equal('AbortCmd', e)
4733 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4734
4735 " helpgrep/lhelpgrep
4736 let e = ''
4737 try
4738 Xhelpgrep quickfix
4739 catch /.*/
4740 let e = v:exception
4741 endtry
4742 call assert_equal('AbortCmd', e)
4743 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4744
4745 " grep/lgrep
4746 if has('unix')
4747 let e = ''
4748 try
4749 silent Xgrep func test_quickfix.vim
4750 catch /.*/
4751 let e = v:exception
4752 endtry
4753 call assert_equal('AbortCmd', e)
4754 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4755 endif
4756endfunc
4757
4758func Test_qfcmd_abort()
4759 augroup QF_Test
4760 au!
4761 autocmd QuickFixCmdPre * throw "AbortCmd"
4762 augroup END
4763
4764 call Xtest_qfcmd_abort('c')
4765 call Xtest_qfcmd_abort('l')
4766
4767 augroup QF_Test
4768 au!
4769 augroup END
4770endfunc
4771
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004772" Test for using a file in one of the parent directories.
4773func Test_search_in_dirstack()
4774 call mkdir('Xtestdir/a/b/c', 'p')
4775 let save_cwd = getcwd()
4776 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4777 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4778 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4779 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4780
4781 let lines = "Entering dir Xtestdir\n" .
4782 \ "Entering dir a\n" .
4783 \ "Entering dir b\n" .
4784 \ "Xfile2:2:X2_L2\n" .
4785 \ "Leaving dir a\n" .
4786 \ "Xfile1:2:X1_L2\n" .
4787 \ "Xfile3:1:X3_L1\n" .
4788 \ "Entering dir c\n" .
4789 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004790 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004791 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004792 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004793 call assert_equal(11, getqflist({'size' : 0}).size)
4794 call assert_equal(4, getqflist({'idx' : 0}).idx)
4795 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004796 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004797 cnext
4798 call assert_equal(6, getqflist({'idx' : 0}).idx)
4799 call assert_equal('X1_L2', getline('.'))
4800 cnext
4801 call assert_equal(7, getqflist({'idx' : 0}).idx)
4802 call assert_equal(1, line('$'))
4803 call assert_equal('', getline(1))
4804 cnext
4805 call assert_equal(9, getqflist({'idx' : 0}).idx)
4806 call assert_equal(1, line('$'))
4807 call assert_equal('', getline(1))
4808
4809 set efm&
4810 exe 'cd ' . save_cwd
4811 call delete('Xtestdir', 'rf')
4812endfunc
4813
Bram Moolenaar1860bde2020-01-06 21:47:21 +01004814" Test for :cquit
4815func Test_cquit()
4816 " Exit Vim with a non-zero value
4817 if RunVim([], ["cquit 7"], '')
4818 call assert_equal(7, v:shell_error)
4819 endif
4820
4821 if RunVim([], ["50cquit"], '')
4822 call assert_equal(50, v:shell_error)
4823 endif
4824
4825 " Exit Vim with default value
4826 if RunVim([], ["cquit"], '')
4827 call assert_equal(1, v:shell_error)
4828 endif
4829
4830 " Exit Vim with zero value
4831 if RunVim([], ["cquit 0"], '')
4832 call assert_equal(0, v:shell_error)
4833 endif
4834
4835 " Exit Vim with negative value
4836 call assert_fails('-3cquit', 'E16:')
4837endfunc
4838
Bram Moolenaar858ba062020-05-31 23:11:59 +02004839" Test for getting a specific item from a quickfix list
4840func Xtest_getqflist_by_idx(cchar)
4841 call s:setup_commands(a:cchar)
4842 " Empty list
4843 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
4844 Xexpr ['F1:10:L10', 'F1:20:L20']
4845 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
4846 call assert_equal(bufnr('F1'), l[0].bufnr)
4847 call assert_equal(20, l[0].lnum)
4848 call assert_equal('L20', l[0].text)
4849 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
4850 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
4851 %bwipe!
4852endfunc
4853
4854func Test_getqflist_by_idx()
4855 call Xtest_getqflist_by_idx('c')
4856 call Xtest_getqflist_by_idx('l')
4857endfunc
4858
4859" Test for the 'quickfixtextfunc' setting
4860func Tqfexpr(info)
4861 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004862 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004863 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004864 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004865 endif
4866
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004867 let l = []
4868 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4869 let e = qfl[idx]
4870 let s = ''
4871 if e.bufnr != 0
4872 let bname = bufname(e.bufnr)
4873 let s ..= fnamemodify(bname, ':.')
4874 endif
4875 let s ..= '-'
4876 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
4877 let s ..= e.text
4878 call add(l, s)
4879 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02004880
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004881 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004882endfunc
4883
4884func Xtest_qftextfunc(cchar)
4885 call s:setup_commands(a:cchar)
4886
4887 set efm=%f:%l:%c:%m
4888 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02004889 call assert_equal('Tqfexpr', &quickfixtextfunc)
4890 call assert_equal('',
4891 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02004892 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4893 Xwindow
4894 call assert_equal('F1-L10C2-green', getline(1))
4895 call assert_equal('F1-L20C4-blue', getline(2))
4896 Xclose
4897 set quickfixtextfunc&vim
4898 Xwindow
4899 call assert_equal('F1|10 col 2| green', getline(1))
4900 call assert_equal('F1|20 col 4| blue', getline(2))
4901 Xclose
4902 set efm&
4903 set quickfixtextfunc&
4904
4905 " Test for per list 'quickfixtextfunc' setting
4906 func PerQfText(info)
4907 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004908 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004909 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004910 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02004911 endif
4912 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004913 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02004914 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004915 let l = []
4916 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
4917 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
4918 endfor
4919 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02004920 endfunc
4921 set quickfixtextfunc=Tqfexpr
4922 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
4923 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
4924 Xwindow
4925 call assert_equal('Line 10, Col 2', getline(1))
4926 call assert_equal('Line 20, Col 4', getline(2))
4927 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02004928 call assert_equal(function('PerQfText'),
4929 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02004930 " Add entries to the list when the quickfix buffer is hidden
4931 Xaddexpr ['F1:30:6:red']
4932 Xwindow
4933 call assert_equal('Line 30, Col 6', getline(3))
4934 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02004935 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02004936 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02004937 set quickfixtextfunc&
4938 delfunc PerQfText
4939
4940 " Non-existing function
4941 set quickfixtextfunc=Tabc
4942 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4943 call assert_fails("Xwindow", 'E117:')
4944 Xclose
4945 set quickfixtextfunc&
4946
4947 " set option to a non-function
4948 set quickfixtextfunc=[10,\ 20]
4949 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
4950 call assert_fails("Xwindow", 'E117:')
4951 Xclose
4952 set quickfixtextfunc&
4953
4954 " set option to a function with different set of arguments
4955 func Xqftext(a, b, c)
4956 return a:a .. a:b .. a:c
4957 endfunc
4958 set quickfixtextfunc=Xqftext
4959 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
4960 call assert_fails("Xwindow", 'E119:')
4961 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004962
4963 " set option to a function that returns a list with non-strings
4964 func Xqftext2(d)
4965 return ['one', [], 'two']
4966 endfunc
4967 set quickfixtextfunc=Xqftext2
4968 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
4969 \ 'E730:')
4970 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02004971 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
4972 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004973 Xclose
4974
Bram Moolenaar858ba062020-05-31 23:11:59 +02004975 set quickfixtextfunc&
4976 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02004977 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02004978
4979 " set the global option to a lambda function
4980 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
4981 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4982 Xwindow
4983 call assert_equal(['green', 'blue'], getline(1, '$'))
4984 Xclose
4985 call assert_equal("{d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 'v:val.text')}", &quickfixtextfunc)
4986 set quickfixtextfunc&
4987
4988 " use a lambda function that returns an empty list
4989 set quickfixtextfunc={d\ ->\ []}
4990 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
4991 Xwindow
4992 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
4993 \ getline(1, '$'))
4994 Xclose
4995 set quickfixtextfunc&
4996
4997 " use a lambda function that returns a list with empty strings
4998 set quickfixtextfunc={d\ ->\ ['',\ '']}
4999 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5000 Xwindow
5001 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5002 \ getline(1, '$'))
5003 Xclose
5004 set quickfixtextfunc&
5005
5006 " set the per-quickfix list text function to a lambda function
5007 call g:Xsetlist([], ' ',
5008 \ {'quickfixtextfunc' :
5009 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5010 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5011 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5012 Xwindow
5013 call assert_equal('Line 10, Col 2', getline(1))
5014 call assert_equal('Line 20, Col 4', getline(2))
5015 Xclose
5016 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5017 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005018endfunc
5019
5020func Test_qftextfunc()
5021 call Xtest_qftextfunc('c')
5022 call Xtest_qftextfunc('l')
5023endfunc
5024
Bram Moolenaarec98e932020-06-08 19:35:59 +02005025" Running :lhelpgrep command more than once in a help window, doesn't jump to
5026" the help topic
5027func Test_lhelpgrep_from_help_window()
5028 call mkdir('Xtestdir/doc', 'p')
5029 call writefile(['window'], 'Xtestdir/doc/a.txt')
5030 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5031 let save_rtp = &rtp
5032 let &rtp = 'Xtestdir'
5033 lhelpgrep window
5034 lhelpgrep buffer
5035 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5036 lhelpgrep window
5037 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5038 let &rtp = save_rtp
5039 call delete('Xtestdir', 'rf')
5040 new | only!
5041endfunc
5042
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005043" Test for the crash fixed by 7.3.715
5044func Test_setloclist_crash()
5045 %bw!
5046 let g:BufNum = bufnr()
5047 augroup QF_Test
5048 au!
5049 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5050 augroup END
5051
5052 try
5053 lvimgrep /.*/ *.mak
5054 catch /E926:/
5055 endtry
5056 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5057 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5058
5059 augroup QF_Test
5060 au!
5061 augroup END
5062 unlet g:BufNum
5063 %bw!
5064endfunc
5065
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005066" vim: shiftwidth=2 sts=2 expandtab